Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
3ac729b
feat(ai): add the AI gateway, resource, controllers, and emitters
ItamarZand88 Jul 22, 2026
f3a397e
fix(ai): apply carve review findings
ItamarZand88 Jul 22, 2026
087af9b
feat(ai): embed the ai-gateway addon into compiled Workers
ItamarZand88 Jul 22, 2026
470a0e6
chore(ai): satisfy biome formatting on ai-gateway packages
ItamarZand88 Jul 22, 2026
b757911
chore(ai): drop the carried-over Postgres runtime binding
ItamarZand88 Jul 22, 2026
2350678
chore(ai): keep this PR AI-only, drop an unrelated InitialSetup log t…
ItamarZand88 Jul 22, 2026
48e80aa
refactor(ai): spawn the launcher binary instead of a napi addon
ItamarZand88 Jul 22, 2026
8e368b8
feat(ai): filter getAvailableModels by runtime cloud availability
ItamarZand88 Jul 23, 2026
ee49969
chore(sdk): restore the literal em dash in the package description
ItamarZand88 Jul 23, 2026
fab0ed8
ci(release): ship the ai-gateway launcher binary as per-platform preb…
ItamarZand88 Jul 23, 2026
07b0121
test(ai): answer the Claude availability probe in the two-cloud integ…
ItamarZand88 Jul 23, 2026
a2b0b54
fix: size dev/test thread stacks for the deep deployment async chain
ItamarZand88 Jul 23, 2026
cd51d8f
fix(ai): treat a 400 probe response as an unavailable model
ItamarZand88 Jul 23, 2026
a7cb041
fix(ai): let one-shot hosts exit by unref-ing the gateway stdio
ItamarZand88 Jul 24, 2026
6ab5501
fix(ai): enable aiplatform on the GCP Terraform path
ItamarZand88 Jul 24, 2026
ecefd9f
fix(ai): refresh the ambient bearer token single-flight
ItamarZand88 Jul 24, 2026
7323e63
fix(ai): fail closed on an unsupported BYO provider
ItamarZand88 Jul 24, 2026
a8bfa43
fix(ai): point BYO-Anthropic defaults at active models
ItamarZand88 Jul 24, 2026
0c1bbb1
refactor(ai): split the gateway router into per-provider modules
ItamarZand88 Jul 24, 2026
d5679ee
fix(ai): remove the 2MB proxy body limit
ItamarZand88 Jul 24, 2026
fb36c4e
fix(ai): bound the ambient metadata token fetch with a timeout
ItamarZand88 Jul 24, 2026
be3c311
fix(ai): fail fast on a BYO-Anthropic Responses call
ItamarZand88 Jul 24, 2026
b94c845
test(ai): cover the ai import-data types in the schema snapshot
ItamarZand88 Jul 24, 2026
27974cc
docs(ai): correct the AWS signing-service names in the creds module doc
ItamarZand88 Jul 24, 2026
92ec4d9
fix(ai): make the published ai-gateway wrapper installable
ItamarZand88 Jul 26, 2026
5bfbc22
fix(ai): cap the proxied request body and reject it in the gateway er…
ItamarZand88 Jul 26, 2026
3599c5e
fix(ci): publish the ai-gateway to the npm dev channel
ItamarZand88 Jul 26, 2026
692564b
chore(ci): tighten the ai-gateway test filter comment
ItamarZand88 Jul 26, 2026
125b00d
chore(ai): trim internal detail from a live-test ignore reason
ItamarZand88 Jul 26, 2026
c6153d6
feat(ai): support .enabled(input) on the AI resource
ItamarZand88 Jul 26, 2026
99ae0b8
test(ai): refresh the ai render snapshots for the registration doc
ItamarZand88 Jul 26, 2026
e195ef6
fix(ai): stage the gateway launcher in the versioned Worker base
ItamarZand88 Jul 26, 2026
93e5029
fix(ai): install only the bindings addon in a bundled Worker
ItamarZand88 Jul 26, 2026
cc187e4
fix(ci): qualify the ai-gateway packages before publishing them
ItamarZand88 Jul 26, 2026
6a45ea9
chore(ai): follow the workspace to 3.2.0
ItamarZand88 Jul 27, 2026
f116dd3
fix(ci): keep a dry-run release from publishing the gateway packages
ItamarZand88 Jul 27, 2026
a14b8e7
fix(ci): stop building the ai-gateway wrapper during install
ItamarZand88 Jul 30, 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 @@ -176,6 +176,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 @@ -285,7 +290,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