Skip to content

[AAASM-1228] ✨ (runtime): Add SDK runtime auto-detection and lifecycle (F115)#41

Merged
Chisanan232 merged 12 commits into
masterfrom
v0.0.1/AAASM-1228/feat/runtime_lifecycle
May 21, 2026
Merged

[AAASM-1228] ✨ (runtime): Add SDK runtime auto-detection and lifecycle (F115)#41
Chisanan232 merged 12 commits into
masterfrom
v0.0.1/AAASM-1228/feat/runtime_lifecycle

Conversation

@Chisanan232
Copy link
Copy Markdown
Contributor

Target

  • Task summary:

    Add src/runtime.ts — a new submodule that implements the F115 runtime lifecycle for the Node.js SDK: locate the aasm Rust sidecar, probe whether it's already running, start it if not, and report a clear install hint when no binary is found. The new orchestrator is exposed as initAssembly(agentId?) from @agent-assembly/sdk/runtime and is not re-exported from src/index.ts — the existing gateway-based initAssembly(config) keeps its meaning.

  • Key point change (optional):

    initAssembly(agentId, port = DEFAULT_PORT)
      1. if (await isRunning(port)) return                  // idempotent re-init
      2. binary = findAasmBinary()                          // 4 search paths
         if (binary === null) throw new Error(INSTALL_HINT)
      3. startRuntime(binary, port)                         // detached subprocess
    

    Binary search order:

    Step Location Covers install method
    1 $PATH (delimiter-split) brew install, cargo install
    2 ~/.local/bin/aasm curl | sh
    3 node_modules/@agent-assembly/runtime-{platform}-{arch}/bin/aasm pnpm add agent-assembly (optionalDependency)
    4 /usr/local/bin/aasm Docker base image

Effecting Scope

  • Action Types:
    • ✨ Adding new something
      • 🟢 No breaking change
      • 🟠 Has breaking change
    • ✏️ Modifying existing something
    • 🚮 Removing something
    • 🔧 Fixing bug
    • ♻️ Refactoring something
    • 🍀 Improving something
    • 🚀 Release
  • Scopes:
    • 🧩 SDK public API
    • 🪡 API client and transport
    • 🤖 Framework hooks
    • 🫀 Data model and types
    • ⛑️ Error handling
    • 🧪 Testing
    • 🚀 Building
    • 📚 Documentation
  • Additional description:
    Tests for runtime.ts are intentionally deferred to AAASM-1230 (cross-SDK test sub-task) per the story decomposition. Local verification:
    • pnpm typecheck → clean
    • pnpm lint → clean
    • pnpm test → 126/131 pass; the 3 failures (tests/packaging/*) are pre-existing on master (need native NAPI build artifacts not available in this environment).

Description

5 granular commits, each adds one logical unit:

# Commit
1 ✨ (runtime): Add src/runtime.ts skeleton with F115 constants
2 ✨ (runtime): Add findAasmBinary() resolver across the 4 install paths
3 ✨ (runtime): Add isRunning() local TCP liveness probe
4 ✨ (runtime): Add startRuntime() detached sidecar spawn
5 ✨ (runtime): Add initAssembly() lifecycle orchestrator

Module-level constants and the install-hint message shared by the four
lifecycle functions in subsequent commits. RUNTIME_SUBPACKAGE follows
the esbuild npm-optionalDependencies pattern
(`runtime-{platform}-{arch}`).

Not re-exported from src/index.ts to avoid colliding with the existing
gateway-based @agent-assembly/sdk initAssembly.

Refs AAASM-1228 / AAASM-1205.
Resolves the aasm binary in this order: $PATH → ~/.local/bin/aasm →
node_modules/@agent-assembly/runtime-{platform}-{arch}/bin/aasm
(esbuild-style optionalDependency) → /usr/local/bin/aasm (Docker base
image). The bundled-runtime path is computed relative to import.meta.url
so it resolves whether this module is executed from src/ (tests) or
dist/esm/ (built).

Refs AAASM-1228.
Promises true iff a connect to 127.0.0.1:DEFAULT_PORT lands within
100 ms. Settles on the first of connect / timeout / error and tears
down the socket — the lifecycle orchestrator uses this to skip
startRuntime() when the sidecar is already up (idempotent re-init).

Refs AAASM-1228.
Spawns `aasm serve --port <port>` with stdin closed, stdout+stderr
appended to .aasm-runtime.log under logDir (default: process.cwd()),
detached: true + child.unref() so the Node event loop can exit
independently of the sidecar. Returns the ChildProcess handle; the
caller does not await.

Refs AAASM-1228.
Implements the F115 four-step lifecycle: probe → resolve binary → spawn.
Returns early when isRunning() reports a live sidecar (idempotent
re-init), throws Error(INSTALL_HINT) when findAasmBinary() returns
null. agentId is accepted per the AAASM-1228 signature but is not
consumed at the lifecycle layer; the existing gateway-aware
@agent-assembly/sdk initAssembly handles register-and-connect once the
sidecar is reachable.

Closes AAASM-1228.
src/runtime.ts shipped using `dirname(fileURLToPath(import.meta.url))`
to anchor the bundled-runtime sub-package path resolution relative to
this module. That breaks `tsc -p tsconfig.cjs.json` with TS1343
(import.meta only allowed when --module is es2020+/nodenext) and
cascades into the entire `pnpm run build` → packaging-test → test
matrix going red on every Node version × OS combination.

Switch to the project-wide `createRequire(${cwd()}/package.json)`
pattern used by src/native/client.ts, src/core/init-assembly.ts, and
the framework-detection modules. It works in both ESM and CJS contexts
and resolves the optional dep via Node's standard module algorithm,
which is also more correct than the hand-rolled relative-path walking.

Refs AAASM-1228.
@codecov
Copy link
Copy Markdown

codecov Bot commented May 21, 2026

Codecov Report

❌ Patch coverage is 74.35897% with 20 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/runtime.ts 74.35% 18 Missing and 2 partials ⚠️

📢 Thoughts on this report? Let us know!

Module preamble, imports, and two fixture helpers used by the four
F115 scenario tests landing in subsequent commits:

  * makeFakeAasm(dir) — writes an executable aasm shim into dir.
  * makeBundledRuntimePackage(root) — materialises a fake
    node_modules/@agent-assembly/runtime-{platform}-{arch}/{package.json,
    bin/aasm} tree under root so the createRequire-based bundled-path
    resolver in src/runtime.ts has something real to resolve.

Refs AAASM-1228 / AAASM-1230.
Creates an executable aasm shim in a tmp dir, sets process.env.PATH
to that dir (and HOME to a non-existent path to disable the
~/.local/bin fallback), then asserts findAasmBinary returns the
exact tmp-dir path. Covers the primary brew install / cargo install
/ curl installer code path.

Refs AAASM-1228 / AAASM-1230.
Materialises a fake node_modules/@agent-assembly/runtime-{platform}-{arch}
sub-package under a tmp cwd, points PATH/HOME at non-existent dirs to
suppress the earlier search-path branches, and asserts findAasmBinary
returns the bundled bin/aasm path. Exercises the createRequire-based
resolution that replaced the import.meta.url approach in commit
8eecb52.

Refs AAASM-1228 / AAASM-1230.
createRequire.resolve returns the realpath form of the optional
sub-package's package.json. On macOS that means /var/folders/...
→ /private/var/folders/... after symlink resolution, so the prior
direct fake-path comparison fails. Apply realpathSync to the expected
path so the assertion holds on Darwin as well as Linux.

Refs AAASM-1228 / AAASM-1230.
Empties every search location (PATH, HOME, cwd without node_modules)
and asserts initAssembly rejects with an Error whose message is
exactly INSTALL_HINT — i.e. the full pnpm / brew / curl install
copy-paste the runtime ships to end users.

Refs AAASM-1228 / AAASM-1230.
Binds an ephemeral 127.0.0.1 port (avoids racing with whatever might
be on DEFAULT_PORT 7878 on the dev box), points PATH/HOME at empty
locations to guarantee findAasmBinary would fail, then calls
initAssembly(undefined, port). The orchestrator must short-circuit on
isRunning() and resolve cleanly without spawning a second sidecar —
the structural guarantee that repeated init_assembly invocations are
idempotent.

Closes the 4th AAASM-1230 AC scenario for the Node.js SDK.

Refs AAASM-1228 / AAASM-1230.
@sonarqubecloud
Copy link
Copy Markdown

@Chisanan232 Chisanan232 merged commit 589ec99 into master May 21, 2026
25 of 26 checks passed
@Chisanan232 Chisanan232 deleted the v0.0.1/AAASM-1228/feat/runtime_lifecycle branch May 21, 2026 05:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant