Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
df1a48a
feat(ai): add the AI gateway, resource, controllers, and emitters
ItamarZand88 Jul 22, 2026
189689e
fix(ai): apply carve review findings
ItamarZand88 Jul 22, 2026
34afd6d
feat(ai): embed the ai-gateway addon into compiled Workers
ItamarZand88 Jul 22, 2026
4eb31ac
chore(ai): satisfy biome formatting on ai-gateway packages
ItamarZand88 Jul 22, 2026
3a19567
chore(ai): drop the carried-over Postgres runtime binding
ItamarZand88 Jul 22, 2026
543ac71
chore(ai): keep this PR AI-only, drop an unrelated InitialSetup log t…
ItamarZand88 Jul 22, 2026
7f214ac
refactor(ai): spawn the launcher binary instead of a napi addon
ItamarZand88 Jul 22, 2026
1572578
feat(ai): filter getAvailableModels by runtime cloud availability
ItamarZand88 Jul 23, 2026
1e26f90
chore(sdk): restore the literal em dash in the package description
ItamarZand88 Jul 23, 2026
f741b8f
ci(release): ship the ai-gateway launcher binary as per-platform preb…
ItamarZand88 Jul 23, 2026
631ad71
test(ai): answer the Claude availability probe in the two-cloud integ…
ItamarZand88 Jul 23, 2026
e935b26
fix: size dev/test thread stacks for the deep deployment async chain
ItamarZand88 Jul 23, 2026
40e4e4f
fix(ai): treat a 400 probe response as an unavailable model
ItamarZand88 Jul 23, 2026
c287fe6
fix(ai): let one-shot hosts exit by unref-ing the gateway stdio
ItamarZand88 Jul 24, 2026
d1c4ef6
fix(ai): enable aiplatform on the GCP Terraform path
ItamarZand88 Jul 24, 2026
d618be7
fix(ai): refresh the ambient bearer token single-flight
ItamarZand88 Jul 24, 2026
92585b8
fix(ai): fail closed on an unsupported BYO provider
ItamarZand88 Jul 24, 2026
f4eeec4
fix(ai): point BYO-Anthropic defaults at active models
ItamarZand88 Jul 24, 2026
daa1e89
refactor(ai): split the gateway router into per-provider modules
ItamarZand88 Jul 24, 2026
edbd4fb
fix(ai): remove the 2MB proxy body limit
ItamarZand88 Jul 24, 2026
b1e5e14
fix(ai): bound the ambient metadata token fetch with a timeout
ItamarZand88 Jul 24, 2026
3bced1b
fix(ai): fail fast on a BYO-Anthropic Responses call
ItamarZand88 Jul 24, 2026
2d2f921
test(ai): cover the ai import-data types in the schema snapshot
ItamarZand88 Jul 24, 2026
af74585
docs(ai): correct the AWS signing-service names in the creds module doc
ItamarZand88 Jul 24, 2026
8b1fded
fix(ai): make the published ai-gateway wrapper installable
ItamarZand88 Jul 26, 2026
14418e9
fix(ai): cap the proxied request body and reject it in the gateway er…
ItamarZand88 Jul 26, 2026
164b836
fix(ci): publish the ai-gateway to the npm dev channel
ItamarZand88 Jul 26, 2026
3239828
chore(ci): tighten the ai-gateway test filter comment
ItamarZand88 Jul 26, 2026
ef8c977
chore(ai): trim internal detail from a live-test ignore reason
ItamarZand88 Jul 26, 2026
30c689b
feat(ai): support .enabled(input) on the AI resource
ItamarZand88 Jul 26, 2026
058e953
test(ai): refresh the ai render snapshots for the registration doc
ItamarZand88 Jul 26, 2026
4266674
fix(ai): stage the gateway launcher in the versioned Worker base
ItamarZand88 Jul 26, 2026
2bea8d9
fix(ai): install only the bindings addon in a bundled Worker
ItamarZand88 Jul 26, 2026
2e47a36
fix(ci): qualify the ai-gateway packages before publishing them
ItamarZand88 Jul 26, 2026
e37599c
chore(ai): follow the workspace to 3.1.0
ItamarZand88 Jul 27, 2026
bd39244
fix(ci): keep a dry-run release from publishing the gateway packages
ItamarZand88 Jul 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,14 @@
rustflags = ["--cfg", "tokio_unstable"]
rustdocflags = ["--cfg", "tokio_unstable"]

[env]
# The deployment reconcile polls a deep async chain on one stack (executor -> resource
# controllers -> the cloud SDKs' tower/hyper/rustls futures). In debug builds those frames
# are un-inlined and the chain needs ~3MB, over tokio's 2MB default thread-stack, so the
# alien-test cloud e2e (push_/pull_) overflows its test thread. Release binaries are
# unaffected (inlined frames fit 2MB), so this only sizes dev/test threads. 8MB matches the
# headroom alien-worker-runtime already gives its runtime for the same reason.
RUST_MIN_STACK = "8388608"

[target.wasm32-unknown-unknown]
rustflags = ['--cfg', 'getrandom_backend="wasm_js"']
7 changes: 6 additions & 1 deletion .github/workflows/ci-fast.yml
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,11 @@ jobs:

# Manager registry proxy against a real cloud registry: cloud-tests.yml.
'and not binary_id(alien-manager::registry_proxy_cloud_test)'

# AI gateway suites that hit real model endpoints: they need .env.test creds.
'and not binary_id(alien-ai-gateway::live_bedrock)'
'and not binary_id(alien-ai-gateway::live_foundry_claude)'
'and not binary_id(alien-ai-gateway::live_vertex_claude)'
)
cargo nextest run --workspace --filter-expr "${FILTER_CLAUSES[*]}"

Expand Down Expand Up @@ -282,7 +287,7 @@ jobs:
- name: TypeScript unit tests
env:
NODE_OPTIONS: "--max-old-space-size=8192"
run: pnpm --filter @alienplatform/core --filter @alienplatform/bindings --filter @alienplatform/commands test
run: pnpm --filter @alienplatform/core --filter @alienplatform/bindings --filter @alienplatform/commands --filter @alienplatform/ai-gateway test

- name: Build all CLIs
if: steps.changes.outcome != 'success' || steps.changes.outputs.examples == 'true' || github.event_name == 'workflow_dispatch'
Expand Down
30 changes: 30 additions & 0 deletions .github/workflows/e2e-cloud.yml
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,7 @@ jobs:
PACKAGES=()
if [ "${{ needs.compute-matrix.outputs.build_base_image }}" = "true" ]; then
PACKAGES+=("-p" "alien-worker-runtime")
PACKAGES+=("-p" "alien-ai-gateway")
fi
if [ "${{ needs.compute-matrix.outputs.build_operator_image }}" = "true" ]; then
PACKAGES+=("-p" "alien-operator")
Expand Down Expand Up @@ -554,6 +555,13 @@ jobs:
path: target/x86_64-unknown-linux-musl/release/alien-worker-runtime
retention-days: 1

- uses: actions/upload-artifact@v6
if: needs.compute-matrix.outputs.build_base_image == 'true'
with:
name: alien-ai-gateway-x86_64
path: target/x86_64-unknown-linux-musl/release/alien-ai-gateway
retention-days: 1

- uses: actions/upload-artifact@v6
if: needs.compute-matrix.outputs.build_operator_image == 'true'
with:
Expand Down Expand Up @@ -608,6 +616,7 @@ jobs:
PACKAGES=()
if [ "${{ needs.compute-matrix.outputs.build_base_image }}" = "true" ]; then
PACKAGES+=("-p" "alien-worker-runtime")
PACKAGES+=("-p" "alien-ai-gateway")
fi
if [ "${{ needs.compute-matrix.outputs.build_operator_image }}" = "true" ]; then
PACKAGES+=("-p" "alien-operator")
Expand Down Expand Up @@ -644,6 +653,13 @@ jobs:
path: target/aarch64-unknown-linux-musl/release/alien-worker-runtime
retention-days: 1

- uses: actions/upload-artifact@v6
if: needs.compute-matrix.outputs.build_base_image == 'true'
with:
name: alien-ai-gateway-aarch64
path: target/aarch64-unknown-linux-musl/release/alien-ai-gateway
retention-days: 1

- uses: actions/upload-artifact@v6
if: needs.compute-matrix.outputs.build_operator_image == 'true'
with:
Expand Down Expand Up @@ -673,12 +689,24 @@ jobs:
name: alien-worker-runtime-x86_64
path: target/x86_64-unknown-linux-musl/release/

- uses: actions/download-artifact@v7
if: needs.build-x86_64.result == 'success'
with:
name: alien-ai-gateway-x86_64
path: target/x86_64-unknown-linux-musl/release/

- uses: actions/download-artifact@v7
if: needs.build-aarch64.result == 'success'
with:
name: alien-worker-runtime-aarch64
path: target/aarch64-unknown-linux-musl/release/

- uses: actions/download-artifact@v7
if: needs.build-aarch64.result == 'success'
with:
name: alien-ai-gateway-aarch64
path: target/aarch64-unknown-linux-musl/release/

- uses: actions/download-artifact@v7
if: needs.compute-matrix.outputs.needs_bindings_x86_64 == 'true'
with:
Expand All @@ -698,6 +726,8 @@ jobs:
# Create empty placeholder binaries for skipped architectures
[ ! -f target/x86_64-unknown-linux-musl/release/alien-worker-runtime ] && touch target/x86_64-unknown-linux-musl/release/alien-worker-runtime
[ ! -f target/aarch64-unknown-linux-musl/release/alien-worker-runtime ] && touch target/aarch64-unknown-linux-musl/release/alien-worker-runtime
[ ! -f target/x86_64-unknown-linux-musl/release/alien-ai-gateway ] && touch target/x86_64-unknown-linux-musl/release/alien-ai-gateway
[ ! -f target/aarch64-unknown-linux-musl/release/alien-ai-gateway ] && touch target/aarch64-unknown-linux-musl/release/alien-ai-gateway
chmod +x target/*/release/alien-worker-runtime

- name: Ensure Worker addon paths exist
Expand Down
103 changes: 97 additions & 6 deletions .github/workflows/publish-npm-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,26 +72,38 @@ jobs:
fail-fast: false
matrix:
include:
# gateway_target/gateway_artifact drive the alien-ai-gateway launcher
# binary built alongside the addon: darwin legs share the addon's
# target; linux legs build it statically against musl, so one binary
# (per arch) serves both the glibc and Alpine prebuild packages.
- runner: depot-macos-15
os: macos
target: aarch64-apple-darwin
triple: darwin-arm64
expect_arch: arm64
gateway_target: aarch64-apple-darwin
gateway_artifact: darwin-arm64
- runner: depot-macos-15
os: macos
target: x86_64-apple-darwin
triple: darwin-x64
expect_arch: x86_64
gateway_target: x86_64-apple-darwin
gateway_artifact: darwin-x64
- runner: depot-ubuntu-24.04-16
os: linux
target: x86_64-unknown-linux-gnu
triple: linux-x64-gnu
expect_arch: x86-64
gateway_target: x86_64-unknown-linux-musl
gateway_artifact: linux-x64
- runner: depot-ubuntu-24.04-arm-16
os: linux
target: aarch64-unknown-linux-gnu
triple: linux-arm64-gnu
expect_arch: aarch64
gateway_target: aarch64-unknown-linux-musl
gateway_artifact: linux-arm64
runs-on: ${{ matrix.runner }}
timeout-minutes: 60
env:
Expand Down Expand Up @@ -170,6 +182,28 @@ jobs:
retention-days: 1
path: packages/bindings/npm/${{ matrix.triple }}/alien-bindings-node.${{ matrix.triple }}.node

# The AI gateway ships as a standalone launcher binary, not an addon. It
# reuses this matrix (same runners/toolchains; it depends on
# alien-bindings' credential resolver, so protoc is already set up).
- name: Add gateway build target (${{ matrix.gateway_target }})
run: rustup target add ${{ matrix.gateway_target }}

- name: Build ai-gateway binary (${{ matrix.gateway_artifact }})
env:
CARGO_NET_GIT_FETCH_WITH_CLI: "true"
run: |
cargo build --release -p alien-ai-gateway --bin alien-ai-gateway \
--target ${{ matrix.gateway_target }}

- name: Assert ai-gateway binary architecture
run: file "target/${{ matrix.gateway_target }}/release/alien-ai-gateway" | grep -q "${{ matrix.expect_arch }}"

- uses: actions/upload-artifact@v4
with:
name: npm-dev-gateway-${{ matrix.gateway_artifact }}
retention-days: 1
path: target/${{ matrix.gateway_target }}/release/alien-ai-gateway

pack-and-publish:
needs: [prepare, build-addon]
runs-on: depot-ubuntu-24.04-arm-4
Expand Down Expand Up @@ -217,10 +251,36 @@ jobs:
"packages/bindings/npm/${triple}/alien-bindings-node.${triple}.node"
done

- name: Restore gateway binaries
uses: actions/download-artifact@v4
with:
pattern: npm-dev-gateway-*
path: gateway-bins

# The linux binaries are static musl builds, so a triple's gnu and musl
# packages ship the same executable. Artifact download drops the execute
# bit; restore it so npm packs the binary runnable. Runs before the
# rewrite, which stamps these generated manifests with the dev version.
- name: Stage gateway binaries into prebuild packages
shell: bash
run: |
set -euo pipefail
node packages/ai-gateway/scripts/generate-prebuilds.mjs
for pair in darwin-arm64:darwin-arm64 darwin-x64:darwin-x64 \
linux-x64-gnu:linux-x64 linux-x64-musl:linux-x64 \
linux-arm64-gnu:linux-arm64 linux-arm64-musl:linux-arm64; do
triple="${pair%%:*}"
source="${pair##*:}"
cp "gateway-bins/npm-dev-gateway-${source}/alien-ai-gateway" \
"packages/ai-gateway/npm/${triple}/alien-ai-gateway"
chmod 755 "packages/ai-gateway/npm/${triple}/alien-ai-gateway"
done

- name: Rewrite package graph to immutable dev versions
run: |
node .npm-dev-tools/scripts/npm-dev-release.mjs rewrite "${{ needs.prepare.outputs.git_sha }}" | tee npm-dev-versions.json
node packages/bindings/scripts/inject-optional-deps.mjs
Comment thread
greptile-apps[bot] marked this conversation as resolved.
node packages/ai-gateway/scripts/inject-optional-deps.mjs
node .npm-dev-tools/scripts/npm-dev-release.mjs validate "${{ needs.prepare.outputs.git_sha }}"
{
echo '## npm dev package versions'
Expand All @@ -242,6 +302,7 @@ jobs:
packages/core
packages/commands
packages/bindings
packages/ai-gateway
packages/sdk
packages/testing
client-sdks/platform/typescript
Expand All @@ -250,6 +311,12 @@ jobs:
packages/bindings/npm/darwin-x64
packages/bindings/npm/linux-x64-gnu
packages/bindings/npm/linux-arm64-gnu
packages/ai-gateway/npm/darwin-arm64
packages/ai-gateway/npm/darwin-x64
packages/ai-gateway/npm/linux-x64-gnu
packages/ai-gateway/npm/linux-x64-musl
packages/ai-gateway/npm/linux-arm64-gnu
packages/ai-gateway/npm/linux-arm64-musl
EOF
node .npm-dev-tools/scripts/npm-dev-release.mjs digest npm-dev-tarballs/*.tgz | tee npm-dev-digests.json
{
Expand All @@ -266,12 +333,14 @@ jobs:
consumer="$(mktemp -d)"
npm init --yes --prefix "$consumer" >/dev/null
case "$(uname -s)-$(uname -m)" in
Linux-x86_64) native_package_prefix=alienplatform-bindings-linux-x64-gnu ;;
Linux-aarch64) native_package_prefix=alienplatform-bindings-linux-arm64-gnu ;;
Darwin-x86_64) native_package_prefix=alienplatform-bindings-darwin-x64 ;;
Darwin-arm64) native_package_prefix=alienplatform-bindings-darwin-arm64 ;;
Linux-x86_64) host_triple=linux-x64-gnu ;;
Linux-aarch64) host_triple=linux-arm64-gnu ;;
Darwin-x86_64) host_triple=darwin-x64 ;;
Darwin-arm64) host_triple=darwin-arm64 ;;
*) echo "Unsupported smoke-test platform: $(uname -s)-$(uname -m)" >&2; exit 1 ;;
esac
native_package_prefix="alienplatform-bindings-${host_triple}"
gateway_package_prefix="alienplatform-ai-gateway-${host_triple}"
tarballs=("$GITHUB_WORKSPACE"/npm-dev-tarballs/*.tgz)
install_tarballs=()
for tarball in "${tarballs[@]}"; do
Expand All @@ -280,6 +349,11 @@ jobs:
alienplatform-bindings-darwin-arm64-*.tgz|alienplatform-bindings-darwin-x64-*.tgz|alienplatform-bindings-linux-x64-gnu-*.tgz|alienplatform-bindings-linux-arm64-gnu-*.tgz)
[[ "$filename" == "$native_package_prefix"-*.tgz ]] && install_tarballs+=("$tarball")
;;
# Platform packages for other hosts carry os/cpu/libc selectors npm
# would refuse; install only the one this runner can execute.
alienplatform-ai-gateway-darwin-arm64-*.tgz|alienplatform-ai-gateway-darwin-x64-*.tgz|alienplatform-ai-gateway-linux-x64-gnu-*.tgz|alienplatform-ai-gateway-linux-x64-musl-*.tgz|alienplatform-ai-gateway-linux-arm64-gnu-*.tgz|alienplatform-ai-gateway-linux-arm64-musl-*.tgz)
[[ "$filename" == "$gateway_package_prefix"-*.tgz ]] && install_tarballs+=("$tarball")
;;
*) install_tarballs+=("$tarball") ;;
esac
done
Expand Down Expand Up @@ -341,16 +415,33 @@ jobs:
}

# Native packages and leaf dependencies first; public entry points last.
published=()
for pattern in \
'*bindings-darwin-arm64*' '*bindings-darwin-x64*' \
'*bindings-linux-x64-gnu*' '*bindings-linux-arm64-gnu*' \
'*core*' '*bindings-[0-9]*' '*commands*' '*sdk*' '*testing*' \
'*ai-gateway-darwin-arm64*' '*ai-gateway-darwin-x64*' \
'*ai-gateway-linux-x64-gnu*' '*ai-gateway-linux-x64-musl*' \
'*ai-gateway-linux-arm64-gnu*' '*ai-gateway-linux-arm64-musl*' \
'*core*' '*ai-gateway-[0-9]*' '*bindings-[0-9]*' '*commands*' '*sdk*' '*testing*' \
'*platform-api*' '*manager-api*'; do
mapfile -t matches < <(compgen -G "npm-dev-tarballs/${pattern}.tgz" || true)
test "${#matches[@]}" -gt 0 || continue
for tarball in "${matches[@]}"; do publish_tarball "$tarball"; done
for tarball in "${matches[@]}"; do
publish_tarball "$tarball"
published+=("$(basename "$tarball")")
done
done

# The pattern list above is an allowlist, so a package added to the pack step but
# not to it would be packed and then silently never published.
missing="$(comm -23 \
<(cd npm-dev-tarballs && ls -- *.tgz | sort) \
<(printf '%s\n' ${published[@]+"${published[@]}"} | sort -u))"
if [ -n "$missing" ]; then
echo "::error::packed but never published: $(tr '\n' ' ' <<< "$missing")"
exit 1
fi

- name: Upload package evidence
uses: actions/upload-artifact@v4
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-qualification.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ jobs:
echo "::error::Release qualification requires a Linear-derived branch"
exit 1
fi
allowed='^(Cargo.toml|Cargo.lock|packages/(core|commands|sdk|testing|bindings)/package.json|crates/alien-bindings-node/package.json|client-sdks/(platform|manager)/typescript/package.json|packages/bindings/npm/(darwin-arm64|darwin-x64|linux-x64-gnu|linux-arm64-gnu)/package.json)$'
allowed='^(Cargo.toml|Cargo.lock|packages/(core|commands|sdk|testing|bindings|ai-gateway)/package.json|crates/alien-bindings-node/package.json|client-sdks/(platform|manager)/typescript/package.json|packages/bindings/npm/(darwin-arm64|darwin-x64|linux-x64-gnu|linux-arm64-gnu)/package.json)$'
unexpected=$(git diff --name-only "$BASE_SHA" "$SOURCE_REF" | grep -Ev "$allowed" || true)
if [ -n "$unexpected" ]; then
echo "::error::Release PR contains non-version files:"
Expand Down
Loading
Loading