@agentproto/driver-agent-cli 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-KHHRPQ2Q.mjs → chunk-L6BRNMVP.mjs} +175 -23
- package/dist/chunk-L6BRNMVP.mjs.map +1 -0
- package/dist/index.d.ts +12 -3
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/manifest/index.d.ts +2 -2
- package/dist/manifest/index.mjs +2 -2
- package/dist/{schema-Ds8jc9fL.d.ts → schema-L-2rEB1H.d.ts} +179 -1
- package/package.json +2 -2
- package/dist/chunk-KHHRPQ2Q.mjs.map +0 -1
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/model.ts","../src/continuation/strategies/none.ts","../src/continuation/types.ts","../src/continuation/strategies/pinned-session.ts","../src/continuation/strategies/transcript.ts","../src/continuation/strategies/native-resume.ts","../src/continuation/registry.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Agent CLI as a model port — turn ANY AIP-45 agent CLI runtime into a generic\n * `complete({system?, prompt}) → {result}` executor. This is the one bridge that\n * lets the SAME registry (hermes, claude-code, opencode, codex, openclaw, …)\n * back any prompt→completion seam: a report's chapter writer, a corpus\n * distiller, a Mastra tool's judgment step. The executor swaps, the prompts\n * (built by each seam's engine) don't.\n *\n * It drives the CLI over **ACP**: per `complete()` it spawns a fresh session,\n * sends one user turn, concatenates the `text-delta` stream until `turn-end`,\n * then closes. Lives here (not in a product) so seams BELOW the products —\n * `@agentproto/corpus` distill, the CLI — can consume it without importing\n * upward. The runner is injectable so assembly is unit-tested without a binary.\n */\n\nimport type { AgentCliRuntime } from \"./types.js\"\n\n/**\n * The minimal structural model port every seam consumes. Anything with this\n * `complete` shape satisfies the corpus `ReportModelPort` / `DistillPort`-backing\n * model / an AIP `ModelPort` — duck-typed, no nominal coupling.\n */\nexport interface ModelLike {\n complete(req: {\n system?: string\n prompt: string\n [k: string]: unknown\n }): Promise<{ result: string }>\n}\n\n/**\n * The \"file-reading sub-agent\" tier — opt-in across every file-IO-capable\n * executor. When `datasetDir` is set the executor is rooted there and granted\n * its own read tools, so instead of being limited to the excerpts a seam quotes\n * in the prompt it can open the primary sources directly and ground first-hand.\n */\nexport interface FileReadingOptions {\n /** Absolute path to the dataset/source root the executor may read from. */\n datasetDir?: string\n}\n\n/** The instruction prepended to a completion when {@link FileReadingOptions.datasetDir} is set. */\nexport function datasetPreamble(datasetDir: string): string {\n return (\n `You have direct read access to the source files under \\`${datasetDir}\\` ` +\n `(e.g. \\`sources/\\` raw captures, \\`entries/\\` refined notes). Use your ` +\n `file-reading tools to consult the primary sources directly when grounding ` +\n `claims — do not rely only on the excerpts quoted in this prompt.`\n )\n}\n\n/** Compose system + prompt with an optional source-access preamble (shared by every executor). */\nexport function composePrompt(\n system: string | undefined,\n prompt: string,\n datasetDir?: string\n): string {\n const head = datasetDir ? `${datasetPreamble(datasetDir)}\\n\\n` : \"\"\n return system ? `${head}${system}\\n\\n${prompt}` : `${head}${prompt}`\n}\n\n/** Provider keys an agent CLI may route through, forwarded from the parent env by default. */\nexport const PROVIDER_KEY_ENV = [\n \"OPENROUTER_API_KEY\",\n \"ANTHROPIC_API_KEY\",\n \"OPENAI_API_KEY\",\n] as const\n\nexport interface AgentCliModelOptions extends FileReadingOptions {\n /**\n * Env handed to the spawned CLI process — the provider key it routes through.\n * Defaults to forwarding {@link PROVIDER_KEY_ENV} from the parent process env.\n */\n env?: Record<string, string>\n /** Working directory for the CLI process. Defaults to `datasetDir` when set. */\n cwd?: string\n /** Timeout per completion (ms). Default 5 min. */\n timeoutMs?: number\n /**\n * Injectable runner (composed prompt → completion text). Defaults to driving\n * the runtime over ACP. Override in tests to avoid the CLI.\n */\n run?: (prompt: string) => Promise<string>\n}\n\n/** Build the env for the spawned CLI: explicit override, else forwarded provider keys. */\nexport function resolveCliEnv(\n opts: Pick<AgentCliModelOptions, \"env\">\n): Record<string, string> {\n if (opts.env) return opts.env\n const env: Record<string, string> = {}\n for (const k of PROVIDER_KEY_ENV) {\n const v = process.env[k]\n if (v) env[k] = v\n }\n return env\n}\n\n/** Drive one ACP turn on `runtime`, concatenating the text deltas. */\nasync function driveTurn(\n runtime: AgentCliRuntime,\n prompt: string,\n opts: AgentCliModelOptions\n): Promise<string> {\n const controller = new AbortController()\n const timer = setTimeout(\n () => controller.abort(),\n opts.timeoutMs ?? 5 * 60 * 1000\n )\n\n const cwd = opts.cwd ?? opts.datasetDir\n const session = await runtime.start({\n env: resolveCliEnv(opts),\n signal: controller.signal,\n ...(cwd ? { cwd } : {}),\n })\n\n try {\n let text = \"\"\n for await (const evt of session.send({ role: \"user\", content: prompt })) {\n if (evt.kind === \"text-delta\") {\n text += evt.text\n } else if (evt.kind === \"error\") {\n throw new Error(`${runtime.definition.id} model: ${evt.error.message}`)\n } else if (evt.kind === \"turn-end\") {\n if (evt.reason !== \"completed\")\n throw new Error(`${runtime.definition.id} model: turn ${evt.reason}`)\n break\n }\n }\n if (controller.signal.aborted)\n throw new Error(`${runtime.definition.id} model: timed out`)\n return text.trim()\n } finally {\n clearTimeout(timer)\n await session.close()\n }\n}\n\n/**\n * Build a {@link ModelLike} backed by an AIP-45 agent-CLI runtime. Hand it any\n * `*Runtime()` from the registry (Hermes, claude-code, opencode, …); per-CLI\n * presets are one-liners over this.\n */\nexport function makeAgentCliModel(\n runtime: AgentCliRuntime,\n opts: AgentCliModelOptions = {}\n): ModelLike {\n const run = opts.run ?? ((prompt: string) => driveTurn(runtime, prompt, opts))\n return {\n async complete({ system, prompt }) {\n return {\n result: await run(composePrompt(system, prompt, opts.datasetDir)),\n }\n },\n }\n}\n","/**\n * `none` strategy — pre-AIP-45-extension behaviour.\n *\n * Spawn a fresh session per acquire; close it on release. No state,\n * no reuse. The default when a manifest declares no `continuation`\n * block (back-compat for adapters that haven't been updated).\n */\n\nimport type { ContinuationStrategy } from \"../types.js\"\n\nexport const noneStrategy: ContinuationStrategy = {\n id: \"none\",\n async acquire(ctx) {\n return ctx.runtime.start(ctx.startOptions)\n },\n async release(ctx) {\n await ctx.session.close()\n },\n}\n","/**\n * AIP-45 ContinuationStrategy interface.\n *\n * A continuation strategy decides HOW prior conversation turns reach a\n * spawned CLI on subsequent invocations. Built-ins handle:\n *\n * - `none` — fresh session per call (current pre-AIP-45 behaviour)\n * - `pinned-session` — keep the spawned child alive, reuse across turns\n * - `transcript` — caller-supplied preamble prepended to each turn\n * - `native-resume` — pass a session id to the CLI's own `--resume` flag\n *\n * Adapter packages MAY register custom strategies via the registry —\n * for example, a Goose-specific strategy that uses MCP-side session\n * load semantics. Custom strategy ids require a follow-up AIP that\n * opens the `ContinuationStrategyId` enum (so the manifest schema can\n * validate them).\n *\n * The strategy owns the SESSION LIFECYCLE: `acquire` returns a session\n * the caller can `send()` against, and `release` decides whether the\n * session lives on (pinned-session) or closes immediately (none). The\n * runner / generation strategy MUST go through `acquire`/`release` —\n * it MUST NOT call `runtime.start()` / `session.close()` directly when\n * a strategy is active.\n */\n\nimport type {\n AgentCliRuntime,\n AgentCliRuntimeSession,\n AgentCliStartOptions,\n ContinuationKeyScope,\n ContinuationStrategyId,\n RuntimeConfig,\n TurnContext,\n} from \"../types.js\"\n\n/**\n * Per-acquire context the strategy gets. The runner builds this from\n * the manifest, the operator config, and the current turn's identity.\n */\nexport interface AcquireContext {\n runtime: AgentCliRuntime\n /** Already-composed start options (cwd / env / signal / config /\n * turnCtx). Strategies MAY override individual fields when they\n * call `runtime.start(...)` themselves. */\n startOptions: AgentCliStartOptions\n /** Per-call config (already validated against the manifest). */\n config: RuntimeConfig\n /** Identity context for key derivation. */\n turnCtx: TurnContext\n}\n\n/**\n * Strategies can hint to the runner about how the turn played out so\n * the strategy can decide whether to keep the session alive (normal\n * end), reset its TTL but keep it (transient error), or evict it\n * (dead-process error).\n */\nexport type ReleaseOutcome =\n | { kind: \"completed\" }\n | { kind: \"cancelled\" }\n | { kind: \"error\"; reason: \"transient\" | \"fatal\"; message: string }\n\nexport interface ReleaseContext {\n session: AgentCliRuntimeSession\n outcome: ReleaseOutcome\n turnCtx: TurnContext\n}\n\n/**\n * The strategy contract. `acquire` returns a session ready for the\n * caller to `send()` against — fresh OR reused. `release` decides\n * the session's fate. Strategies MAY hold internal state (e.g.\n * the pinned-session map) keyed by `turnCtx`.\n */\nexport interface ContinuationStrategy {\n readonly id: ContinuationStrategyId\n acquire(ctx: AcquireContext): Promise<AgentCliRuntimeSession>\n release(ctx: ReleaseContext): Promise<void>\n}\n\n/**\n * Derive a stable pin key from `turnCtx` according to the manifest's\n * `pinned_session.key_scope`. Missing scope fields downgrade to a\n * less-specific key with a warning — pinning still works, it just\n * collides more.\n *\n * Returns `null` when EVERY scope field the manifest asked for is\n * missing (no key derivable; strategy falls back to per-spawn).\n */\nexport function deriveKeyFromScope(\n scope: ContinuationKeyScope[],\n turnCtx: TurnContext\n): string | null {\n const parts: string[] = []\n for (const s of scope) {\n const v = turnCtx[s]\n if (v) parts.push(`${s}=${v}`)\n }\n return parts.length === 0 ? null : parts.join(\"|\")\n}\n","/**\n * `pinned-session` strategy — keep the spawned child alive across\n * turns so the CLI's in-memory model context carries over.\n *\n * Suitable for manifests that declare `session.mode: persistent` AND\n * `context_carryover: true` (Claude Code, OpenCode, ...). Acquires\n * either reuse a live pinned session or spawn fresh and pin; releases\n * keep the session alive and reset its idle TTL. The strategy\n * auto-evicts after the manifest's `pinned_session.idle_timeout_ms`.\n *\n * The pin key is derived from `turnCtx` according to the manifest's\n * `pinned_session.key_scope` (default: `[conversation, operator]` —\n * different conversations and different operators each get their own\n * child process).\n *\n * Lost on process restart. DB-backed pin persistence is a follow-up\n * (track sessionId in `cli_sessions` table, then optionally fall back\n * to native-resume / transcript on restart).\n */\n\nimport type {\n AgentCliRuntimeSession,\n AgentCliRuntime,\n AgentCliStartOptions,\n} from \"../../types.js\"\nimport type { ContinuationStrategy } from \"../types.js\"\nimport { deriveKeyFromScope } from \"../types.js\"\n\ninterface PinnedEntry {\n session: AgentCliRuntimeSession\n /** Cached so retry-after-eviction can recreate without re-resolving\n * the runtime entry from outside. */\n runtime: AgentCliRuntime\n /** Cached so eviction-and-retry uses the same start options. */\n startOptions: AgentCliStartOptions\n idleTimer: ReturnType<typeof setTimeout> | null\n}\n\nconst DEFAULT_IDLE_TIMEOUT_MS = 30 * 60 * 1000\n\nconst pins = new Map<string, PinnedEntry>()\n\nfunction clearIdleTimer(entry: PinnedEntry): void {\n if (entry.idleTimer) {\n clearTimeout(entry.idleTimer)\n entry.idleTimer = null\n }\n}\n\nfunction scheduleIdleEviction(\n key: string,\n entry: PinnedEntry,\n idleTimeoutMs: number\n): void {\n clearIdleTimer(entry)\n entry.idleTimer = setTimeout(() => {\n pins.delete(key)\n entry.session.close().catch(err => {\n console.warn(\n `[pinned-session] idle close failed for ${key}:`,\n err instanceof Error ? err.message : err\n )\n })\n console.log(\n `[pinned-session] ${key} idle ${idleTimeoutMs / 60_000}m → closed`\n )\n }, idleTimeoutMs)\n // Don't keep the event loop alive just for the idle close — the\n // child will be reaped on process exit anyway. Without `unref`\n // a stale pin would block graceful shutdown.\n entry.idleTimer.unref?.()\n}\n\nfunction evictPin(key: string): void {\n const entry = pins.get(key)\n if (!entry) return\n clearIdleTimer(entry)\n pins.delete(key)\n entry.session.close().catch(err => {\n console.warn(\n `[pinned-session] evict close failed for ${key}:`,\n err instanceof Error ? err.message : err\n )\n })\n}\n\nexport const pinnedSessionStrategy: ContinuationStrategy = {\n id: \"pinned-session\",\n\n async acquire(ctx) {\n const tuning = ctx.runtime.definition.continuation?.pinned_session\n const scope = tuning?.key_scope ?? [\"conversation\", \"operator\"]\n const key = deriveKeyFromScope(scope, ctx.turnCtx)\n const idleTimeoutMs = tuning?.idle_timeout_ms ?? DEFAULT_IDLE_TIMEOUT_MS\n\n if (key === null) {\n // No identity to pin against — fall back to per-spawn behaviour.\n // Warn so the host learns to populate turnCtx.\n console.warn(\n `[pinned-session] turnCtx has no fields matching key_scope ${JSON.stringify(scope)}; falling back to per-spawn (no pin).`\n )\n return ctx.runtime.start(ctx.startOptions)\n }\n\n const existing = pins.get(key)\n if (existing) {\n // Cancel the idle timer — this turn is reusing the pin.\n clearIdleTimer(existing)\n return existing.session\n }\n\n const session = await ctx.runtime.start(ctx.startOptions)\n const entry: PinnedEntry = {\n session,\n runtime: ctx.runtime,\n startOptions: ctx.startOptions,\n idleTimer: null,\n }\n pins.set(key, entry)\n scheduleIdleEviction(key, entry, idleTimeoutMs)\n return session\n },\n\n async release(ctx) {\n // Find the entry by identity — ReleaseContext doesn't carry `runtime`,\n // so we match by session reference. Acceptable since the pin map is small.\n let foundKey: string | null = null\n for (const [k, e] of pins) {\n if (e.session === ctx.session) {\n foundKey = k\n break\n }\n }\n\n if (!foundKey) {\n // Session wasn't pinned (per-spawn fallback path) — close it\n // like the `none` strategy would.\n await ctx.session.close()\n return\n }\n\n const entry = pins.get(foundKey)!\n const tuning = entry.runtime.definition.continuation?.pinned_session\n const idleTimeoutMs = tuning?.idle_timeout_ms ?? DEFAULT_IDLE_TIMEOUT_MS\n\n // Fatal errors → evict so the next turn re-spawns. Transient\n // errors and normal completion → reset the idle TTL and keep.\n // Cancelled (user aborted) is treated like normal completion —\n // the user wanted to stop this turn, not the whole session.\n if (ctx.outcome.kind === \"error\" && ctx.outcome.reason === \"fatal\") {\n evictPin(foundKey)\n return\n }\n\n scheduleIdleEviction(foundKey, entry, idleTimeoutMs)\n },\n}\n\n/**\n * Test helper — drop all pinned entries and clear timers. Not part\n * of the public API; exposed under `__test__` so tests can reset the\n * module's singleton state between runs.\n */\nexport const __test__ = {\n resetPins(): void {\n for (const [k] of pins) evictPin(k)\n },\n pinCount(): number {\n return pins.size\n },\n}\n","/**\n * `transcript` strategy — works for any CLI, including those with\n * `resumable: false` and ephemeral sessions.\n *\n * The driver doesn't know about Mastra memory or the host's\n * conversation log — that's the host's domain. The host supplies the\n * preamble at acquire-time via `startOptions.config.options` (the\n * convention is option id `__transcript`, see below) and the strategy\n * is otherwise identical to `none` — fresh session per acquire,\n * close on release.\n *\n * In practice the host does the prepending itself before calling\n * `runtime.start` (it controls the `message` text). This strategy\n * exists mostly as a NAMED policy choice in the manifest — declaring\n * it tells the host \"use the transcript-replay path for this CLI\"\n * without the host needing to inspect capabilities.\n *\n * Token-costly but stateless and survives API restarts.\n */\n\nimport type { ContinuationStrategy } from \"../types.js\"\n\nexport const transcriptStrategy: ContinuationStrategy = {\n id: \"transcript\",\n async acquire(ctx) {\n return ctx.runtime.start(ctx.startOptions)\n },\n async release(ctx) {\n await ctx.session.close()\n },\n}\n","/**\n * `native-resume` strategy — reattach to the agent's own session by id\n * (ACP `loadSession`, MCP equivalent, or argv-style `--resume`).\n *\n * Two-step lifecycle:\n * 1. **acquire**: look up a persisted sessionId for `turnCtx` via\n * `loadHook`. If found, pass it to `runtime.start` as\n * `resumeSessionId` so the protocol arm reattaches. If not, spawn\n * fresh — and after the session is up, capture the new id from\n * `session.sessionId` and persist it via `saveHook`.\n * 2. **release**: close the spawned process. The session lives in\n * the agent's storage layer (e.g. Claude Code's JSONL files);\n * cold-start resume on the next acquire reads from that store.\n *\n * Hooks are registered once per host process via\n * `configureNativeResume({ load, save })`. Without hooks the strategy\n * degrades to per-spawn behaviour with a one-line warning — it's not\n * fatal because the spawn still works, just without continuity.\n *\n * Requires the manifest to declare `capabilities.resumable: true`\n * AND the agent to advertise the matching protocol capability (e.g.\n * ACP `loadSession: true`). The schema enforces the manifest side at\n * validation; runtime capability mismatch surfaces from the protocol\n * arm as the agent's own error.\n */\n\nimport type { ContinuationStrategy, AcquireContext } from \"../types.js\"\nimport { deriveKeyFromScope } from \"../types.js\"\nimport type { TurnContext } from \"../../types.js\"\n\nexport interface NativeResumeHooks {\n /** Look up a persisted sessionId for the given identity scope. Return\n * undefined when no prior session exists — strategy spawns fresh. */\n load: (turnCtx: TurnContext) => Promise<string | undefined>\n /** Persist a freshly-established sessionId so the next cold start\n * can resume. Called once per \"fresh spawn\" acquire (not per turn).\n * Idempotent / upsert semantics expected on the host side. */\n save: (turnCtx: TurnContext, sessionId: string) => Promise<void>\n /** Optional: drop the persisted entry when a session is detected as\n * unresumable (agent rejected loadSession with a hard error). */\n forget?: (turnCtx: TurnContext) => Promise<void>\n}\n\nlet _hooks: NativeResumeHooks | null = null\n\n/**\n * Register the host's session-id load/save callbacks. Call once at\n * boot. Subsequent calls overwrite — useful in tests; in prod treat\n * the registration as exclusive.\n */\nexport function configureNativeResume(hooks: NativeResumeHooks): void {\n _hooks = hooks\n}\n\n/** Reset to no-hooks. Test helper; not part of public API. */\nexport function __resetNativeResumeForTests(): void {\n _hooks = null\n}\n\nexport const nativeResumeStrategy: ContinuationStrategy = {\n id: \"native-resume\",\n async acquire(ctx: AcquireContext) {\n if (!_hooks) {\n console.warn(\n \"[native-resume] no hooks registered (call configureNativeResume at boot); falling back to per-spawn — no continuity.\"\n )\n return ctx.runtime.start(ctx.startOptions)\n }\n // Use the same key-derivation as pinned-session so a host can\n // declare its scope ONCE in the manifest (`continuation.pinned_session.key_scope`)\n // and have both strategies key off the same identity. Native-resume\n // doesn't have its own key_scope today; it inherits.\n const scope =\n ctx.runtime.definition.continuation?.pinned_session?.key_scope ?? [\n \"conversation\",\n \"operator\",\n ]\n const key = deriveKeyFromScope(scope, ctx.turnCtx)\n if (key === null) {\n console.warn(\n `[native-resume] turnCtx has no fields matching key_scope ${JSON.stringify(scope)}; falling back to per-spawn (no resume).`\n )\n return ctx.runtime.start(ctx.startOptions)\n }\n\n const existingId = await _hooks.load(ctx.turnCtx).catch(err => {\n console.warn(\n `[native-resume] load hook failed for ${key}:`,\n err instanceof Error ? err.message : err\n )\n return undefined\n })\n\n let session\n let resumed = false\n if (existingId) {\n try {\n session = await ctx.runtime.start({\n ...ctx.startOptions,\n resumeSessionId: existingId,\n })\n resumed = true\n } catch (err) {\n // Most likely the agent rejected the id (session expired,\n // wiped, mismatched cwd). Drop the stale pin and spawn fresh\n // so the user gets continuity going forward instead of being\n // stuck on a dead reference.\n console.warn(\n `[native-resume] resume failed for ${key} (id=${existingId.slice(0, 12)}…), starting fresh:`,\n err instanceof Error ? err.message : err\n )\n if (_hooks.forget) {\n await _hooks.forget(ctx.turnCtx).catch(() => undefined)\n }\n session = await ctx.runtime.start(ctx.startOptions)\n }\n } else {\n session = await ctx.runtime.start(ctx.startOptions)\n }\n\n // Persist the established id when this is a NEW session (resume\n // path keeps the same id we already have, no need to re-save).\n // The runtime guarantees session.sessionId reflects the protocol\n // session id when the arm exposes it.\n if (!resumed && session.sessionId) {\n await _hooks.save(ctx.turnCtx, session.sessionId).catch(err => {\n console.warn(\n `[native-resume] save hook failed for ${key}:`,\n err instanceof Error ? err.message : err\n )\n })\n }\n return session\n },\n\n async release(ctx) {\n // The protocol session lives in the agent's own storage; closing\n // the spawned subprocess is fine — `loadSession` on the next\n // acquire reattaches via the persisted id.\n await ctx.session.close()\n },\n}\n","/**\n * Continuation strategy registry.\n *\n * Module-scoped singleton — all built-ins are registered at import\n * time, custom strategies (from adapter packages) register via\n * `registerContinuationStrategy`. The runner looks up by id;\n * unregistered ids throw at acquire-time so the caller fails fast\n * with a clear \"this strategy id isn't registered\" message.\n */\n\nimport type { ContinuationStrategyId } from \"../types.js\"\nimport type { ContinuationStrategy } from \"./types.js\"\nimport { noneStrategy } from \"./strategies/none.js\"\nimport { pinnedSessionStrategy } from \"./strategies/pinned-session.js\"\nimport { transcriptStrategy } from \"./strategies/transcript.js\"\nimport { nativeResumeStrategy } from \"./strategies/native-resume.js\"\n\nconst registry = new Map<ContinuationStrategyId, ContinuationStrategy>()\n\n/**\n * Register (or replace) a continuation strategy. Adapter packages\n * MAY register custom strategies on import — but they MUST first\n * land an AIP that opens the `ContinuationStrategyId` enum so the\n * manifest schema accepts the new id.\n */\nexport function registerContinuationStrategy(\n strategy: ContinuationStrategy\n): void {\n registry.set(strategy.id, strategy)\n}\n\nexport function getContinuationStrategy(\n id: ContinuationStrategyId\n): ContinuationStrategy {\n const s = registry.get(id)\n if (!s) {\n throw new Error(\n `[agent-cli] No continuation strategy registered for id '${id}'. Built-ins: ${Array.from(registry.keys()).join(\", \")}.`\n )\n }\n return s\n}\n\nexport function listContinuationStrategies(): ContinuationStrategyId[] {\n return Array.from(registry.keys())\n}\n\n// Register built-ins eagerly at module load so any importer of the\n// registry sees them. Custom strategies layer on top.\nregisterContinuationStrategy(noneStrategy)\nregisterContinuationStrategy(pinnedSessionStrategy)\nregisterContinuationStrategy(transcriptStrategy)\nregisterContinuationStrategy(nativeResumeStrategy)\n","/**\n * @agentproto/driver-agent-cli — AIP-45 AGENT-CLI.md `defineAgentCli`\n * reference impl.\n *\n * Spec: https://agentproto.sh/docs/aip-45\n *\n * Authoring paths:\n * - TS: `defineAgentCli({...})` → `AgentCliHandle`\n * - MD: `parseAgentCliManifest(src) → agentCliFromManifest({...})` → `AgentCliHandle`\n *\n * Runtime: `createAgentCliRuntime(handle)` → spawn binary, dispatch\n * turns through the protocol arm (acp / mcp / proprietary), normalise\n * events to {@link StreamEvent}.\n */\n\nexport const SPEC_NAME = \"agentcli-interactive/v1\" as const\nexport const SPEC_VERSION = \"0.1.0-alpha\" as const\n\nexport {\n defineAgentCli,\n createAgentCliRuntime,\n} from \"./define-agent-cli.js\"\n// Agent CLI → generic model port: one executor backing every prompt→completion\n// seam (report writer, corpus distiller, Mastra judgment step) over any AIP-45 CLI.\nexport {\n makeAgentCliModel,\n resolveCliEnv,\n composePrompt,\n datasetPreamble,\n PROVIDER_KEY_ENV,\n} from \"./model.js\"\nexport type {\n ModelLike,\n FileReadingOptions,\n AgentCliModelOptions,\n} from \"./model.js\"\n// Exposed so callers can build a sandbox-resident `AgentCliRuntime`\n// against the same protocol layer the host-spawn factory uses, by\n// passing a `ChildProcess`-shaped duck whose stdio is bridged to a\n// remote subprocess (e2b sandbox, ssh, etc.). See guilde's\n// `cli-session-spawn/sandbox-runtime.ts` for a worked example.\nexport {\n createAcpProtocolArm,\n autoAllowPermissionHandler,\n planModePermissionHandler,\n type AcpPermissionHandler,\n type AcpPermissionOutcome,\n type AcpPermissionRequestParams,\n} from \"./protocol/acp-client.js\"\nexport {\n createPrintSession,\n mapMastraEvent,\n createMastraMapperState,\n type PrintArmOptions,\n type MastraMapperState,\n} from \"./protocol/print-arm.js\"\n// Generic proprietary-protocol arm loader — dynamically imports the\n// manifest's `adapter` package. Exported so proprietary adapter packages\n// (and their tests) can drive the same loader `createAgentCliRuntime`\n// uses, without duplicating the load-and-validate logic.\nexport {\n createProprietaryProtocolArm,\n type ProprietaryProtocolOptions,\n} from \"./protocol/proprietary.js\"\nexport {\n agentCliFrontmatterSchema,\n runtimeConfigSchema,\n type AgentCliFrontmatter,\n type RuntimeConfigInput,\n} from \"./schema.js\"\nexport {\n toFileBasedMcpServers,\n type MastracodeMcpServerConfig,\n} from \"./mcp-servers.js\"\nexport {\n composeSpawn,\n resolveContinuationStrategy,\n RuntimeConfigError,\n type ComposedSpawn,\n} from \"./manifest/compose.js\"\nexport {\n registerContinuationStrategy,\n getContinuationStrategy,\n listContinuationStrategies,\n} from \"./continuation/registry.js\"\nexport {\n configureNativeResume,\n type NativeResumeHooks,\n} from \"./continuation/strategies/native-resume.js\"\nexport {\n deriveKeyFromScope,\n type ContinuationStrategy,\n type AcquireContext,\n type ReleaseContext,\n type ReleaseOutcome,\n} from \"./continuation/types.js\"\nexport type {\n AgentCliDefinition,\n AgentCliHandle,\n AgentCliProtocol,\n AgentCliSessionMode,\n AgentCliClient,\n AgentCliConnectOptions,\n AgentCliRuntime,\n AgentCliRuntimeSession,\n AgentCliStartOptions,\n AgentCliCapabilities,\n AgentCliInstallMethod,\n AgentCliVersionCheck,\n AgentCliAuth,\n AgentCliSetupStep,\n AgentCliSetupSkipIf,\n AgentCliSetupPersist,\n AgentCliSession,\n AgentCliModels,\n AgentCliMcpBlock,\n AgentCliMode,\n AgentCliOption,\n AgentCliOptionType,\n AgentCliContinuation,\n AgentCliPinnedSessionTuning,\n AgentCliPrintConfig,\n ContinuationStrategyId,\n ContinuationKeyScope,\n RuntimeConfig,\n TurnContext,\n StreamEvent,\n} from \"./types.js\"\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/model.ts","../src/continuation/strategies/none.ts","../src/continuation/types.ts","../src/continuation/strategies/pinned-session.ts","../src/continuation/strategies/transcript.ts","../src/continuation/strategies/native-resume.ts","../src/continuation/registry.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Agent CLI as a model port — turn ANY AIP-45 agent CLI runtime into a generic\n * `complete({system?, prompt}) → {result}` executor. This is the one bridge that\n * lets the SAME registry (hermes, claude-code, opencode, codex, openclaw, …)\n * back any prompt→completion seam: a report's chapter writer, a corpus\n * distiller, a Mastra tool's judgment step. The executor swaps, the prompts\n * (built by each seam's engine) don't.\n *\n * It drives the CLI over **ACP**: per `complete()` it spawns a fresh session,\n * sends one user turn, concatenates the `text-delta` stream until `turn-end`,\n * then closes. Lives here (not in a product) so seams BELOW the products —\n * `@agentproto/corpus` distill, the CLI — can consume it without importing\n * upward. The runner is injectable so assembly is unit-tested without a binary.\n */\n\nimport type { AgentCliRuntime } from \"./types.js\"\n\n/**\n * The minimal structural model port every seam consumes. Anything with this\n * `complete` shape satisfies the corpus `ReportModelPort` / `DistillPort`-backing\n * model / an AIP `ModelPort` — duck-typed, no nominal coupling.\n */\nexport interface ModelLike {\n complete(req: {\n system?: string\n prompt: string\n [k: string]: unknown\n }): Promise<{ result: string }>\n}\n\n/**\n * The \"file-reading sub-agent\" tier — opt-in across every file-IO-capable\n * executor. When `datasetDir` is set the executor is rooted there and granted\n * its own read tools, so instead of being limited to the excerpts a seam quotes\n * in the prompt it can open the primary sources directly and ground first-hand.\n */\nexport interface FileReadingOptions {\n /** Absolute path to the dataset/source root the executor may read from. */\n datasetDir?: string\n}\n\n/** The instruction prepended to a completion when {@link FileReadingOptions.datasetDir} is set. */\nexport function datasetPreamble(datasetDir: string): string {\n return (\n `You have direct read access to the source files under \\`${datasetDir}\\` ` +\n `(e.g. \\`sources/\\` raw captures, \\`entries/\\` refined notes). Use your ` +\n `file-reading tools to consult the primary sources directly when grounding ` +\n `claims — do not rely only on the excerpts quoted in this prompt.`\n )\n}\n\n/** Compose system + prompt with an optional source-access preamble (shared by every executor). */\nexport function composePrompt(\n system: string | undefined,\n prompt: string,\n datasetDir?: string\n): string {\n const head = datasetDir ? `${datasetPreamble(datasetDir)}\\n\\n` : \"\"\n return system ? `${head}${system}\\n\\n${prompt}` : `${head}${prompt}`\n}\n\n/** Provider keys an agent CLI may route through, forwarded from the parent env by default. */\nexport const PROVIDER_KEY_ENV = [\n \"OPENROUTER_API_KEY\",\n \"ANTHROPIC_API_KEY\",\n \"OPENAI_API_KEY\",\n] as const\n\nexport interface AgentCliModelOptions extends FileReadingOptions {\n /**\n * Env handed to the spawned CLI process — the provider key it routes through.\n * Defaults to forwarding {@link PROVIDER_KEY_ENV} from the parent process env.\n */\n env?: Record<string, string>\n /** Working directory for the CLI process. Defaults to `datasetDir` when set. */\n cwd?: string\n /** Timeout per completion (ms). Default 5 min. */\n timeoutMs?: number\n /**\n * Injectable runner (composed prompt → completion text). Defaults to driving\n * the runtime over ACP. Override in tests to avoid the CLI.\n */\n run?: (prompt: string) => Promise<string>\n}\n\n/** Build the env for the spawned CLI: explicit override, else forwarded provider keys. */\nexport function resolveCliEnv(\n opts: Pick<AgentCliModelOptions, \"env\">\n): Record<string, string> {\n if (opts.env) return opts.env\n const env: Record<string, string> = {}\n for (const k of PROVIDER_KEY_ENV) {\n const v = process.env[k]\n if (v) env[k] = v\n }\n return env\n}\n\n/** Drive one ACP turn on `runtime`, concatenating the text deltas. */\nasync function driveTurn(\n runtime: AgentCliRuntime,\n prompt: string,\n opts: AgentCliModelOptions\n): Promise<string> {\n const controller = new AbortController()\n const timer = setTimeout(\n () => controller.abort(),\n opts.timeoutMs ?? 5 * 60 * 1000\n )\n\n const cwd = opts.cwd ?? opts.datasetDir\n const session = await runtime.start({\n env: resolveCliEnv(opts),\n signal: controller.signal,\n ...(cwd ? { cwd } : {}),\n })\n\n try {\n let text = \"\"\n for await (const evt of session.send({ role: \"user\", content: prompt })) {\n if (evt.kind === \"text-delta\") {\n text += evt.text\n } else if (evt.kind === \"error\") {\n throw new Error(`${runtime.definition.id} model: ${evt.error.message}`)\n } else if (evt.kind === \"turn-end\") {\n if (evt.reason !== \"completed\")\n throw new Error(`${runtime.definition.id} model: turn ${evt.reason}`)\n break\n }\n }\n if (controller.signal.aborted)\n throw new Error(`${runtime.definition.id} model: timed out`)\n return text.trim()\n } finally {\n clearTimeout(timer)\n await session.close()\n }\n}\n\n/**\n * Build a {@link ModelLike} backed by an AIP-45 agent-CLI runtime. Hand it any\n * `*Runtime()` from the registry (Hermes, claude-code, opencode, …); per-CLI\n * presets are one-liners over this.\n */\nexport function makeAgentCliModel(\n runtime: AgentCliRuntime,\n opts: AgentCliModelOptions = {}\n): ModelLike {\n const run = opts.run ?? ((prompt: string) => driveTurn(runtime, prompt, opts))\n return {\n async complete({ system, prompt }) {\n return {\n result: await run(composePrompt(system, prompt, opts.datasetDir)),\n }\n },\n }\n}\n","/**\n * `none` strategy — pre-AIP-45-extension behaviour.\n *\n * Spawn a fresh session per acquire; close it on release. No state,\n * no reuse. The default when a manifest declares no `continuation`\n * block (back-compat for adapters that haven't been updated).\n */\n\nimport type { ContinuationStrategy } from \"../types.js\"\n\nexport const noneStrategy: ContinuationStrategy = {\n id: \"none\",\n async acquire(ctx) {\n return ctx.runtime.start(ctx.startOptions)\n },\n async release(ctx) {\n await ctx.session.close()\n },\n}\n","/**\n * AIP-45 ContinuationStrategy interface.\n *\n * A continuation strategy decides HOW prior conversation turns reach a\n * spawned CLI on subsequent invocations. Built-ins handle:\n *\n * - `none` — fresh session per call (current pre-AIP-45 behaviour)\n * - `pinned-session` — keep the spawned child alive, reuse across turns\n * - `transcript` — caller-supplied preamble prepended to each turn\n * - `native-resume` — pass a session id to the CLI's own `--resume` flag\n *\n * Adapter packages MAY register custom strategies via the registry —\n * for example, a Goose-specific strategy that uses MCP-side session\n * load semantics. Custom strategy ids require a follow-up AIP that\n * opens the `ContinuationStrategyId` enum (so the manifest schema can\n * validate them).\n *\n * The strategy owns the SESSION LIFECYCLE: `acquire` returns a session\n * the caller can `send()` against, and `release` decides whether the\n * session lives on (pinned-session) or closes immediately (none). The\n * runner / generation strategy MUST go through `acquire`/`release` —\n * it MUST NOT call `runtime.start()` / `session.close()` directly when\n * a strategy is active.\n */\n\nimport type {\n AgentCliRuntime,\n AgentCliRuntimeSession,\n AgentCliStartOptions,\n ContinuationKeyScope,\n ContinuationStrategyId,\n RuntimeConfig,\n TurnContext,\n} from \"../types.js\"\n\n/**\n * Per-acquire context the strategy gets. The runner builds this from\n * the manifest, the operator config, and the current turn's identity.\n */\nexport interface AcquireContext {\n runtime: AgentCliRuntime\n /** Already-composed start options (cwd / env / signal / config /\n * turnCtx). Strategies MAY override individual fields when they\n * call `runtime.start(...)` themselves. */\n startOptions: AgentCliStartOptions\n /** Per-call config (already validated against the manifest). */\n config: RuntimeConfig\n /** Identity context for key derivation. */\n turnCtx: TurnContext\n}\n\n/**\n * Strategies can hint to the runner about how the turn played out so\n * the strategy can decide whether to keep the session alive (normal\n * end), reset its TTL but keep it (transient error), or evict it\n * (dead-process error).\n */\nexport type ReleaseOutcome =\n | { kind: \"completed\" }\n | { kind: \"cancelled\" }\n | { kind: \"error\"; reason: \"transient\" | \"fatal\"; message: string }\n\nexport interface ReleaseContext {\n session: AgentCliRuntimeSession\n outcome: ReleaseOutcome\n turnCtx: TurnContext\n}\n\n/**\n * The strategy contract. `acquire` returns a session ready for the\n * caller to `send()` against — fresh OR reused. `release` decides\n * the session's fate. Strategies MAY hold internal state (e.g.\n * the pinned-session map) keyed by `turnCtx`.\n */\nexport interface ContinuationStrategy {\n readonly id: ContinuationStrategyId\n acquire(ctx: AcquireContext): Promise<AgentCliRuntimeSession>\n release(ctx: ReleaseContext): Promise<void>\n}\n\n/**\n * Derive a stable pin key from `turnCtx` according to the manifest's\n * `pinned_session.key_scope`. Missing scope fields downgrade to a\n * less-specific key with a warning — pinning still works, it just\n * collides more.\n *\n * Returns `null` when EVERY scope field the manifest asked for is\n * missing (no key derivable; strategy falls back to per-spawn).\n */\nexport function deriveKeyFromScope(\n scope: ContinuationKeyScope[],\n turnCtx: TurnContext\n): string | null {\n const parts: string[] = []\n for (const s of scope) {\n const v = turnCtx[s]\n if (v) parts.push(`${s}=${v}`)\n }\n return parts.length === 0 ? null : parts.join(\"|\")\n}\n","/**\n * `pinned-session` strategy — keep the spawned child alive across\n * turns so the CLI's in-memory model context carries over.\n *\n * Suitable for manifests that declare `session.mode: persistent` AND\n * `context_carryover: true` (Claude Code, OpenCode, ...). Acquires\n * either reuse a live pinned session or spawn fresh and pin; releases\n * keep the session alive and reset its idle TTL. The strategy\n * auto-evicts after the manifest's `pinned_session.idle_timeout_ms`.\n *\n * The pin key is derived from `turnCtx` according to the manifest's\n * `pinned_session.key_scope` (default: `[conversation, operator]` —\n * different conversations and different operators each get their own\n * child process).\n *\n * Lost on process restart. DB-backed pin persistence is a follow-up\n * (track sessionId in `cli_sessions` table, then optionally fall back\n * to native-resume / transcript on restart).\n */\n\nimport type {\n AgentCliRuntimeSession,\n AgentCliRuntime,\n AgentCliStartOptions,\n} from \"../../types.js\"\nimport type { ContinuationStrategy } from \"../types.js\"\nimport { deriveKeyFromScope } from \"../types.js\"\n\ninterface PinnedEntry {\n session: AgentCliRuntimeSession\n /** Cached so retry-after-eviction can recreate without re-resolving\n * the runtime entry from outside. */\n runtime: AgentCliRuntime\n /** Cached so eviction-and-retry uses the same start options. */\n startOptions: AgentCliStartOptions\n idleTimer: ReturnType<typeof setTimeout> | null\n}\n\nconst DEFAULT_IDLE_TIMEOUT_MS = 30 * 60 * 1000\n\nconst pins = new Map<string, PinnedEntry>()\n\nfunction clearIdleTimer(entry: PinnedEntry): void {\n if (entry.idleTimer) {\n clearTimeout(entry.idleTimer)\n entry.idleTimer = null\n }\n}\n\nfunction scheduleIdleEviction(\n key: string,\n entry: PinnedEntry,\n idleTimeoutMs: number\n): void {\n clearIdleTimer(entry)\n entry.idleTimer = setTimeout(() => {\n pins.delete(key)\n entry.session.close().catch(err => {\n console.warn(\n `[pinned-session] idle close failed for ${key}:`,\n err instanceof Error ? err.message : err\n )\n })\n console.log(\n `[pinned-session] ${key} idle ${idleTimeoutMs / 60_000}m → closed`\n )\n }, idleTimeoutMs)\n // Don't keep the event loop alive just for the idle close — the\n // child will be reaped on process exit anyway. Without `unref`\n // a stale pin would block graceful shutdown.\n entry.idleTimer.unref?.()\n}\n\nfunction evictPin(key: string): void {\n const entry = pins.get(key)\n if (!entry) return\n clearIdleTimer(entry)\n pins.delete(key)\n entry.session.close().catch(err => {\n console.warn(\n `[pinned-session] evict close failed for ${key}:`,\n err instanceof Error ? err.message : err\n )\n })\n}\n\nexport const pinnedSessionStrategy: ContinuationStrategy = {\n id: \"pinned-session\",\n\n async acquire(ctx) {\n const tuning = ctx.runtime.definition.continuation?.pinned_session\n const scope = tuning?.key_scope ?? [\"conversation\", \"operator\"]\n const key = deriveKeyFromScope(scope, ctx.turnCtx)\n const idleTimeoutMs = tuning?.idle_timeout_ms ?? DEFAULT_IDLE_TIMEOUT_MS\n\n if (key === null) {\n // No identity to pin against — fall back to per-spawn behaviour.\n // Warn so the host learns to populate turnCtx.\n console.warn(\n `[pinned-session] turnCtx has no fields matching key_scope ${JSON.stringify(scope)}; falling back to per-spawn (no pin).`\n )\n return ctx.runtime.start(ctx.startOptions)\n }\n\n const existing = pins.get(key)\n if (existing) {\n // Cancel the idle timer — this turn is reusing the pin.\n clearIdleTimer(existing)\n return existing.session\n }\n\n const session = await ctx.runtime.start(ctx.startOptions)\n const entry: PinnedEntry = {\n session,\n runtime: ctx.runtime,\n startOptions: ctx.startOptions,\n idleTimer: null,\n }\n pins.set(key, entry)\n scheduleIdleEviction(key, entry, idleTimeoutMs)\n return session\n },\n\n async release(ctx) {\n // Find the entry by identity — ReleaseContext doesn't carry `runtime`,\n // so we match by session reference. Acceptable since the pin map is small.\n let foundKey: string | null = null\n for (const [k, e] of pins) {\n if (e.session === ctx.session) {\n foundKey = k\n break\n }\n }\n\n if (!foundKey) {\n // Session wasn't pinned (per-spawn fallback path) — close it\n // like the `none` strategy would.\n await ctx.session.close()\n return\n }\n\n const entry = pins.get(foundKey)!\n const tuning = entry.runtime.definition.continuation?.pinned_session\n const idleTimeoutMs = tuning?.idle_timeout_ms ?? DEFAULT_IDLE_TIMEOUT_MS\n\n // Fatal errors → evict so the next turn re-spawns. Transient\n // errors and normal completion → reset the idle TTL and keep.\n // Cancelled (user aborted) is treated like normal completion —\n // the user wanted to stop this turn, not the whole session.\n if (ctx.outcome.kind === \"error\" && ctx.outcome.reason === \"fatal\") {\n evictPin(foundKey)\n return\n }\n\n scheduleIdleEviction(foundKey, entry, idleTimeoutMs)\n },\n}\n\n/**\n * Test helper — drop all pinned entries and clear timers. Not part\n * of the public API; exposed under `__test__` so tests can reset the\n * module's singleton state between runs.\n */\nexport const __test__ = {\n resetPins(): void {\n for (const [k] of pins) evictPin(k)\n },\n pinCount(): number {\n return pins.size\n },\n}\n","/**\n * `transcript` strategy — works for any CLI, including those with\n * `resumable: false` and ephemeral sessions.\n *\n * The driver doesn't know about Mastra memory or the host's\n * conversation log — that's the host's domain. The host supplies the\n * preamble at acquire-time via `startOptions.config.options` (the\n * convention is option id `__transcript`, see below) and the strategy\n * is otherwise identical to `none` — fresh session per acquire,\n * close on release.\n *\n * In practice the host does the prepending itself before calling\n * `runtime.start` (it controls the `message` text). This strategy\n * exists mostly as a NAMED policy choice in the manifest — declaring\n * it tells the host \"use the transcript-replay path for this CLI\"\n * without the host needing to inspect capabilities.\n *\n * Token-costly but stateless and survives API restarts.\n */\n\nimport type { ContinuationStrategy } from \"../types.js\"\n\nexport const transcriptStrategy: ContinuationStrategy = {\n id: \"transcript\",\n async acquire(ctx) {\n return ctx.runtime.start(ctx.startOptions)\n },\n async release(ctx) {\n await ctx.session.close()\n },\n}\n","/**\n * `native-resume` strategy — reattach to the agent's own session by id\n * (ACP `loadSession`, MCP equivalent, or argv-style `--resume`).\n *\n * Two-step lifecycle:\n * 1. **acquire**: look up a persisted sessionId for `turnCtx` via\n * `loadHook`. If found, pass it to `runtime.start` as\n * `resumeSessionId` so the protocol arm reattaches. If not, spawn\n * fresh — and after the session is up, capture the new id from\n * `session.sessionId` and persist it via `saveHook`.\n * 2. **release**: close the spawned process. The session lives in\n * the agent's storage layer (e.g. Claude Code's JSONL files);\n * cold-start resume on the next acquire reads from that store.\n *\n * Hooks are registered once per host process via\n * `configureNativeResume({ load, save })`. Without hooks the strategy\n * degrades to per-spawn behaviour with a one-line warning — it's not\n * fatal because the spawn still works, just without continuity.\n *\n * Requires the manifest to declare `capabilities.resumable: true`\n * AND the agent to advertise the matching protocol capability (e.g.\n * ACP `loadSession: true`). The schema enforces the manifest side at\n * validation; runtime capability mismatch surfaces from the protocol\n * arm as the agent's own error.\n */\n\nimport type { ContinuationStrategy, AcquireContext } from \"../types.js\"\nimport { deriveKeyFromScope } from \"../types.js\"\nimport type { TurnContext } from \"../../types.js\"\n\nexport interface NativeResumeHooks {\n /** Look up a persisted sessionId for the given identity scope. Return\n * undefined when no prior session exists — strategy spawns fresh. */\n load: (turnCtx: TurnContext) => Promise<string | undefined>\n /** Persist a freshly-established sessionId so the next cold start\n * can resume. Called once per \"fresh spawn\" acquire (not per turn).\n * Idempotent / upsert semantics expected on the host side. */\n save: (turnCtx: TurnContext, sessionId: string) => Promise<void>\n /** Optional: drop the persisted entry when a session is detected as\n * unresumable (agent rejected loadSession with a hard error). */\n forget?: (turnCtx: TurnContext) => Promise<void>\n}\n\nlet _hooks: NativeResumeHooks | null = null\n\n/**\n * Register the host's session-id load/save callbacks. Call once at\n * boot. Subsequent calls overwrite — useful in tests; in prod treat\n * the registration as exclusive.\n */\nexport function configureNativeResume(hooks: NativeResumeHooks): void {\n _hooks = hooks\n}\n\n/** Reset to no-hooks. Test helper; not part of public API. */\nexport function __resetNativeResumeForTests(): void {\n _hooks = null\n}\n\nexport const nativeResumeStrategy: ContinuationStrategy = {\n id: \"native-resume\",\n async acquire(ctx: AcquireContext) {\n if (!_hooks) {\n console.warn(\n \"[native-resume] no hooks registered (call configureNativeResume at boot); falling back to per-spawn — no continuity.\"\n )\n return ctx.runtime.start(ctx.startOptions)\n }\n // Use the same key-derivation as pinned-session so a host can\n // declare its scope ONCE in the manifest (`continuation.pinned_session.key_scope`)\n // and have both strategies key off the same identity. Native-resume\n // doesn't have its own key_scope today; it inherits.\n const scope =\n ctx.runtime.definition.continuation?.pinned_session?.key_scope ?? [\n \"conversation\",\n \"operator\",\n ]\n const key = deriveKeyFromScope(scope, ctx.turnCtx)\n if (key === null) {\n console.warn(\n `[native-resume] turnCtx has no fields matching key_scope ${JSON.stringify(scope)}; falling back to per-spawn (no resume).`\n )\n return ctx.runtime.start(ctx.startOptions)\n }\n\n const existingId = await _hooks.load(ctx.turnCtx).catch(err => {\n console.warn(\n `[native-resume] load hook failed for ${key}:`,\n err instanceof Error ? err.message : err\n )\n return undefined\n })\n\n let session\n let resumed = false\n if (existingId) {\n try {\n session = await ctx.runtime.start({\n ...ctx.startOptions,\n resumeSessionId: existingId,\n })\n resumed = true\n } catch (err) {\n // Most likely the agent rejected the id (session expired,\n // wiped, mismatched cwd). Drop the stale pin and spawn fresh\n // so the user gets continuity going forward instead of being\n // stuck on a dead reference.\n console.warn(\n `[native-resume] resume failed for ${key} (id=${existingId.slice(0, 12)}…), starting fresh:`,\n err instanceof Error ? err.message : err\n )\n if (_hooks.forget) {\n await _hooks.forget(ctx.turnCtx).catch(() => undefined)\n }\n session = await ctx.runtime.start(ctx.startOptions)\n }\n } else {\n session = await ctx.runtime.start(ctx.startOptions)\n }\n\n // Persist the established id when this is a NEW session (resume\n // path keeps the same id we already have, no need to re-save).\n // The runtime guarantees session.sessionId reflects the protocol\n // session id when the arm exposes it.\n if (!resumed && session.sessionId) {\n await _hooks.save(ctx.turnCtx, session.sessionId).catch(err => {\n console.warn(\n `[native-resume] save hook failed for ${key}:`,\n err instanceof Error ? err.message : err\n )\n })\n }\n return session\n },\n\n async release(ctx) {\n // The protocol session lives in the agent's own storage; closing\n // the spawned subprocess is fine — `loadSession` on the next\n // acquire reattaches via the persisted id.\n await ctx.session.close()\n },\n}\n","/**\n * Continuation strategy registry.\n *\n * Module-scoped singleton — all built-ins are registered at import\n * time, custom strategies (from adapter packages) register via\n * `registerContinuationStrategy`. The runner looks up by id;\n * unregistered ids throw at acquire-time so the caller fails fast\n * with a clear \"this strategy id isn't registered\" message.\n */\n\nimport type { ContinuationStrategyId } from \"../types.js\"\nimport type { ContinuationStrategy } from \"./types.js\"\nimport { noneStrategy } from \"./strategies/none.js\"\nimport { pinnedSessionStrategy } from \"./strategies/pinned-session.js\"\nimport { transcriptStrategy } from \"./strategies/transcript.js\"\nimport { nativeResumeStrategy } from \"./strategies/native-resume.js\"\n\nconst registry = new Map<ContinuationStrategyId, ContinuationStrategy>()\n\n/**\n * Register (or replace) a continuation strategy. Adapter packages\n * MAY register custom strategies on import — but they MUST first\n * land an AIP that opens the `ContinuationStrategyId` enum so the\n * manifest schema accepts the new id.\n */\nexport function registerContinuationStrategy(\n strategy: ContinuationStrategy\n): void {\n registry.set(strategy.id, strategy)\n}\n\nexport function getContinuationStrategy(\n id: ContinuationStrategyId\n): ContinuationStrategy {\n const s = registry.get(id)\n if (!s) {\n throw new Error(\n `[agent-cli] No continuation strategy registered for id '${id}'. Built-ins: ${Array.from(registry.keys()).join(\", \")}.`\n )\n }\n return s\n}\n\nexport function listContinuationStrategies(): ContinuationStrategyId[] {\n return Array.from(registry.keys())\n}\n\n// Register built-ins eagerly at module load so any importer of the\n// registry sees them. Custom strategies layer on top.\nregisterContinuationStrategy(noneStrategy)\nregisterContinuationStrategy(pinnedSessionStrategy)\nregisterContinuationStrategy(transcriptStrategy)\nregisterContinuationStrategy(nativeResumeStrategy)\n","/**\n * @agentproto/driver-agent-cli — AIP-45 AGENT-CLI.md `defineAgentCli`\n * reference impl.\n *\n * Spec: https://agentproto.sh/docs/aip-45\n *\n * Authoring paths:\n * - TS: `defineAgentCli({...})` → `AgentCliHandle`\n * - MD: `parseAgentCliManifest(src) → agentCliFromManifest({...})` → `AgentCliHandle`\n *\n * Runtime: `createAgentCliRuntime(handle)` → spawn binary, dispatch\n * turns through the protocol arm (acp / mcp / proprietary), normalise\n * events to {@link StreamEvent}.\n */\n\nexport const SPEC_NAME = \"agentcli-interactive/v1\" as const\nexport const SPEC_VERSION = \"0.1.0-alpha\" as const\n\nexport {\n defineAgentCli,\n createAgentCliRuntime,\n} from \"./define-agent-cli.js\"\n// Agent CLI → generic model port: one executor backing every prompt→completion\n// seam (report writer, corpus distiller, Mastra judgment step) over any AIP-45 CLI.\nexport {\n makeAgentCliModel,\n resolveCliEnv,\n composePrompt,\n datasetPreamble,\n PROVIDER_KEY_ENV,\n} from \"./model.js\"\nexport type {\n ModelLike,\n FileReadingOptions,\n AgentCliModelOptions,\n} from \"./model.js\"\n// Exposed so callers can build a sandbox-resident `AgentCliRuntime`\n// against the same protocol layer the host-spawn factory uses, by\n// passing a `ChildProcess`-shaped duck whose stdio is bridged to a\n// remote subprocess (e2b sandbox, ssh, etc.). See guilde's\n// `cli-session-spawn/sandbox-runtime.ts` for a worked example.\nexport {\n createAcpProtocolArm,\n autoAllowPermissionHandler,\n planModePermissionHandler,\n type AcpPermissionHandler,\n type AcpPermissionOutcome,\n type AcpPermissionRequestParams,\n} from \"./protocol/acp-client.js\"\nexport {\n createPrintSession,\n mapMastraEvent,\n createMastraMapperState,\n type PrintArmOptions,\n type MastraMapperState,\n} from \"./protocol/print-arm.js\"\n// Generic proprietary-protocol arm loader — dynamically imports the\n// manifest's `adapter` package. Exported so proprietary adapter packages\n// (and their tests) can drive the same loader `createAgentCliRuntime`\n// uses, without duplicating the load-and-validate logic.\nexport {\n createProprietaryProtocolArm,\n type ProprietaryProtocolOptions,\n} from \"./protocol/proprietary.js\"\nexport {\n agentCliFrontmatterSchema,\n runtimeConfigSchema,\n type AgentCliFrontmatter,\n type RuntimeConfigInput,\n} from \"./schema.js\"\nexport {\n toFileBasedMcpServers,\n type MastracodeMcpServerConfig,\n} from \"./mcp-servers.js\"\nexport {\n composeSpawn,\n resolveContinuationStrategy,\n RuntimeConfigError,\n type ComposedSpawn,\n} from \"./manifest/compose.js\"\nexport {\n registerContinuationStrategy,\n getContinuationStrategy,\n listContinuationStrategies,\n} from \"./continuation/registry.js\"\nexport {\n configureNativeResume,\n type NativeResumeHooks,\n} from \"./continuation/strategies/native-resume.js\"\nexport {\n deriveKeyFromScope,\n type ContinuationStrategy,\n type AcquireContext,\n type ReleaseContext,\n type ReleaseOutcome,\n} from \"./continuation/types.js\"\nexport type {\n AgentCliDefinition,\n AgentCliHandle,\n AgentCliProtocol,\n AgentCliSessionMode,\n AgentCliClient,\n AgentCliConnectOptions,\n AgentCliRuntime,\n AgentCliRuntimeSession,\n AgentCliStartOptions,\n AgentCliCapabilities,\n AgentCliInstallMethod,\n AgentCliVersionCheck,\n AgentCliAuth,\n AgentCliSetupStep,\n AgentCliSetupSkipIf,\n AgentCliSetupPersist,\n AgentCliSession,\n AgentCliModels,\n AgentCliMcpBlock,\n AgentCliMode,\n AgentCliOption,\n AgentCliOptionType,\n AgentCliPresetDeclaration,\n AgentCliContinuation,\n AgentCliPinnedSessionTuning,\n AgentCliPrintConfig,\n ContinuationStrategyId,\n ContinuationKeyScope,\n RuntimeConfig,\n TurnContext,\n StreamEvent,\n} from \"./types.js\"\n"]}
|
package/dist/manifest/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { l as AgentCliFrontmatter, A as AgentCliHandle } from '../schema-
|
|
2
|
-
export {
|
|
1
|
+
import { l as AgentCliFrontmatter, A as AgentCliHandle } from '../schema-L-2rEB1H.js';
|
|
2
|
+
export { E as agentCliFrontmatterSchema } from '../schema-L-2rEB1H.js';
|
|
3
3
|
import '@agentproto/acp';
|
|
4
4
|
import 'zod';
|
|
5
5
|
|
package/dist/manifest/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { agentCliFrontmatterSchema, defineAgentCli } from '../chunk-
|
|
2
|
-
export { agentCliFrontmatterSchema } from '../chunk-
|
|
1
|
+
import { agentCliFrontmatterSchema, defineAgentCli } from '../chunk-L6BRNMVP.mjs';
|
|
2
|
+
export { agentCliFrontmatterSchema } from '../chunk-L6BRNMVP.mjs';
|
|
3
3
|
import matter from 'gray-matter';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -151,6 +151,18 @@ interface AgentCliSession {
|
|
|
151
151
|
interface AgentCliModels {
|
|
152
152
|
default?: string;
|
|
153
153
|
allowed?: string[];
|
|
154
|
+
/**
|
|
155
|
+
* Model-id patterns this adapter must NEVER route to, even when a caller
|
|
156
|
+
* passes the id explicitly (the `model` option is free-form, so `allowed`
|
|
157
|
+
* is only a curated menu and can't *prevent* an off-menu id). Each pattern
|
|
158
|
+
* matches case-insensitively against the requested model id and supports a
|
|
159
|
+
* single trailing `*` wildcard (prefix match); otherwise exact. A match is
|
|
160
|
+
* refused at compose time (`RuntimeConfigError`, code `model_denied`).
|
|
161
|
+
* Use to reserve a premium provider for a dedicated adapter — e.g. hermes
|
|
162
|
+
* denies `["anthropic/*", "claude-*"]` so Anthropic models stay exclusive
|
|
163
|
+
* to the claude-code adapter.
|
|
164
|
+
*/
|
|
165
|
+
deny?: string[];
|
|
154
166
|
env?: Record<string, string>;
|
|
155
167
|
/**
|
|
156
168
|
* How the host selects a model at session start:
|
|
@@ -182,6 +194,16 @@ interface AgentCliCapabilities {
|
|
|
182
194
|
*/
|
|
183
195
|
file_attach?: boolean;
|
|
184
196
|
}
|
|
197
|
+
/**
|
|
198
|
+
* Support status for a declared mode. Absent ⇒ treated as `"active"`.
|
|
199
|
+
* active — the mode does what its description claims.
|
|
200
|
+
* noop — declared and accepted, but measured to have no effect
|
|
201
|
+
* (argv/env compose fine, but the observable outcome is
|
|
202
|
+
* identical to not passing it). Kept declared for honesty
|
|
203
|
+
* and so a future fix can flip it back to `active`.
|
|
204
|
+
* planned — declared as an intended surface but not wired yet.
|
|
205
|
+
*/
|
|
206
|
+
type AgentCliModeStatus = "active" | "noop" | "planned";
|
|
185
207
|
/**
|
|
186
208
|
* AIP-45 mode declaration — a mutually-exclusive operation profile
|
|
187
209
|
* the CLI exposes. The host picks at most ONE mode per turn via
|
|
@@ -191,8 +213,51 @@ interface AgentCliCapabilities {
|
|
|
191
213
|
interface AgentCliMode {
|
|
192
214
|
id: string;
|
|
193
215
|
description?: string;
|
|
216
|
+
/**
|
|
217
|
+
* Extra argv prepended BEFORE the manifest's default `bin_args` when
|
|
218
|
+
* this mode is active. Needed for CLIs whose global flags must
|
|
219
|
+
* precede a subcommand baked into `bin_args` (e.g. hermes'
|
|
220
|
+
* `--ignore-user-config` must come before `acp`, where
|
|
221
|
+
* `bin_args_append` would land it too late).
|
|
222
|
+
*/
|
|
223
|
+
bin_args_prepend?: string[];
|
|
194
224
|
bin_args_append?: string[];
|
|
195
225
|
env?: Record<string, string>;
|
|
226
|
+
/**
|
|
227
|
+
* Env keys to DELETE from the spawn env when this mode is active.
|
|
228
|
+
* Applied at the runtime's env-merge point (after the ambient
|
|
229
|
+
* process.env + mode/option env are combined), so a mode can scrub a
|
|
230
|
+
* credential that must never reach a non-native endpoint — e.g. a
|
|
231
|
+
* gateway mode scrubbing `ANTHROPIC_API_KEY` so it can't leak to a
|
|
232
|
+
* third-party Anthropic-compatible host (it would both 401 and expose
|
|
233
|
+
* the real key). Unlike `env`, this can't be expressed as a static
|
|
234
|
+
* set (a key set to "" is still present); deletion is the only safe
|
|
235
|
+
* semantics. Mirrors the in-code scrub `claude-sdk` does in
|
|
236
|
+
* `buildQueryOptions`; surfaced here so CLI-adapter gateway modes
|
|
237
|
+
* get the same auth hygiene without per-adapter code.
|
|
238
|
+
*/
|
|
239
|
+
env_unset?: string[];
|
|
240
|
+
/**
|
|
241
|
+
* Honest support status surfaced to clients (e.g. via `adapter_list`).
|
|
242
|
+
* Lets an adapter admit that a declared mode is a measured no-op or
|
|
243
|
+
* not-yet-wired instead of silently accepting it. Absent ⇒ `"active"`.
|
|
244
|
+
*/
|
|
245
|
+
status?: AgentCliModeStatus;
|
|
246
|
+
/** Human-readable reason backing `status` (e.g. what was measured). */
|
|
247
|
+
status_note?: string;
|
|
248
|
+
/**
|
|
249
|
+
* How the host activates this mode at session start:
|
|
250
|
+
* - "bin_args" (default) — apply via this mode's `bin_args_prepend` /
|
|
251
|
+
* `bin_args_append` / `env`, composed into argv/env at spawn time.
|
|
252
|
+
* Preserves every existing adapter's behavior unchanged.
|
|
253
|
+
* - "config" — this CLI has no argv/env surface for mode selection;
|
|
254
|
+
* instead the mode id is forwarded to the ACP arm's `connect({mode})`
|
|
255
|
+
* and applied via `session/set_config_option` with `configId:"mode"`
|
|
256
|
+
* after `newSession` (e.g. opencode). `bin_args_prepend` /
|
|
257
|
+
* `bin_args_append` / `env` are ignored for a mode declaring this.
|
|
258
|
+
* Omit → "bin_args".
|
|
259
|
+
*/
|
|
260
|
+
apply?: "bin_args" | "config";
|
|
196
261
|
}
|
|
197
262
|
type AgentCliOptionType = "boolean" | "integer" | "string" | "enum";
|
|
198
263
|
/**
|
|
@@ -211,6 +276,14 @@ interface AgentCliOption {
|
|
|
211
276
|
min?: number;
|
|
212
277
|
/** Inclusive upper bound when type === "integer". */
|
|
213
278
|
max?: number;
|
|
279
|
+
/**
|
|
280
|
+
* Argv template prepended BEFORE the manifest's default `bin_args`
|
|
281
|
+
* when the option has a non-default value. The literal token
|
|
282
|
+
* `{value}` is replaced with the option's value (stringified). Use
|
|
283
|
+
* for value-bearing global flags that must precede a subcommand
|
|
284
|
+
* (e.g. hermes' `--skills {value}`).
|
|
285
|
+
*/
|
|
286
|
+
bin_args_prepend?: string[];
|
|
214
287
|
/**
|
|
215
288
|
* Argv template appended when the option has a non-default value.
|
|
216
289
|
* The literal token `{value}` is replaced with the option's value
|
|
@@ -227,6 +300,63 @@ interface AgentCliOption {
|
|
|
227
300
|
* may contain `{value}` for templating.
|
|
228
301
|
*/
|
|
229
302
|
env?: Record<string, string>;
|
|
303
|
+
/**
|
|
304
|
+
* Env keys to DELETE from the spawn env when the option has a
|
|
305
|
+
* non-default value. Symmetric with `AgentCliMode.env_unset` and
|
|
306
|
+
* applied at the same runtime env-merge point. Lets a single option
|
|
307
|
+
* carry both the value it sets AND the credential it must displace —
|
|
308
|
+
* e.g. a `base_url` option pointing at a third-party Anthropic-
|
|
309
|
+
* compatible gateway should scrub the ambient `ANTHROPIC_API_KEY`
|
|
310
|
+
* so it can't leak, without forcing the operator to also pick a
|
|
311
|
+
* preset mode. The deletion runs before operator-supplied `opts.env`
|
|
312
|
+
* is merged, so a caller can still re-inject a specific key if they
|
|
313
|
+
* truly intend to.
|
|
314
|
+
*/
|
|
315
|
+
env_unset?: string[];
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* AIP-45 gateway-preset declaration — a backend an Anthropic/OpenAI-
|
|
319
|
+
* compatible client can front, declared by the adapter that knows how to
|
|
320
|
+
* drive it. The manifest authoring shape; the runtime normalizes it to a
|
|
321
|
+
* `ProviderPreset` (via the catalog's merge seam) so adapter-declared
|
|
322
|
+
* presets appear in `agentproto presets list` / `list_provider_presets`
|
|
323
|
+
* alongside the built-in registry. Data-only — no adapter projection
|
|
324
|
+
* (`env`/`env_unset`/`bin_args`) here; that stays in the adapter's modes
|
|
325
|
+
* and options, same as the built-in presets are projected today.
|
|
326
|
+
*/
|
|
327
|
+
interface AgentCliPresetDeclaration {
|
|
328
|
+
/**
|
|
329
|
+
* Stable preset id. SHOULD equal the mode id if the adapter projects
|
|
330
|
+
* this preset as a mode (e.g. `moonshot`, `openrouter`). Catalog
|
|
331
|
+
* dedupes built-in vs adapter-declared by id; an adapter-declared id
|
|
332
|
+
* that collides with a built-in is ignored in favor of the built-in
|
|
333
|
+
* (the registry is the source of truth for canonical providers).
|
|
334
|
+
*/
|
|
335
|
+
id: string;
|
|
336
|
+
/** Human label for the catalog UI ("Moonshot (Kimi)"). */
|
|
337
|
+
label: string;
|
|
338
|
+
/** Short description; surfaced in the catalog. */
|
|
339
|
+
description?: string;
|
|
340
|
+
/** API schema flavor — selects which adapter family can consume it. */
|
|
341
|
+
schemaFlavor: "anthropic" | "openai";
|
|
342
|
+
/** Base URL the client hits. */
|
|
343
|
+
baseUrl: string;
|
|
344
|
+
/**
|
|
345
|
+
* Conventional env var holding this provider's API key
|
|
346
|
+
* (e.g. MOONSHOT_API_KEY). Catalog status is derived from its presence
|
|
347
|
+
* in the daemon's environment ("ready" vs "available").
|
|
348
|
+
*/
|
|
349
|
+
keyEnv: string;
|
|
350
|
+
/**
|
|
351
|
+
* Env vars to scrub when this preset is active. Optional at the
|
|
352
|
+
* manifest level — an adapter that scrubs in code (like claude-sdk)
|
|
353
|
+
* may omit it. The catalog does not surface `scrubEnv` to clients.
|
|
354
|
+
*/
|
|
355
|
+
scrubEnv?: string[];
|
|
356
|
+
/** Conventional default model id for this provider, if any. */
|
|
357
|
+
defaultModel?: string;
|
|
358
|
+
/** Optional homepage/docs URL for the catalog UI. */
|
|
359
|
+
homepage?: string;
|
|
230
360
|
}
|
|
231
361
|
/**
|
|
232
362
|
* Built-in continuation strategy ids. Future custom strategies require
|
|
@@ -360,6 +490,15 @@ interface AgentCliDefinition {
|
|
|
360
490
|
modes?: AgentCliMode[];
|
|
361
491
|
/** AIP-45 options (independent typed knobs). */
|
|
362
492
|
options?: AgentCliOption[];
|
|
493
|
+
/**
|
|
494
|
+
* AIP-45 gateway presets this adapter can drive. Adapter-declared
|
|
495
|
+
* presets are merged into the provider-preset catalog
|
|
496
|
+
* (`agentproto presets list` / `list_provider_presets`) alongside the
|
|
497
|
+
* built-in registry, deduped by id (built-in wins on collision). Lets
|
|
498
|
+
* an external adapter surface a gateway the built-in registry doesn't
|
|
499
|
+
* know about without patching `@agentproto/provider-presets`.
|
|
500
|
+
*/
|
|
501
|
+
presets?: AgentCliPresetDeclaration[];
|
|
363
502
|
/** AIP-45 continuation policy (how prior turns reach the CLI). */
|
|
364
503
|
continuation?: AgentCliContinuation;
|
|
365
504
|
requires?: AgentCliRequires;
|
|
@@ -416,6 +555,16 @@ interface AgentCliConnectOptions {
|
|
|
416
555
|
* `session/set_config_option` with `configId:"effort"` on ACP arms.
|
|
417
556
|
*/
|
|
418
557
|
effort?: string;
|
|
558
|
+
/**
|
|
559
|
+
* Mode to activate at session start, for ACP arms whose CLI models
|
|
560
|
+
* mode selection as a session config option rather than an argv/env
|
|
561
|
+
* surface (`AgentCliMode.apply === "config"`, e.g. opencode). Applied
|
|
562
|
+
* via `session/set_config_option` with `configId:"mode"` immediately
|
|
563
|
+
* after `newSession`, best-effort like `model`/`effort`. Adapters that
|
|
564
|
+
* apply mode via `bin_args`/`env` instead (claude-code) leave this
|
|
565
|
+
* unset and are unaffected.
|
|
566
|
+
*/
|
|
567
|
+
mode?: string;
|
|
419
568
|
/**
|
|
420
569
|
* Called on ANY adapter-process activity observed by the protocol
|
|
421
570
|
* arm — incoming ACP `session/update` notifications (even ones that
|
|
@@ -809,6 +958,7 @@ declare const agentCliFrontmatterSchema: z.ZodObject<{
|
|
|
809
958
|
models: z.ZodOptional<z.ZodObject<{
|
|
810
959
|
default: z.ZodOptional<z.ZodString>;
|
|
811
960
|
allowed: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
961
|
+
deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
812
962
|
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
813
963
|
apply: z.ZodOptional<z.ZodEnum<{
|
|
814
964
|
config: "config";
|
|
@@ -828,8 +978,20 @@ declare const agentCliFrontmatterSchema: z.ZodObject<{
|
|
|
828
978
|
modes: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
829
979
|
id: z.ZodString;
|
|
830
980
|
description: z.ZodOptional<z.ZodString>;
|
|
981
|
+
bin_args_prepend: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
831
982
|
bin_args_append: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
832
983
|
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
984
|
+
env_unset: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
985
|
+
status: z.ZodOptional<z.ZodEnum<{
|
|
986
|
+
active: "active";
|
|
987
|
+
noop: "noop";
|
|
988
|
+
planned: "planned";
|
|
989
|
+
}>>;
|
|
990
|
+
status_note: z.ZodOptional<z.ZodString>;
|
|
991
|
+
apply: z.ZodOptional<z.ZodEnum<{
|
|
992
|
+
config: "config";
|
|
993
|
+
bin_args: "bin_args";
|
|
994
|
+
}>>;
|
|
833
995
|
}, z.core.$strict>>>;
|
|
834
996
|
options: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
835
997
|
id: z.ZodString;
|
|
@@ -844,9 +1006,25 @@ declare const agentCliFrontmatterSchema: z.ZodObject<{
|
|
|
844
1006
|
default: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodNumber, z.ZodString]>>;
|
|
845
1007
|
min: z.ZodOptional<z.ZodNumber>;
|
|
846
1008
|
max: z.ZodOptional<z.ZodNumber>;
|
|
1009
|
+
bin_args_prepend: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
847
1010
|
bin_args_template: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
848
1011
|
bin_args_append_when_true: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
849
1012
|
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
1013
|
+
env_unset: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1014
|
+
}, z.core.$strict>>>;
|
|
1015
|
+
presets: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1016
|
+
id: z.ZodString;
|
|
1017
|
+
label: z.ZodString;
|
|
1018
|
+
description: z.ZodOptional<z.ZodString>;
|
|
1019
|
+
schemaFlavor: z.ZodEnum<{
|
|
1020
|
+
anthropic: "anthropic";
|
|
1021
|
+
openai: "openai";
|
|
1022
|
+
}>;
|
|
1023
|
+
baseUrl: z.ZodString;
|
|
1024
|
+
keyEnv: z.ZodString;
|
|
1025
|
+
scrubEnv: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1026
|
+
defaultModel: z.ZodOptional<z.ZodString>;
|
|
1027
|
+
homepage: z.ZodOptional<z.ZodString>;
|
|
850
1028
|
}, z.core.$strict>>>;
|
|
851
1029
|
continuation: z.ZodOptional<z.ZodObject<{
|
|
852
1030
|
default: z.ZodEnum<{
|
|
@@ -908,4 +1086,4 @@ declare const runtimeConfigSchema: z.ZodObject<{
|
|
|
908
1086
|
}, z.core.$strict>;
|
|
909
1087
|
type RuntimeConfigInput = z.infer<typeof runtimeConfigSchema>;
|
|
910
1088
|
|
|
911
|
-
export { type AgentCliHandle as A, type
|
|
1089
|
+
export { type AgentCliHandle as A, type AgentCliVersionCheck as B, type ContinuationStrategyId as C, type RuntimeConfigInput as D, agentCliFrontmatterSchema as E, runtimeConfigSchema as F, type RuntimeConfig as R, type TurnContext as T, type AgentCliRuntime as a, type AgentCliDefinition as b, type AgentCliClient as c, type AgentCliPrintConfig as d, type AgentCliRuntimeSession as e, type AgentCliStartOptions as f, type ContinuationKeyScope as g, type AgentCliAuth as h, type AgentCliCapabilities as i, type AgentCliConnectOptions as j, type AgentCliContinuation as k, type AgentCliFrontmatter as l, type AgentCliInstallMethod as m, type AgentCliMcpBlock as n, type AgentCliMode as o, type AgentCliModels as p, type AgentCliOption as q, type AgentCliOptionType as r, type AgentCliPinnedSessionTuning as s, type AgentCliPresetDeclaration as t, type AgentCliProtocol as u, type AgentCliSession as v, type AgentCliSessionMode as w, type AgentCliSetupPersist as x, type AgentCliSetupSkipIf as y, type AgentCliSetupStep as z };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentproto/driver-agent-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "@agentproto/driver-agent-cli — AIP-45 AGENT-CLI.md reference implementation. Multi-protocol runner that loads an AGENT-CLI.md manifest, spawns the binary, and dispatches turns through an ACP / MCP / proprietary arm. ACP arm delegates to @agentproto/acp; emits the canonical StreamEvent taxonomy regardless of underlying protocol.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agentproto",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"gray-matter": "^4.0.3",
|
|
55
55
|
"zod": "^4.4.3",
|
|
56
|
-
"@agentproto/acp": "0.
|
|
56
|
+
"@agentproto/acp": "0.4.0",
|
|
57
57
|
"@agentproto/define-doctype": "0.1.0"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|