@agent-compose/sdk 0.8.2 → 0.8.4

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.
Files changed (43) hide show
  1. package/dist/agent/__tests__/perf-sampler.test.d.ts +10 -0
  2. package/dist/agent/agent-context.d.ts +1 -1
  3. package/dist/agent/agent-loop.d.ts +9 -1
  4. package/dist/agent/desktop-open.d.ts +184 -0
  5. package/dist/agent/perf-sampler.d.ts +99 -0
  6. package/dist/agent/services-manifest.d.ts +88 -0
  7. package/dist/agent/services-restore.d.ts +58 -0
  8. package/dist/client.d.ts +164 -8
  9. package/dist/display.d.ts +17 -0
  10. package/dist/index.d.ts +14 -5
  11. package/dist/index.js +1393 -53
  12. package/dist/runtimes/_cli-agent.d.ts +359 -2
  13. package/dist/runtimes/claude-code.d.ts +12 -0
  14. package/dist/runtimes/codex.d.ts +8 -0
  15. package/dist/runtimes/openai-desktop.js +1329 -53
  16. package/dist/runtimes/session-env.test.d.ts +14 -0
  17. package/dist/sandbox.d.ts +1 -1
  18. package/dist/types/api-conversations.d.ts +309 -1
  19. package/dist/types/api-factory.d.ts +115 -10
  20. package/dist/types/api-runs.d.ts +21 -0
  21. package/dist/types/protocol.d.ts +44 -1
  22. package/dist/types/runtime.d.ts +120 -0
  23. package/package.json +1 -1
  24. package/src/agent/agent-context.ts +100 -11
  25. package/src/agent/agent-loop.ts +15 -3
  26. package/src/agent/desktop-open.ts +418 -0
  27. package/src/agent/perf-sampler.ts +202 -0
  28. package/src/agent/services-manifest.ts +356 -0
  29. package/src/agent/services-restore.ts +195 -0
  30. package/src/client.ts +328 -12
  31. package/src/display.ts +44 -1
  32. package/src/index.ts +65 -2
  33. package/src/runtimes/_cli-agent.ts +911 -35
  34. package/src/runtimes/claude-code.ts +198 -14
  35. package/src/runtimes/codex.ts +58 -1
  36. package/src/sandbox/providers/e2b.ts +29 -1
  37. package/src/sandbox/providers/local.ts +16 -4
  38. package/src/sandbox.ts +1 -1
  39. package/src/types/api-conversations.ts +307 -3
  40. package/src/types/api-factory.ts +118 -10
  41. package/src/types/api-runs.ts +23 -0
  42. package/src/types/protocol.ts +44 -1
  43. package/src/types/runtime.ts +122 -0
@@ -15,6 +15,34 @@ export interface McpServerConfig {
15
15
  env?: Record<string, string>;
16
16
  }
17
17
 
18
+ /**
19
+ * Exit-event push (the completion DOORBELL, v0.10.43). When set, the durable
20
+ * detached transport's in-guest wrapper fires ONE best-effort HTTP POST
21
+ * announcing `{ turnId, exitCode }` immediately AFTER the exit sentinel is
22
+ * durably written — so the server can verify-and-harvest at event latency
23
+ * instead of the watchdog's poll cadence.
24
+ *
25
+ * THE PUSH IS A DOORBELL, NEVER A VERDICT: the durable file stays the only
26
+ * truth; the push's arrival triggers verification against it, its absence
27
+ * means nothing (the poll ladder is the unchanged backstop), and a lost /
28
+ * duplicate / spoofed push must be harmless. Accordingly the wrapper never
29
+ * blocks sentinel-writing on the push (sentinel first, push after; failures
30
+ * are invisible to the runner lifecycle).
31
+ *
32
+ * Auth: `tokenEnv` NAMES a guest env var (e.g. the cloud session's
33
+ * `AGENT_COMPOSE_API_KEY`) — the wrapper reads it at push time, so the
34
+ * credential never appears in the generated script text or any log.
35
+ */
36
+ export interface TurnExitNotify {
37
+ /** Absolute URL of the server's turn-exit-event endpoint. */
38
+ url: string;
39
+ /** The bridge turn id this runner executes (rides the POST body). */
40
+ turnId: string;
41
+ /** Guest env var holding the bearer credential. A name that is not a
42
+ * plain env identifier disables the push (never risks shell injection). */
43
+ tokenEnv: string;
44
+ }
45
+
18
46
  /** Options passed to a runtime when creating a ModelExecutionContract. */
19
47
  export interface RuntimeOptions {
20
48
  allowedTools?: string[];
@@ -47,8 +75,35 @@ export interface RuntimeOptions {
47
75
  pause?: BoundaryPauseFn;
48
76
  /** Optional JSON schema for runtimes with native structured-output support. */
49
77
  outputFormat?: { type: "json_schema"; schema: Record<string, unknown> };
78
+ /** Exit-event doorbell config (cloud sessions) — see `TurnExitNotify`.
79
+ * Absent ⇒ no push; the durable transport behaves exactly as before. */
80
+ turnExitNotify?: TurnExitNotify;
81
+ /** $HOME-relative path of a shell env file the CLI process sources at
82
+ * launch (cloud sessions: the platform-managed session-secrets file,
83
+ * `SESSION_ENV_FILE_RELPATH`). Sourced fresh at EVERY turn launch, so a
84
+ * rewrite between turns lands on the next turn without a VM recycle.
85
+ * Absent ⇒ nothing is sourced (local/BYOM runs never read a user's own
86
+ * dotfiles by surprise). Must be a plain relative path — no quotes, no
87
+ * `..`; the runtime validates and drops anything else. */
88
+ sessionEnvFile?: string;
89
+ /** ABSOLUTE guest path of a per-turn model-credential shell fragment
90
+ * (cloud subscription sessions: the server ships the TURN ACTOR's own
91
+ * subscription credential there before dispatching the turn). Sourced at
92
+ * launch AFTER `sessionEnvFile`, so the turn's credential always wins —
93
+ * each turn runs on its actor's plan, never a baked or session-wide one.
94
+ * Absent ⇒ nothing extra is sourced. Must be a plain absolute path — no
95
+ * quotes, no `..`; the runtime validates and drops anything else. */
96
+ credEnvFile?: string;
50
97
  }
51
98
 
99
+ /** Three-valued liveness verdict for a runtime's CURRENT turn, read from
100
+ * DURABLE guest state (heartbeat file, stdout file, exit sentinel, pid) over
101
+ * a fresh short exec — never from the health of any long-lived stream.
102
+ * `probe-failed` (exec timeout, transport fault, unparseable output) is
103
+ * NEVER evidence of death: the caller tracks it separately and only many
104
+ * consecutive failures escalate to a sandbox-unreachable verdict. */
105
+ export type RunnerLivenessVerdict = "alive" | "dead" | "probe-failed";
106
+
52
107
  /** Runtime-normalized result of running pre-tool processors. */
53
108
  export type ToolCallGateResult =
54
109
  | { kind: "allow"; call: ToolCall }
@@ -110,6 +165,73 @@ export interface ModelExecutionContract {
110
165
  * `captureCheckpoint` is omitted, this is never called.
111
166
  */
112
167
  restoreCheckpoint?(blob: unknown): void;
168
+ /**
169
+ * Durable liveness probe for the CURRENT turn (2026-08-15 incident, turn
170
+ * 18dc5261: a silently wedged tail stream blinded the executor's
171
+ * process-grep probe to a turn that had FINISHED into its durable file —
172
+ * ten minutes of "no evidence" over a completed answer). Runtimes that run
173
+ * the detached durable transport implement this by reading the guest's
174
+ * durable trio — heartbeat file, stdout size, exit sentinel, pid — over a
175
+ * fresh short exec. The executor's evidence ticker prefers this over its
176
+ * generic process-grep probe.
177
+ *
178
+ * Contract: resolves fast (the implementation carries its own explicit
179
+ * exec timeout) and never throws — faults map to "probe-failed". Null
180
+ * means NO durable probe exists right now (boot phase before the runner
181
+ * launched, a transport without durable files): the caller keeps whatever
182
+ * fallback probe it already had; null is never a verdict.
183
+ */
184
+ probeTurnLiveness?(): Promise<RunnerLivenessVerdict | null>;
185
+ /**
186
+ * DOORBELL, NEVER A VERDICT (exit-event push, v0.10.43): wake the current
187
+ * turn's durable watchdog NOW so it runs its normal verification pass —
188
+ * durable probe, then harvest-on-sentinel / honest no-sentinel death —
189
+ * immediately instead of at the next poll interval. Carries NO information
190
+ * of its own: a nudge for a live turn verifies alive and is a no-op; a
191
+ * spurious / duplicate / stale nudge is harmless; the poll ladder is the
192
+ * unchanged backstop when no nudge arrives. Never throws; a nudge while no
193
+ * watchdog is armed is remembered for the next arm (or dropped at turn
194
+ * start — a new turn owes nothing to the previous turn's doorbell).
195
+ */
196
+ nudgeTurnProbe?(): void;
197
+ /**
198
+ * RESUME HANDOFF, NEVER A KILL (redispatch-carries-session, 2026-08-15
199
+ * forensics): mark the CURRENT turn's in-guest runner as handed off — the
200
+ * caller intends a successor turn to RESUME the same guest session, so
201
+ * abort/early-exit must unwind the transport WITHOUT reaping the detached
202
+ * process tree or deleting its durable files (heartbeat included — the
203
+ * park path's busy signal keeps reading it). Without this, "stop
204
+ * consuming" and "kill the guest tree" are fused on the abort seam, and a
205
+ * supersede-then-resume would destroy the very session it resumes.
206
+ * One-way for the runner instance; a runtime without a detachable guest
207
+ * (single-exec transports, ACP) simply omits the method — its abort
208
+ * semantics are unchanged and the caller falls back to kill semantics.
209
+ */
210
+ detachGuest?(): void;
211
+ /**
212
+ * Deliver ONE user message INTO the currently running turn (the cloud
213
+ * analogue of `inboxStream` for runtimes whose agent loop lives in a
214
+ * detached in-guest CLI). The message rides a durable per-turn inbox
215
+ * file; the guest-side feeder forwards it to the CLI's stdin, where a
216
+ * steering-capable harness folds it into the live turn at the next safe
217
+ * boundary. Four-valued and honest:
218
+ * - "delivered" — the guest feeder forwarded the message to the CLI's
219
+ * stdin BEFORE the turn's terminal result: the running turn saw it.
220
+ * Only this verdict may advance any answered watermark.
221
+ * - "pending" — the append landed in the durable inbox but the ack
222
+ * window exhausted before the feeder forwarded it (guest exit 5: the
223
+ * CLI is not draining stdin mid-step — a long single tool call — or
224
+ * the guest is crawling). NOT seen yet; leave it owed. The line stays
225
+ * appended, so the CLI may still read it when the current step
226
+ * finishes — callers may narrate that bound but must never advance a
227
+ * watermark on it.
228
+ * - "closed" — the turn ended (guest exit 4 / exec fault) before
229
+ * the message was consumed: it was NOT seen; leave it owed.
230
+ * - "unsupported" — no live stream-input turn exists right now (boot
231
+ * phase, a spec/transport without stream input, ACP path).
232
+ * Calls are serialized per turn; never throws.
233
+ */
234
+ injectUserMessage?(text: string): Promise<"delivered" | "pending" | "closed" | "unsupported">;
113
235
  sendMessage(opts: {
114
236
  prompt: string;
115
237
  sessionId?: string;