agentbox-sdk 0.1.301 → 0.1.302

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.
@@ -1,5 +1,5 @@
1
- import { o as AgentProviderName, h as AgentOptions, v as AgentSetupConfig, t as AgentRunConfig, s as AgentRun, r as AgentResult, a3 as RawAgentEvent, b as AgentAttachRequest, z as AttachedRun } from '../types-B3N-Qo2q.js';
2
- export { a as AgentApprovalMode, c as AgentCommandConfig, d as AgentCostData, e as AgentExecutionRequest, f as AgentLocalMcpConfig, g as AgentMcpConfig, i as AgentOptionsBase, j as AgentOptionsMap, k as AgentPermissionDecision, l as AgentPermissionKind, m as AgentPermissionResponse, n as AgentProviderAdapter, p as AgentReasoningEffort, q as AgentRemoteMcpConfig, u as AgentRunSink, w as AgentSetupRequest, x as AgentSkillConfig, y as AgentSubAgentConfig, C as ClaudeCodeAgentOptions, B as ClaudeCodeHookConfig, D as ClaudeCodeHookEvent, E as ClaudeCodeHookHandler, F as ClaudeCodeHookMatcherGroup, G as ClaudeCodeHooksConfig, H as ClaudeCodeProviderOptions, I as CodexAgentOptions, J as CodexCommandHook, K as CodexHookEvent, L as CodexHookMatcherGroup, M as CodexHooksConfig, N as CodexProviderOptions, O as DataContent, P as EmbeddedSkillConfig, Q as FilePart, R as ImagePart, Y as OpenCodeAgentOptions, Z as OpenCodePluginConfig, _ as OpenCodePluginEvent, $ as OpenCodePluginHookConfig, a0 as OpenCodeProviderOptions, a5 as RepoSkillConfig, aa as TextPart, ae as UserContent, af as UserContentPart } from '../types-B3N-Qo2q.js';
1
+ import { o as AgentProviderName, h as AgentOptions, v as AgentSetupConfig, t as AgentRunConfig, s as AgentRun, r as AgentResult, a3 as RawAgentEvent, b as AgentAttachRequest, z as AttachedRun } from '../types-Dj_HCr6Q.js';
2
+ export { a as AgentApprovalMode, c as AgentCommandConfig, d as AgentCostData, e as AgentExecutionRequest, f as AgentLocalMcpConfig, g as AgentMcpConfig, i as AgentOptionsBase, j as AgentOptionsMap, k as AgentPermissionDecision, l as AgentPermissionKind, m as AgentPermissionResponse, n as AgentProviderAdapter, p as AgentReasoningEffort, q as AgentRemoteMcpConfig, u as AgentRunSink, w as AgentSetupRequest, x as AgentSkillConfig, y as AgentSubAgentConfig, C as ClaudeCodeAgentOptions, B as ClaudeCodeHookConfig, D as ClaudeCodeHookEvent, E as ClaudeCodeHookHandler, F as ClaudeCodeHookMatcherGroup, G as ClaudeCodeHooksConfig, H as ClaudeCodeProviderOptions, I as CodexAgentOptions, J as CodexCommandHook, K as CodexHookEvent, L as CodexHookMatcherGroup, M as CodexHooksConfig, N as CodexProviderOptions, O as DataContent, P as EmbeddedSkillConfig, Q as FilePart, R as ImagePart, Y as OpenCodeAgentOptions, Z as OpenCodePluginConfig, _ as OpenCodePluginEvent, $ as OpenCodePluginHookConfig, a0 as OpenCodeProviderOptions, a5 as RepoSkillConfig, ab as TextPart, af as UserContent, ag as UserContentPart } from '../types-Dj_HCr6Q.js';
3
3
  import { S as Sandbox } from '../Sandbox-CByFJI8X.js';
4
4
  export { AgentProvider } from '../enums.js';
5
5
  import 'e2b';
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  Agent
3
- } from "../chunk-4MBB6QHD.js";
4
- import "../chunk-ZOWBRUQR.js";
3
+ } from "../chunk-YAMFJAU6.js";
4
+ import "../chunk-NWAXQ7UD.js";
5
5
  import {
6
6
  AGENT_RESERVED_PORTS,
7
7
  collectAllAgentReservedPorts
8
- } from "../chunk-INMA52FV.js";
8
+ } from "../chunk-AVXJMCBC.js";
9
9
  import "../chunk-NSJM57Z4.js";
10
10
  import {
11
11
  AgentProvider
@@ -188,6 +188,22 @@ async function readStreamAsText(stream) {
188
188
  result += decoder.decode();
189
189
  return result;
190
190
  }
191
+ async function readStreamAsBytes(stream) {
192
+ const reader = stream.getReader();
193
+ const chunks = [];
194
+ try {
195
+ while (true) {
196
+ const { done, value } = await reader.read();
197
+ if (done) {
198
+ break;
199
+ }
200
+ chunks.push(Buffer.isBuffer(value) ? value : Buffer.from(value));
201
+ }
202
+ } finally {
203
+ reader.releaseLock();
204
+ }
205
+ return Buffer.concat(chunks);
206
+ }
191
207
  async function pipeReadableStream(stream, onChunk) {
192
208
  const reader = stream.getReader();
193
209
  const decoder = new TextDecoder();
@@ -256,6 +272,7 @@ export {
256
272
  sleep,
257
273
  waitFor,
258
274
  readStreamAsText,
275
+ readStreamAsBytes,
259
276
  pipeReadableStream,
260
277
  readNodeStream,
261
278
  linesFromTextChunks,
@@ -5,11 +5,12 @@ import {
5
5
  debugSandbox,
6
6
  pipeReadableStream,
7
7
  readNodeStream,
8
+ readStreamAsBytes,
8
9
  readStreamAsText,
9
10
  sleep,
10
11
  suppressUnhandledRejection,
11
12
  time
12
- } from "./chunk-INMA52FV.js";
13
+ } from "./chunk-AVXJMCBC.js";
13
14
  import {
14
15
  shellQuote,
15
16
  toShellCommand
@@ -1284,6 +1285,7 @@ var LocalDockerSandboxAdapter = class extends SandboxAdapter {
1284
1285
  };
1285
1286
 
1286
1287
  // src/sandboxes/providers/modal.ts
1288
+ import path from "path";
1287
1289
  import { ModalClient } from "modal";
1288
1290
 
1289
1291
  // src/sandboxes/tarball.ts
@@ -1535,6 +1537,74 @@ ${command}`;
1535
1537
  raw: process2
1536
1538
  };
1537
1539
  }
1540
+ /**
1541
+ * Upload `content` to `targetPath` inside the Modal sandbox.
1542
+ *
1543
+ * Modal's TS SDK only exposes a `Sandbox.open()` FileIO handle for direct
1544
+ * filesystem access, which is deprecated and capped at 100 MiB per
1545
+ * operation. To match the cross-provider semantics (works for arbitrarily
1546
+ * large artifacts, parent dirs are created on demand), we instead pipe
1547
+ * raw bytes through stdin into a single `mkdir -p … && cat > …` shell —
1548
+ * the same single-exec pattern `uploadAndRun` uses.
1549
+ */
1550
+ async uploadFile(content, targetPath) {
1551
+ this.requireProvisioned();
1552
+ const sandbox = this.requireSandbox();
1553
+ const data = Buffer.isBuffer(content) ? content : Buffer.from(content, "utf8");
1554
+ const dir = path.posix.dirname(targetPath);
1555
+ const wrapped = dir && dir !== "." && dir !== "/" ? `set -e; mkdir -p ${shellQuote(dir)}; cat > ${shellQuote(targetPath)}` : `set -e; cat > ${shellQuote(targetPath)}`;
1556
+ const proc = await sandbox.exec(["/bin/sh", "-c", wrapped], {
1557
+ mode: "binary"
1558
+ });
1559
+ const writer = proc.stdin.getWriter();
1560
+ try {
1561
+ await writer.write(data);
1562
+ await writer.close();
1563
+ } finally {
1564
+ try {
1565
+ writer.releaseLock();
1566
+ } catch {
1567
+ }
1568
+ }
1569
+ const [stderrBytes, exitCode] = await Promise.all([
1570
+ readStreamAsBytes(proc.stderr),
1571
+ proc.wait()
1572
+ ]);
1573
+ if (exitCode !== 0) {
1574
+ const stderr = stderrBytes.toString("utf8").trim();
1575
+ throw new Error(
1576
+ `Failed to upload file to Modal sandbox at ${targetPath} (exit ${exitCode})${stderr ? `: ${stderr}` : ""}`
1577
+ );
1578
+ }
1579
+ }
1580
+ /**
1581
+ * Download a file from the Modal sandbox as raw bytes.
1582
+ *
1583
+ * Implemented by `cat`-ing the file in a binary-mode `exec` and
1584
+ * collecting stdout. This matches the cross-provider contract (returns a
1585
+ * Node `Buffer` of the file's exact bytes) and avoids the deprecated
1586
+ * 100 MiB FileIO cap on `Sandbox.open()`.
1587
+ */
1588
+ async downloadFile(sourcePath) {
1589
+ this.requireProvisioned();
1590
+ const sandbox = this.requireSandbox();
1591
+ const proc = await sandbox.exec(
1592
+ ["/bin/sh", "-c", `cat -- ${shellQuote(sourcePath)}`],
1593
+ { mode: "binary" }
1594
+ );
1595
+ const [stdoutBytes, stderrBytes, exitCode] = await Promise.all([
1596
+ readStreamAsBytes(proc.stdout),
1597
+ readStreamAsBytes(proc.stderr),
1598
+ proc.wait()
1599
+ ]);
1600
+ if (exitCode !== 0) {
1601
+ const stderr = stderrBytes.toString("utf8").trim();
1602
+ throw new Error(
1603
+ `Failed to download file from Modal sandbox at ${sourcePath} (exit ${exitCode})${stderr ? `: ${stderr}` : ""}`
1604
+ );
1605
+ }
1606
+ return stdoutBytes;
1607
+ }
1538
1608
  async list(options) {
1539
1609
  const sandboxes = [];
1540
1610
  for await (const sandbox of this.client.sandboxes.list({
@@ -155,6 +155,7 @@ function toAISDKEvent(event) {
155
155
  };
156
156
  case "message.completed":
157
157
  case "run.completed":
158
+ case "run.cancelled":
158
159
  return {
159
160
  type: "response-finish",
160
161
  id: event.runId,
@@ -376,9 +377,130 @@ var OpenCodeLogAssembler = class {
376
377
  return clone(next);
377
378
  }
378
379
  };
380
+ var ClaudeCodeLogAssembler = class {
381
+ currentMessageId = null;
382
+ textByMessageId = /* @__PURE__ */ new Map();
383
+ thinkingByMessageId = /* @__PURE__ */ new Map();
384
+ byMessageId = /* @__PURE__ */ new Map();
385
+ process(event) {
386
+ if (!isRecord(event)) return [];
387
+ const type = typeof event.type === "string" ? event.type : "";
388
+ if (type === "stream_event") {
389
+ const stream = isRecord(event.event) ? event.event : null;
390
+ if (!stream) return [];
391
+ const streamType = typeof stream.type === "string" ? stream.type : "";
392
+ if (streamType === "message_start") {
393
+ const message = isRecord(stream.message) ? stream.message : null;
394
+ const id = message && typeof message.id === "string" ? message.id : null;
395
+ if (!id) return [];
396
+ this.currentMessageId = id;
397
+ if (!this.textByMessageId.has(id)) this.textByMessageId.set(id, "");
398
+ if (!this.thinkingByMessageId.has(id))
399
+ this.thinkingByMessageId.set(id, "");
400
+ return [this.upsertMessage(id)];
401
+ }
402
+ if (streamType === "content_block_delta") {
403
+ const id = this.currentMessageId;
404
+ if (!id) return [];
405
+ const delta = isRecord(stream.delta) ? stream.delta : null;
406
+ if (!delta) return [];
407
+ if (delta.type === "text_delta" && typeof delta.text === "string" && delta.text) {
408
+ const text = (this.textByMessageId.get(id) ?? "") + delta.text;
409
+ this.textByMessageId.set(id, text);
410
+ return [this.upsertMessage(id)];
411
+ }
412
+ if (delta.type === "thinking_delta" && typeof delta.thinking === "string" && delta.thinking) {
413
+ const thinking = (this.thinkingByMessageId.get(id) ?? "") + delta.thinking;
414
+ this.thinkingByMessageId.set(id, thinking);
415
+ return [this.upsertMessage(id)];
416
+ }
417
+ return [];
418
+ }
419
+ return [];
420
+ }
421
+ if (type === "assistant") {
422
+ const message = isRecord(event.message) ? event.message : null;
423
+ const id = message && typeof message.id === "string" ? message.id : null;
424
+ if (!id || !message) {
425
+ return [clone(event)];
426
+ }
427
+ const final = extractClaudeAssistantContent(message);
428
+ this.textByMessageId.set(id, final.text);
429
+ this.thinkingByMessageId.set(id, final.thinking);
430
+ const snapshot = this.upsertMessage(id, final.extraBlocks);
431
+ this.currentMessageId = null;
432
+ return [snapshot];
433
+ }
434
+ return [clone(event)];
435
+ }
436
+ seed(snapshots) {
437
+ this.currentMessageId = null;
438
+ this.textByMessageId.clear();
439
+ this.thinkingByMessageId.clear();
440
+ this.byMessageId.clear();
441
+ for (const snapshot of snapshots) {
442
+ if (!isRecord(snapshot)) continue;
443
+ if (snapshot.type !== "message.updated") continue;
444
+ const messageId = typeof snapshot.messageId === "string" ? snapshot.messageId : null;
445
+ if (!messageId) continue;
446
+ this.byMessageId.set(messageId, clone(snapshot));
447
+ const message = isRecord(snapshot.message) ? snapshot.message : null;
448
+ const content = message && Array.isArray(message.content) ? message.content : [];
449
+ let text = "";
450
+ let thinking = "";
451
+ for (const block of content) {
452
+ if (!isRecord(block)) continue;
453
+ if (block.type === "text" && typeof block.text === "string") {
454
+ text += block.text;
455
+ } else if (block.type === "thinking" && typeof block.thinking === "string") {
456
+ thinking += block.thinking;
457
+ }
458
+ }
459
+ this.textByMessageId.set(messageId, text);
460
+ this.thinkingByMessageId.set(messageId, thinking);
461
+ }
462
+ }
463
+ upsertMessage(messageId, extraBlocks = []) {
464
+ const text = this.textByMessageId.get(messageId) ?? "";
465
+ const thinking = this.thinkingByMessageId.get(messageId) ?? "";
466
+ const content = [];
467
+ if (text) content.push({ type: "text", text });
468
+ if (thinking) content.push({ type: "thinking", thinking });
469
+ for (const block of extraBlocks) content.push(clone(block));
470
+ const next = {
471
+ type: "message.updated",
472
+ messageId,
473
+ message: {
474
+ id: messageId,
475
+ role: "assistant",
476
+ content
477
+ }
478
+ };
479
+ this.byMessageId.set(messageId, next);
480
+ return clone(next);
481
+ }
482
+ };
483
+ function extractClaudeAssistantContent(message) {
484
+ const content = Array.isArray(message.content) ? message.content : [];
485
+ let text = "";
486
+ let thinking = "";
487
+ const extraBlocks = [];
488
+ for (const block of content) {
489
+ if (!isRecord(block)) continue;
490
+ if (block.type === "text" && typeof block.text === "string") {
491
+ text += block.text;
492
+ } else if (block.type === "thinking" && typeof block.thinking === "string") {
493
+ thinking += block.thinking;
494
+ } else {
495
+ extraBlocks.push(clone(block));
496
+ }
497
+ }
498
+ return { text, thinking, extraBlocks };
499
+ }
379
500
  var ProviderLogAssembler = class {
380
501
  codex = new CodexLogAssembler();
381
502
  openCode = new OpenCodeLogAssembler();
503
+ claudeCode = new ClaudeCodeLogAssembler();
382
504
  /**
383
505
  * Process a raw provider event and return any newly-produced assembled
384
506
  * snapshots. May return an empty array when the event is non-stateful (e.g.
@@ -391,6 +513,9 @@ var ProviderLogAssembler = class {
391
513
  if (provider === AgentProvider.OpenCode || provider === "opencode") {
392
514
  return this.openCode.process(event);
393
515
  }
516
+ if (provider === AgentProvider.ClaudeCode || provider === "claude-code") {
517
+ return this.claudeCode.process(event);
518
+ }
394
519
  if (isRecord(event)) {
395
520
  return [clone(event)];
396
521
  }
@@ -411,14 +536,17 @@ var ProviderLogAssembler = class {
411
536
  this.openCode.seed(snapshots);
412
537
  return;
413
538
  }
539
+ if (provider === AgentProvider.ClaudeCode || provider === "claude-code") {
540
+ this.claudeCode.seed(snapshots);
541
+ return;
542
+ }
414
543
  }
415
544
  /**
416
545
  * Given a sequence of assembled snapshots (typically the persisted history
417
546
  * for a run), return one entry per item / part with the latest snapshot
418
547
  * winning, preserving first-seen order.
419
548
  *
420
- * For providers that don't have a stateful item model (Claude Code), or
421
- * for unrecognized snapshot shapes, entries are returned in original order
549
+ * For unrecognized snapshot shapes, entries are returned in original order
422
550
  * with no dedup.
423
551
  */
424
552
  static dedupeSnapshots(provider, snapshots) {
@@ -429,6 +557,12 @@ var ProviderLogAssembler = class {
429
557
  return item && typeof item.id === "string" ? `item:${item.id}` : null;
430
558
  });
431
559
  }
560
+ if (provider === AgentProvider.ClaudeCode || provider === "claude-code") {
561
+ return dedupeByKey(snapshots, (snapshot) => {
562
+ const messageId = typeof snapshot.messageId === "string" ? snapshot.messageId : null;
563
+ return messageId ? `message:${messageId}` : null;
564
+ });
565
+ }
432
566
  if (provider === AgentProvider.OpenCode || provider === "opencode") {
433
567
  return dedupeByKey(snapshots, (snapshot) => {
434
568
  const properties = isRecord(snapshot.properties) ? snapshot.properties : null;
@@ -2,7 +2,7 @@ import {
2
2
  createNormalizedEvent,
3
3
  normalizeRawAgentEvent,
4
4
  toAISDKStream
5
- } from "./chunk-ZOWBRUQR.js";
5
+ } from "./chunk-NWAXQ7UD.js";
6
6
  import {
7
7
  AgentBoxError,
8
8
  AsyncQueue,
@@ -19,7 +19,7 @@ import {
19
19
  sleep,
20
20
  time,
21
21
  waitFor
22
- } from "./chunk-INMA52FV.js";
22
+ } from "./chunk-AVXJMCBC.js";
23
23
  import {
24
24
  shellQuote
25
25
  } from "./chunk-NSJM57Z4.js";
@@ -1445,7 +1445,10 @@ function extractCodexCostData(events) {
1445
1445
  let sawUsage = false;
1446
1446
  for (const event of events) {
1447
1447
  const params = asRecord(event.params);
1448
- const usageCandidate = asRecord(event.usage) ?? asRecord(params?.usage) ?? asRecord(params?.tokenUsage) ?? asRecord(asRecord(params?.turn)?.usage) ?? asRecord(asRecord(params?.turn)?.tokenUsage);
1448
+ const tokenUsage = asRecord(params?.tokenUsage);
1449
+ const turn = asRecord(params?.turn);
1450
+ const turnTokenUsage = asRecord(turn?.tokenUsage);
1451
+ const usageCandidate = asRecord(event.usage) ?? asRecord(params?.usage) ?? asRecord(tokenUsage?.last) ?? asRecord(tokenUsage?.total) ?? tokenUsage ?? asRecord(turn?.usage) ?? asRecord(turnTokenUsage?.last) ?? asRecord(turnTokenUsage?.total) ?? turnTokenUsage;
1449
1452
  if (usageCandidate) {
1450
1453
  sawUsage = true;
1451
1454
  mergeUsage(usage, usageCandidate);
@@ -1513,12 +1516,23 @@ function buildClaudeQueryOptions(params) {
1513
1516
  settings: params.settingsPath,
1514
1517
  extraArgs,
1515
1518
  includePartialMessages: true,
1519
+ thinking: { type: "adaptive", display: "summarized" },
1516
1520
  ...run.model ? { model: run.model } : {},
1517
1521
  ...run.reasoning ? { effort: run.reasoning } : {},
1518
1522
  ...provider?.permissionMode ? { permissionMode: provider.permissionMode } : {},
1519
1523
  ...provider?.permissionMode === "bypassPermissions" ? { allowDangerouslySkipPermissions: true } : {},
1520
1524
  ...provider?.allowedTools?.length ? { allowedTools: provider.allowedTools } : {},
1521
- ...run.resumeSessionId ? { resume: run.resumeSessionId } : {}
1525
+ ...run.resumeSessionId ? { resume: run.resumeSessionId } : {},
1526
+ // Fork-at-message: claude-agent-sdk natively supports slicing a
1527
+ // resumed transcript at a message UUID and writing the continuation
1528
+ // under a new session id when `forkSession: true` is set. The
1529
+ // captured message UUID comes from `SDKAssistantMessage.uuid`,
1530
+ // surfaced on normalized `message.started` events.
1531
+ ...run.forkSessionId ? {
1532
+ resume: run.forkSessionId,
1533
+ resumeSessionAt: run.forkAtMessageId,
1534
+ forkSession: true
1535
+ } : {}
1522
1536
  };
1523
1537
  }
1524
1538
  function toRawEvent(runId, payload, type) {
@@ -2092,6 +2106,8 @@ var ClaudeCodeAgentAdapter = class {
2092
2106
  let pendingMessages = 1;
2093
2107
  let firstStreamEventLogged = false;
2094
2108
  let firstTextDeltaLogged = false;
2109
+ let lastTerminalReason;
2110
+ let lastIsError = false;
2095
2111
  const rawPayloads = [];
2096
2112
  try {
2097
2113
  for await (const item of parseNdjsonStream(response.body)) {
@@ -2179,6 +2195,8 @@ var ClaudeCodeAgentAdapter = class {
2179
2195
  }
2180
2196
  if (message.type === "result") {
2181
2197
  const result = message;
2198
+ lastTerminalReason = result.terminal_reason;
2199
+ lastIsError = result.is_error;
2182
2200
  const resultText = result.subtype === "success" ? result.result : accumulatedText;
2183
2201
  if (resultText && resultText !== accumulatedText) {
2184
2202
  accumulatedText = resultText;
@@ -2189,22 +2207,43 @@ var ClaudeCodeAgentAdapter = class {
2189
2207
  }
2190
2208
  }
2191
2209
  const finalText = accumulatedText;
2192
- debugClaude(
2193
- "\u2605 run.completed (%dms since execute start) chars=%d",
2194
- Date.now() - executeStartedAt,
2195
- finalText.length
2196
- );
2197
- sink.emitEvent(
2198
- createNormalizedEvent(
2199
- "run.completed",
2200
- { provider: request.provider, runId: request.runId },
2201
- { text: finalText }
2202
- )
2203
- );
2204
- sink.complete({
2205
- text: finalText,
2206
- costData: extractClaudeCostData(rawPayloads)
2207
- });
2210
+ const isCancelled = lastTerminalReason === "aborted_streaming" || lastTerminalReason === "aborted_tools";
2211
+ const isError = !isCancelled && lastIsError;
2212
+ if (isCancelled) {
2213
+ debugClaude(
2214
+ "\u2605 run.cancelled (%dms since execute start) reason=%s",
2215
+ Date.now() - executeStartedAt,
2216
+ lastTerminalReason
2217
+ );
2218
+ sink.cancel({
2219
+ text: finalText,
2220
+ costData: extractClaudeCostData(rawPayloads)
2221
+ });
2222
+ } else if (isError) {
2223
+ debugClaude(
2224
+ "\u2605 run.error (%dms since execute start) reason=%s",
2225
+ Date.now() - executeStartedAt,
2226
+ lastTerminalReason
2227
+ );
2228
+ sink.fail(new Error(finalText || `claude-code run failed (terminal_reason: ${lastTerminalReason})`));
2229
+ } else {
2230
+ debugClaude(
2231
+ "\u2605 run.completed (%dms since execute start) chars=%d",
2232
+ Date.now() - executeStartedAt,
2233
+ finalText.length
2234
+ );
2235
+ sink.emitEvent(
2236
+ createNormalizedEvent(
2237
+ "run.completed",
2238
+ { provider: request.provider, runId: request.runId },
2239
+ { text: finalText }
2240
+ )
2241
+ );
2242
+ sink.complete({
2243
+ text: finalText,
2244
+ costData: extractClaudeCostData(rawPayloads)
2245
+ });
2246
+ }
2208
2247
  } finally {
2209
2248
  fetchAbort.abort();
2210
2249
  }
@@ -2487,7 +2526,8 @@ function buildThreadParams(cwd, options, request) {
2487
2526
  // Persist the rollout on disk so follow-up runs can call `thread/resume`.
2488
2527
  // `ephemeral: true` threads have no rollout file and resume fails with
2489
2528
  // "no rollout found for thread id ...".
2490
- experimentalRawEvents: true
2529
+ experimentalRawEvents: true,
2530
+ developerInstructions: request.run.systemPrompt ?? null
2491
2531
  };
2492
2532
  }
2493
2533
  function buildResumeParams(cwd, options, request) {
@@ -2496,7 +2536,18 @@ function buildResumeParams(cwd, options, request) {
2496
2536
  cwd,
2497
2537
  model: request.run.model ?? null,
2498
2538
  approvalPolicy: isInteractiveApproval(options) ? "untrusted" : "never",
2499
- sandbox: buildCodexSandboxMode(options)
2539
+ sandbox: buildCodexSandboxMode(options),
2540
+ developerInstructions: request.run.systemPrompt ?? null
2541
+ };
2542
+ }
2543
+ function buildForkParams(cwd, options, request) {
2544
+ return {
2545
+ threadId: request.run.forkSessionId,
2546
+ cwd,
2547
+ model: request.run.model ?? null,
2548
+ approvalPolicy: isInteractiveApproval(options) ? "untrusted" : "never",
2549
+ sandbox: buildCodexSandboxMode(options),
2550
+ developerInstructions: request.run.systemPrompt ?? null
2500
2551
  };
2501
2552
  }
2502
2553
  function buildTurnSandboxPolicy(options) {
@@ -2514,27 +2565,14 @@ function buildTurnSandboxPolicy(options) {
2514
2565
  networkAccess: "enabled"
2515
2566
  };
2516
2567
  }
2517
- function buildTurnCollaborationMode(request) {
2518
- const systemPrompt = request.run.systemPrompt;
2519
- if (!systemPrompt) {
2520
- return void 0;
2521
- }
2522
- return {
2523
- mode: "custom",
2524
- settings: {
2525
- developer_instructions: systemPrompt
2526
- }
2527
- };
2528
- }
2529
2568
  function buildCodexTurnStartParams(params) {
2530
- const { threadId, inputItems, request, turnStartOverrides } = params;
2569
+ const { threadId, inputItems, request } = params;
2531
2570
  const sandboxPolicy = buildTurnSandboxPolicy(request.options);
2532
2571
  return {
2533
2572
  threadId,
2534
2573
  input: inputItems,
2535
2574
  approvalPolicy: isInteractiveApproval(request.options) ? "untrusted" : "never",
2536
2575
  ...sandboxPolicy ? { sandboxPolicy } : {},
2537
- ...turnStartOverrides ?? {},
2538
2576
  model: request.run.model ?? null,
2539
2577
  effort: request.run.reasoning ?? null,
2540
2578
  outputSchema: null
@@ -2998,8 +3036,7 @@ async function createRuntime(request, inputParts) {
2998
3036
  port: REMOTE_CODEX_APP_SERVER_PORT,
2999
3037
  codexDir
3000
3038
  },
3001
- inputItems,
3002
- turnStartOverrides: buildTurnCollaborationMode(request)
3039
+ inputItems
3003
3040
  };
3004
3041
  }
3005
3042
  const codexArgs = buildCodexCommandArgs(
@@ -3037,8 +3074,7 @@ async function createRuntime(request, inputParts) {
3037
3074
  await handle.kill();
3038
3075
  },
3039
3076
  raw: { handle, codexDir },
3040
- inputItems,
3041
- turnStartOverrides: buildTurnCollaborationMode(request)
3077
+ inputItems
3042
3078
  };
3043
3079
  }
3044
3080
  const processHandle = spawnCommand({
@@ -3060,8 +3096,7 @@ async function createRuntime(request, inputParts) {
3060
3096
  await processHandle.kill();
3061
3097
  },
3062
3098
  raw: { processHandle, codexDir },
3063
- inputItems,
3064
- turnStartOverrides: buildTurnCollaborationMode(request)
3099
+ inputItems
3065
3100
  };
3066
3101
  }
3067
3102
  async function buildCodexInputItems(options, inputParts) {
@@ -3118,7 +3153,9 @@ var CodexAgentAdapter = class {
3118
3153
  let rootThreadId;
3119
3154
  let turnId;
3120
3155
  let pendingTurns = 1;
3156
+ let abortInvoked = false;
3121
3157
  sink.setAbort(async () => {
3158
+ abortInvoked = true;
3122
3159
  const threadIdAtAbort = rootThreadId;
3123
3160
  const turnIdAtAbort = turnId;
3124
3161
  if (threadIdAtAbort && turnIdAtAbort) {
@@ -3164,8 +3201,8 @@ var CodexAgentAdapter = class {
3164
3201
  };
3165
3202
  sink.onMessage(sendTurn);
3166
3203
  const rawPayloads = [];
3204
+ let streamedText = "";
3167
3205
  const completion = new Promise((resolve, reject) => {
3168
- let finalText = "";
3169
3206
  void (async () => {
3170
3207
  let firstClientMessageLogged = false;
3171
3208
  for await (const message of client.messages()) {
@@ -3202,7 +3239,7 @@ var CodexAgentAdapter = class {
3202
3239
  for (const event of toNormalizedCodexEvents(request.runId, message)) {
3203
3240
  sink.emitEvent(event);
3204
3241
  if (event.type === "text.delta") {
3205
- finalText += event.delta;
3242
+ streamedText += event.delta;
3206
3243
  }
3207
3244
  }
3208
3245
  if (message.method === "thread/started" && !rootThreadId) {
@@ -3214,7 +3251,14 @@ var CodexAgentAdapter = class {
3214
3251
  if (message.method === "turn/completed" && (!message.params?.threadId || message.params.threadId === rootThreadId)) {
3215
3252
  pendingTurns--;
3216
3253
  if (pendingTurns <= 0) {
3217
- resolve({ text: finalText, turnId, threadId: rootThreadId });
3254
+ const turn = message.params?.turn;
3255
+ const interrupted = turn?.status === "interrupted";
3256
+ resolve({
3257
+ text: streamedText,
3258
+ turnId,
3259
+ threadId: rootThreadId,
3260
+ interrupted
3261
+ });
3218
3262
  return;
3219
3263
  }
3220
3264
  }
@@ -3241,13 +3285,27 @@ var CodexAgentAdapter = class {
3241
3285
  await client.notify("initialized", {});
3242
3286
  }
3243
3287
  const cwd = request.options.cwd ?? process.cwd();
3244
- const threadResponse = request.run.resumeSessionId ? await client.request(
3245
- "thread/resume",
3246
- buildResumeParams(cwd, request.options, request)
3247
- ) : await client.request(
3248
- "thread/start",
3249
- buildThreadParams(cwd, request.options, request)
3250
- );
3288
+ let threadResponse;
3289
+ let threadResultEventName;
3290
+ if (request.run.forkSessionId) {
3291
+ threadResponse = await client.request(
3292
+ "thread/fork",
3293
+ buildForkParams(cwd, request.options, request)
3294
+ );
3295
+ threadResultEventName = "thread/fork:result";
3296
+ } else if (request.run.resumeSessionId) {
3297
+ threadResponse = await client.request(
3298
+ "thread/resume",
3299
+ buildResumeParams(cwd, request.options, request)
3300
+ );
3301
+ threadResultEventName = "thread/resume:result";
3302
+ } else {
3303
+ threadResponse = await client.request(
3304
+ "thread/start",
3305
+ buildThreadParams(cwd, request.options, request)
3306
+ );
3307
+ threadResultEventName = "thread/start:result";
3308
+ }
3251
3309
  rootThreadId = threadResponse.thread.id;
3252
3310
  if ("bindThread" in client && typeof client.bindThread === "function") {
3253
3311
  client.bindThread(threadResponse.thread.id);
@@ -3255,28 +3313,79 @@ var CodexAgentAdapter = class {
3255
3313
  sink.setSessionId(threadResponse.thread.id);
3256
3314
  rawPayloads.push(threadResponse);
3257
3315
  sink.emitRaw(
3258
- toRawEvent2(
3259
- request.runId,
3260
- threadResponse,
3261
- request.run.resumeSessionId ? "thread/resume:result" : "thread/start:result"
3262
- )
3316
+ toRawEvent2(request.runId, threadResponse, threadResultEventName)
3263
3317
  );
3318
+ if (request.run.forkSessionId) {
3319
+ const targetTurnId = request.run.forkAtMessageId;
3320
+ const turns = threadResponse.thread.turns ?? [];
3321
+ const targetIndex = turns.findIndex((turn) => turn.id === targetTurnId);
3322
+ if (targetIndex < 0) {
3323
+ throw new Error(
3324
+ `Codex fork: turn id ${String(targetTurnId)} not found in source thread ${request.run.forkSessionId}.`
3325
+ );
3326
+ }
3327
+ const numTurns = turns.length - 1 - targetIndex;
3328
+ if (numTurns > 0) {
3329
+ const rollbackResponse = await client.request(
3330
+ "thread/rollback",
3331
+ { threadId: rootThreadId, numTurns }
3332
+ );
3333
+ rawPayloads.push(rollbackResponse);
3334
+ sink.emitRaw(
3335
+ toRawEvent2(
3336
+ request.runId,
3337
+ rollbackResponse,
3338
+ "thread/rollback:result"
3339
+ )
3340
+ );
3341
+ }
3342
+ }
3264
3343
  await client.request(
3265
3344
  "turn/start",
3266
3345
  buildCodexTurnStartParams({
3267
3346
  threadId: threadResponse.thread.id,
3268
3347
  inputItems: runtime.inputItems,
3269
- request,
3270
- turnStartOverrides: runtime.turnStartOverrides
3348
+ request
3271
3349
  })
3272
3350
  );
3273
- const { text } = await completion;
3274
- debugCodex(
3275
- "\u2605 run.completed (%dms since execute start) chars=%d",
3276
- Date.now() - executeStartedAt,
3277
- text?.length ?? 0
3278
- );
3279
- sink.complete({ text, costData: extractCodexCostData(rawPayloads) });
3351
+ let completionResult;
3352
+ let completionError;
3353
+ try {
3354
+ completionResult = await completion;
3355
+ } catch (err) {
3356
+ completionError = err;
3357
+ }
3358
+ if (completionError !== void 0) {
3359
+ if (abortInvoked) {
3360
+ debugCodex(
3361
+ "\u2605 run.cancelled (%dms since execute start)",
3362
+ Date.now() - executeStartedAt
3363
+ );
3364
+ sink.cancel({
3365
+ text: streamedText || void 0,
3366
+ costData: extractCodexCostData(rawPayloads)
3367
+ });
3368
+ } else {
3369
+ sink.fail(completionError);
3370
+ }
3371
+ } else {
3372
+ const { text, interrupted } = completionResult;
3373
+ if (abortInvoked || interrupted) {
3374
+ debugCodex(
3375
+ "\u2605 run.cancelled (%dms since execute start) interrupted=%s",
3376
+ Date.now() - executeStartedAt,
3377
+ interrupted
3378
+ );
3379
+ sink.cancel({ text, costData: extractCodexCostData(rawPayloads) });
3380
+ } else {
3381
+ debugCodex(
3382
+ "\u2605 run.completed (%dms since execute start) chars=%d",
3383
+ Date.now() - executeStartedAt,
3384
+ text?.length ?? 0
3385
+ );
3386
+ sink.complete({ text, costData: extractCodexCostData(rawPayloads) });
3387
+ }
3388
+ }
3280
3389
  } finally {
3281
3390
  await runtime.cleanup().catch(() => void 0);
3282
3391
  }
@@ -3521,10 +3630,15 @@ function buildOpenCodeConfig(options, systemPrompt, interactiveApproval) {
3521
3630
  { ...baseAgent, reasoningEffort: level }
3522
3631
  ])
3523
3632
  );
3633
+ const googleBaseUrl = options.env?.GOOGLE_BASE_URL;
3524
3634
  return {
3525
3635
  $schema: "https://opencode.ai/config.json",
3526
3636
  ...mcpConfig ? { mcp: mcpConfig } : {},
3527
3637
  ...commandsConfig ? { command: commandsConfig } : {},
3638
+ provider: {
3639
+ openrouter: { options: { baseURL: "https://openrouter.ai/api/v1" } },
3640
+ ...googleBaseUrl ? { google: { options: { baseURL: googleBaseUrl } } } : {}
3641
+ },
3528
3642
  agent: {
3529
3643
  agentbox: baseAgent,
3530
3644
  ...reasoningVariants,
@@ -3820,7 +3934,11 @@ var OpenCodeAgentAdapter = class {
3820
3934
  let sseTask;
3821
3935
  const dispatchAbort = new AbortController();
3822
3936
  let capturedSessionId;
3937
+ let sessionErrorFromSse;
3938
+ let sessionAbortedFromSse = false;
3939
+ let userAbortRequested = false;
3823
3940
  sink.setAbort(async () => {
3941
+ userAbortRequested = true;
3824
3942
  const sessionIdAtAbort = capturedSessionId;
3825
3943
  if (sessionIdAtAbort) {
3826
3944
  try {
@@ -3849,7 +3967,23 @@ var OpenCodeAgentAdapter = class {
3849
3967
  });
3850
3968
  try {
3851
3969
  const interactiveApproval = isInteractiveApproval(request.options);
3852
- const createdSession = request.run.resumeSessionId ? null : await fetchJson(
3970
+ let forkedSession = null;
3971
+ if (request.run.forkSessionId) {
3972
+ forkedSession = await fetchJson(
3973
+ `${runtime.baseUrl}/session/${encodeURIComponent(request.run.forkSessionId)}/fork`,
3974
+ {
3975
+ method: "POST",
3976
+ headers: {
3977
+ "content-type": "application/json",
3978
+ ...runtime.previewHeaders
3979
+ },
3980
+ body: JSON.stringify({
3981
+ messageID: request.run.forkAtMessageId
3982
+ })
3983
+ }
3984
+ );
3985
+ }
3986
+ const createdSession = request.run.resumeSessionId || forkedSession ? null : await fetchJson(
3853
3987
  `${runtime.baseUrl}/session`,
3854
3988
  {
3855
3989
  method: "POST",
@@ -3862,7 +3996,7 @@ var OpenCodeAgentAdapter = class {
3862
3996
  })
3863
3997
  }
3864
3998
  );
3865
- const sessionId = request.run.resumeSessionId ?? createdSession?.id ?? createdSession?.sessionId;
3999
+ const sessionId = request.run.resumeSessionId ?? forkedSession?.id ?? forkedSession?.sessionId ?? createdSession?.id ?? createdSession?.sessionId;
3866
4000
  if (!sessionId) {
3867
4001
  throw new Error("OpenCode did not return a session id.");
3868
4002
  }
@@ -3952,6 +4086,15 @@ var OpenCodeAgentAdapter = class {
3952
4086
  const properties = payloadRecord.properties;
3953
4087
  const eventSessionId = typeof properties?.sessionID === "string" ? properties.sessionID : void 0;
3954
4088
  if (!eventSessionId || eventSessionId === sessionId) {
4089
+ if (payloadRecord.type === "session.error") {
4090
+ const errData = properties?.error;
4091
+ if (errData?.name === "MessageAbortedError") {
4092
+ sessionAbortedFromSse = true;
4093
+ } else {
4094
+ const errMsg = typeof errData?.data?.message === "string" ? errData.data.message : typeof errData?.message === "string" ? errData.message : "OpenCode session error";
4095
+ sessionErrorFromSse = new Error(errMsg);
4096
+ }
4097
+ }
3955
4098
  debugOpencode(
3956
4099
  "\u2605 %s for session=%s \u2014 aborting in-flight dispatch",
3957
4100
  payloadRecord.type,
@@ -4121,30 +4264,48 @@ var OpenCodeAgentAdapter = class {
4121
4264
  pendingMessages++;
4122
4265
  void dispatchMessage(mapToOpenCodeParts(inputParts));
4123
4266
  await allDone;
4124
- if (dispatchError && !dispatchAbort.signal.aborted) {
4125
- throw dispatchError;
4267
+ if (userAbortRequested || sessionAbortedFromSse) {
4268
+ debugOpencode(
4269
+ "\u2605 run.cancelled (%dms since execute start)",
4270
+ Date.now() - executeStartedAt
4271
+ );
4272
+ sseAbort.abort();
4273
+ await sseTask;
4274
+ sink.cancel({
4275
+ text: streamedTextFromSse || void 0,
4276
+ costData: extractOpenCodeCostData(rawPayloads)
4277
+ });
4278
+ } else if (sessionErrorFromSse) {
4279
+ sseAbort.abort();
4280
+ await sseTask;
4281
+ sink.fail(sessionErrorFromSse);
4282
+ } else if (dispatchError && !(dispatchAbort.signal.aborted && dispatchError?.name === "AbortError")) {
4283
+ sseAbort.abort();
4284
+ await sseTask;
4285
+ sink.fail(dispatchError);
4286
+ } else {
4287
+ debugOpencode(
4288
+ "\u2605 run.completed (%dms since execute start) chars=%d",
4289
+ Date.now() - executeStartedAt,
4290
+ finalText.length
4291
+ );
4292
+ sink.emitEvent(
4293
+ createNormalizedEvent(
4294
+ "run.completed",
4295
+ {
4296
+ provider: request.provider,
4297
+ runId: request.runId
4298
+ },
4299
+ { text: finalText }
4300
+ )
4301
+ );
4302
+ sseAbort.abort();
4303
+ await sseTask;
4304
+ sink.complete({
4305
+ text: finalText,
4306
+ costData: extractOpenCodeCostData(rawPayloads)
4307
+ });
4126
4308
  }
4127
- debugOpencode(
4128
- "\u2605 run.completed (%dms since execute start) chars=%d",
4129
- Date.now() - executeStartedAt,
4130
- finalText.length
4131
- );
4132
- sink.emitEvent(
4133
- createNormalizedEvent(
4134
- "run.completed",
4135
- {
4136
- provider: request.provider,
4137
- runId: request.runId
4138
- },
4139
- { text: finalText }
4140
- )
4141
- );
4142
- sseAbort.abort();
4143
- await sseTask;
4144
- sink.complete({
4145
- text: finalText,
4146
- costData: extractOpenCodeCostData(rawPayloads)
4147
- });
4148
4309
  } finally {
4149
4310
  sseAbort.abort();
4150
4311
  if (sseTask) {
@@ -4308,17 +4469,14 @@ var AgentRunController = class {
4308
4469
  resolveSessionIdReady;
4309
4470
  rejectSessionIdReady;
4310
4471
  resolveFinished;
4311
- rejectFinished;
4312
4472
  constructor(provider, id) {
4313
4473
  this.provider = provider;
4314
4474
  this.id = id;
4315
4475
  let resolveFinished;
4316
- let rejectFinished;
4317
4476
  let resolveSessionIdReady;
4318
4477
  let rejectSessionIdReady;
4319
- this.finished = new Promise((resolve, reject) => {
4478
+ this.finished = new Promise((resolve) => {
4320
4479
  resolveFinished = resolve;
4321
- rejectFinished = reject;
4322
4480
  });
4323
4481
  this.sessionIdReady = new Promise((resolve, reject) => {
4324
4482
  resolveSessionIdReady = resolve;
@@ -4326,7 +4484,6 @@ var AgentRunController = class {
4326
4484
  });
4327
4485
  void this.sessionIdReady.catch(() => void 0);
4328
4486
  this.resolveFinished = resolveFinished;
4329
- this.rejectFinished = rejectFinished;
4330
4487
  this.resolveSessionIdReady = resolveSessionIdReady;
4331
4488
  this.rejectSessionIdReady = rejectSessionIdReady;
4332
4489
  }
@@ -4462,11 +4619,19 @@ var AgentRunController = class {
4462
4619
  this.eventQueue.finish();
4463
4620
  this.rawQueue.finish();
4464
4621
  if (!this.sessionId) {
4465
- const error = new Error(
4466
- "Agent run completed before a provider session id was set."
4467
- );
4468
- this.rejectSessionIdReady(error);
4469
- this.rejectFinished(error);
4622
+ const errorMsg = "Agent run completed before a provider session id was set.";
4623
+ this.rejectSessionIdReady(new Error(errorMsg));
4624
+ this.resolveFinished({
4625
+ id: this.id,
4626
+ provider: this.provider,
4627
+ sessionId: "",
4628
+ text: this.text,
4629
+ rawEvents: [...this.rawEventsList],
4630
+ events: [...this.events],
4631
+ costData: this.costData,
4632
+ isCancelled: false,
4633
+ error: errorMsg
4634
+ });
4470
4635
  return;
4471
4636
  }
4472
4637
  this.resolveFinished({
@@ -4476,7 +4641,42 @@ var AgentRunController = class {
4476
4641
  text: this.text,
4477
4642
  rawEvents: [...this.rawEventsList],
4478
4643
  events: [...this.events],
4479
- costData: this.costData
4644
+ costData: this.costData,
4645
+ isCancelled: false
4646
+ });
4647
+ }
4648
+ cancel(result) {
4649
+ if (this.settled) {
4650
+ return;
4651
+ }
4652
+ this.settled = true;
4653
+ this.clearPendingPermissions(
4654
+ new Error("Agent run was cancelled before pending permission requests resolved.")
4655
+ );
4656
+ if (result?.text) {
4657
+ this.text = result.text;
4658
+ }
4659
+ if (result && "costData" in result) {
4660
+ this.costData = result.costData ?? null;
4661
+ }
4662
+ this.emitEvent(
4663
+ createNormalizedEvent(
4664
+ "run.cancelled",
4665
+ { provider: this.provider, runId: this.id },
4666
+ { text: this.text || void 0 }
4667
+ )
4668
+ );
4669
+ this.eventQueue.finish();
4670
+ this.rawQueue.finish();
4671
+ this.resolveFinished({
4672
+ id: this.id,
4673
+ provider: this.provider,
4674
+ sessionId: this.sessionId ?? "",
4675
+ text: this.text,
4676
+ rawEvents: [...this.rawEventsList],
4677
+ events: [...this.events],
4678
+ costData: this.costData,
4679
+ isCancelled: true
4480
4680
  });
4481
4681
  }
4482
4682
  fail(error) {
@@ -4503,7 +4703,17 @@ var AgentRunController = class {
4503
4703
  if (!this.sessionId) {
4504
4704
  this.rejectSessionIdReady(normalizedError);
4505
4705
  }
4506
- this.rejectFinished(normalizedError);
4706
+ this.resolveFinished({
4707
+ id: this.id,
4708
+ provider: this.provider,
4709
+ sessionId: this.sessionId ?? "",
4710
+ text: this.text,
4711
+ rawEvents: [...this.rawEventsList],
4712
+ events: [...this.events],
4713
+ costData: this.costData,
4714
+ isCancelled: false,
4715
+ error: normalizedError.message
4716
+ });
4507
4717
  }
4508
4718
  async abort() {
4509
4719
  this.abortRequested = true;
@@ -4585,6 +4795,21 @@ var Agent = class {
4585
4795
  }
4586
4796
  }
4587
4797
  stream(runConfig) {
4798
+ if (runConfig.resumeSessionId && runConfig.forkSessionId) {
4799
+ throw new Error(
4800
+ "AgentRunConfig.resumeSessionId and forkSessionId are mutually exclusive."
4801
+ );
4802
+ }
4803
+ if (runConfig.forkSessionId && !runConfig.forkAtMessageId) {
4804
+ throw new Error(
4805
+ "AgentRunConfig.forkSessionId requires forkAtMessageId."
4806
+ );
4807
+ }
4808
+ if (runConfig.forkAtMessageId && !runConfig.forkSessionId) {
4809
+ throw new Error(
4810
+ "AgentRunConfig.forkAtMessageId requires forkSessionId."
4811
+ );
4812
+ }
4588
4813
  const runId = runConfig.runId ?? randomUUID2();
4589
4814
  const streamCalledAt = Date.now();
4590
4815
  debugAgent("stream() provider=%s runId=%s", this.provider, runId);
@@ -1,4 +1,4 @@
1
- export { A as AISDKEvent, S as MessageCompletedEvent, T as MessageInjectedEvent, U as MessageStartedEvent, V as NormalizedAgentEvent, W as NormalizedAgentEventBase, X as NormalizedAgentEventType, a1 as PermissionRequestedEvent, a2 as PermissionResolvedEvent, a3 as RawAgentEvent, a4 as ReasoningDeltaEvent, a6 as RunCompletedEvent, a7 as RunErrorEvent, a8 as RunStartedEvent, a9 as TextDeltaEvent, ab as ToolCallCompletedEvent, ac as ToolCallDeltaEvent, ad as ToolCallStartedEvent, ag as createNormalizedEvent, ah as normalizeRawAgentEvent, ai as toAISDKEvent, aj as toAISDKStream } from '../types-B3N-Qo2q.js';
1
+ export { A as AISDKEvent, S as MessageCompletedEvent, T as MessageInjectedEvent, U as MessageStartedEvent, V as NormalizedAgentEvent, W as NormalizedAgentEventBase, X as NormalizedAgentEventType, a1 as PermissionRequestedEvent, a2 as PermissionResolvedEvent, a3 as RawAgentEvent, a4 as ReasoningDeltaEvent, a6 as RunCancelledEvent, a7 as RunCompletedEvent, a8 as RunErrorEvent, a9 as RunStartedEvent, aa as TextDeltaEvent, ac as ToolCallCompletedEvent, ad as ToolCallDeltaEvent, ae as ToolCallStartedEvent, ah as createNormalizedEvent, ai as normalizeRawAgentEvent, aj as toAISDKEvent, ak as toAISDKStream } from '../types-Dj_HCr6Q.js';
2
2
  import { AgentProvider } from '../enums.js';
3
3
  import '../Sandbox-CByFJI8X.js';
4
4
  import 'e2b';
@@ -62,6 +62,7 @@ type JsonRecord = Record<string, unknown>;
62
62
  declare class ProviderLogAssembler {
63
63
  private readonly codex;
64
64
  private readonly openCode;
65
+ private readonly claudeCode;
65
66
  /**
66
67
  * Process a raw provider event and return any newly-produced assembled
67
68
  * snapshots. May return an empty array when the event is non-stateful (e.g.
@@ -80,8 +81,7 @@ declare class ProviderLogAssembler {
80
81
  * for a run), return one entry per item / part with the latest snapshot
81
82
  * winning, preserving first-seen order.
82
83
  *
83
- * For providers that don't have a stateful item model (Claude Code), or
84
- * for unrecognized snapshot shapes, entries are returned in original order
84
+ * For unrecognized snapshot shapes, entries are returned in original order
85
85
  * with no dedup.
86
86
  */
87
87
  static dedupeSnapshots(provider: AgentProvider | string | null | undefined, snapshots: JsonRecord[]): JsonRecord[];
@@ -4,7 +4,7 @@ import {
4
4
  normalizeRawAgentEvent,
5
5
  toAISDKEvent,
6
6
  toAISDKStream
7
- } from "../chunk-ZOWBRUQR.js";
7
+ } from "../chunk-NWAXQ7UD.js";
8
8
  import "../chunk-GOFJNFAD.js";
9
9
  export {
10
10
  ProviderLogAssembler,
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as AISDKEvent, a as AgentApprovalMode, b as AgentAttachRequest, c as AgentCommandConfig, d as AgentCostData, e as AgentExecutionRequest, f as AgentLocalMcpConfig, g as AgentMcpConfig, h as AgentOptions, i as AgentOptionsBase, j as AgentOptionsMap, k as AgentPermissionDecision, l as AgentPermissionKind, m as AgentPermissionResponse, n as AgentProviderAdapter, o as AgentProviderName, p as AgentReasoningEffort, q as AgentRemoteMcpConfig, r as AgentResult, s as AgentRun, t as AgentRunConfig, u as AgentRunSink, v as AgentSetupConfig, w as AgentSetupRequest, x as AgentSkillConfig, y as AgentSubAgentConfig, z as AttachedRun, C as ClaudeCodeAgentOptions, B as ClaudeCodeHookConfig, D as ClaudeCodeHookEvent, E as ClaudeCodeHookHandler, F as ClaudeCodeHookMatcherGroup, G as ClaudeCodeHooksConfig, H as ClaudeCodeProviderOptions, I as CodexAgentOptions, J as CodexCommandHook, K as CodexHookEvent, L as CodexHookMatcherGroup, M as CodexHooksConfig, N as CodexProviderOptions, O as DataContent, P as EmbeddedSkillConfig, Q as FilePart, R as ImagePart, S as MessageCompletedEvent, T as MessageInjectedEvent, U as MessageStartedEvent, V as NormalizedAgentEvent, W as NormalizedAgentEventBase, X as NormalizedAgentEventType, Y as OpenCodeAgentOptions, Z as OpenCodePluginConfig, _ as OpenCodePluginEvent, $ as OpenCodePluginHookConfig, a0 as OpenCodeProviderOptions, a1 as PermissionRequestedEvent, a2 as PermissionResolvedEvent, a3 as RawAgentEvent, a4 as ReasoningDeltaEvent, a5 as RepoSkillConfig, a6 as RunCompletedEvent, a7 as RunErrorEvent, a8 as RunStartedEvent, a9 as TextDeltaEvent, aa as TextPart, ab as ToolCallCompletedEvent, ac as ToolCallDeltaEvent, ad as ToolCallStartedEvent, ae as UserContent, af as UserContentPart, ag as createNormalizedEvent, ah as normalizeRawAgentEvent, ai as toAISDKEvent, aj as toAISDKStream } from './types-B3N-Qo2q.js';
1
+ export { A as AISDKEvent, a as AgentApprovalMode, b as AgentAttachRequest, c as AgentCommandConfig, d as AgentCostData, e as AgentExecutionRequest, f as AgentLocalMcpConfig, g as AgentMcpConfig, h as AgentOptions, i as AgentOptionsBase, j as AgentOptionsMap, k as AgentPermissionDecision, l as AgentPermissionKind, m as AgentPermissionResponse, n as AgentProviderAdapter, o as AgentProviderName, p as AgentReasoningEffort, q as AgentRemoteMcpConfig, r as AgentResult, s as AgentRun, t as AgentRunConfig, u as AgentRunSink, v as AgentSetupConfig, w as AgentSetupRequest, x as AgentSkillConfig, y as AgentSubAgentConfig, z as AttachedRun, C as ClaudeCodeAgentOptions, B as ClaudeCodeHookConfig, D as ClaudeCodeHookEvent, E as ClaudeCodeHookHandler, F as ClaudeCodeHookMatcherGroup, G as ClaudeCodeHooksConfig, H as ClaudeCodeProviderOptions, I as CodexAgentOptions, J as CodexCommandHook, K as CodexHookEvent, L as CodexHookMatcherGroup, M as CodexHooksConfig, N as CodexProviderOptions, O as DataContent, P as EmbeddedSkillConfig, Q as FilePart, R as ImagePart, S as MessageCompletedEvent, T as MessageInjectedEvent, U as MessageStartedEvent, V as NormalizedAgentEvent, W as NormalizedAgentEventBase, X as NormalizedAgentEventType, Y as OpenCodeAgentOptions, Z as OpenCodePluginConfig, _ as OpenCodePluginEvent, $ as OpenCodePluginHookConfig, a0 as OpenCodeProviderOptions, a1 as PermissionRequestedEvent, a2 as PermissionResolvedEvent, a3 as RawAgentEvent, a4 as ReasoningDeltaEvent, a5 as RepoSkillConfig, a6 as RunCancelledEvent, a7 as RunCompletedEvent, a8 as RunErrorEvent, a9 as RunStartedEvent, aa as TextDeltaEvent, ab as TextPart, ac as ToolCallCompletedEvent, ad as ToolCallDeltaEvent, ae as ToolCallStartedEvent, af as UserContent, ag as UserContentPart, ah as createNormalizedEvent, ai as normalizeRawAgentEvent, aj as toAISDKEvent, ak as toAISDKStream } from './types-Dj_HCr6Q.js';
2
2
  export { AGENT_RESERVED_PORTS, Agent, collectAllAgentReservedPorts } from './agents/index.js';
3
3
  export { A as AsyncCommandHandle, C as CommandEvent, a as CommandOptions, b as CommandResult, D as DaytonaProviderOptions, c as DaytonaSandboxOptions, E as E2bProviderOptions, d as E2bSandboxOptions, G as GitCloneOptions, L as LocalDockerProviderOptions, e as LocalDockerSandboxOptions, M as ModalProviderOptions, f as ModalSandboxOptions, S as Sandbox, g as SandboxDescriptor, h as SandboxListOptions, i as SandboxOptions, j as SandboxOptionsBase, k as SandboxOptionsMap, l as SandboxProviderName, m as SandboxRaw, n as SandboxRawMap, o as SandboxResourceSpec, T as TarballEntry, V as VercelGitSource, p as VercelProviderOptions, q as VercelSandboxOptions } from './Sandbox-CByFJI8X.js';
4
4
  export { SandboxAdapter, buildGitCloneCommand } from './sandboxes/index.js';
package/dist/index.js CHANGED
@@ -1,22 +1,22 @@
1
1
  import {
2
2
  Agent
3
- } from "./chunk-4MBB6QHD.js";
3
+ } from "./chunk-YAMFJAU6.js";
4
4
  import {
5
5
  ProviderLogAssembler,
6
6
  createNormalizedEvent,
7
7
  normalizeRawAgentEvent,
8
8
  toAISDKEvent,
9
9
  toAISDKStream
10
- } from "./chunk-ZOWBRUQR.js";
10
+ } from "./chunk-NWAXQ7UD.js";
11
11
  import {
12
12
  Sandbox,
13
13
  SandboxAdapter,
14
14
  buildGitCloneCommand
15
- } from "./chunk-LPKKT6YT.js";
15
+ } from "./chunk-DDGBIACF.js";
16
16
  import {
17
17
  AGENT_RESERVED_PORTS,
18
18
  collectAllAgentReservedPorts
19
- } from "./chunk-INMA52FV.js";
19
+ } from "./chunk-AVXJMCBC.js";
20
20
  import "./chunk-NSJM57Z4.js";
21
21
  import {
22
22
  AgentProvider,
@@ -2,8 +2,8 @@ import {
2
2
  Sandbox,
3
3
  SandboxAdapter,
4
4
  buildGitCloneCommand
5
- } from "../chunk-LPKKT6YT.js";
6
- import "../chunk-INMA52FV.js";
5
+ } from "../chunk-DDGBIACF.js";
6
+ import "../chunk-AVXJMCBC.js";
7
7
  import "../chunk-NSJM57Z4.js";
8
8
  import {
9
9
  SandboxProvider
@@ -9,7 +9,7 @@ interface RawAgentEvent<TPayload = unknown> {
9
9
  payload: TPayload;
10
10
  }
11
11
 
12
- type NormalizedAgentEventType = "run.started" | "message.started" | "message.injected" | "text.delta" | "reasoning.delta" | "tool.call.started" | "tool.call.delta" | "tool.call.completed" | "permission.requested" | "permission.resolved" | "message.completed" | "run.completed" | "run.error";
12
+ type NormalizedAgentEventType = "run.started" | "message.started" | "message.injected" | "text.delta" | "reasoning.delta" | "tool.call.started" | "tool.call.delta" | "tool.call.completed" | "permission.requested" | "permission.resolved" | "message.completed" | "run.completed" | "run.cancelled" | "run.error";
13
13
  interface NormalizedAgentEventBase {
14
14
  provider: string;
15
15
  runId: string;
@@ -97,11 +97,15 @@ interface RunCompletedEvent extends NormalizedAgentEventBase {
97
97
  type: "run.completed";
98
98
  text?: string;
99
99
  }
100
+ interface RunCancelledEvent extends NormalizedAgentEventBase {
101
+ type: "run.cancelled";
102
+ text?: string;
103
+ }
100
104
  interface RunErrorEvent extends NormalizedAgentEventBase {
101
105
  type: "run.error";
102
106
  error: string;
103
107
  }
104
- type NormalizedAgentEvent = RunStartedEvent | MessageStartedEvent | MessageInjectedEvent | TextDeltaEvent | ReasoningDeltaEvent | ToolCallStartedEvent | ToolCallDeltaEvent | ToolCallCompletedEvent | PermissionRequestedEvent | PermissionResolvedEvent | MessageCompletedEvent | RunCompletedEvent | RunErrorEvent;
108
+ type NormalizedAgentEvent = RunStartedEvent | MessageStartedEvent | MessageInjectedEvent | TextDeltaEvent | ReasoningDeltaEvent | ToolCallStartedEvent | ToolCallDeltaEvent | ToolCallCompletedEvent | PermissionRequestedEvent | PermissionResolvedEvent | MessageCompletedEvent | RunCompletedEvent | RunCancelledEvent | RunErrorEvent;
105
109
  declare function createNormalizedEvent<TType extends NormalizedAgentEventType>(type: TType, base: Omit<NormalizedAgentEventBase, "type" | "timestamp"> & {
106
110
  timestamp?: string;
107
111
  }, extra?: Record<string, unknown>): NormalizedAgentEvent;
@@ -307,6 +311,26 @@ interface AgentRunConfig {
307
311
  model?: string;
308
312
  systemPrompt?: string;
309
313
  resumeSessionId?: string;
314
+ /**
315
+ * Source session/thread to fork from. The new run begins in a *new*
316
+ * session whose history is the prefix of the source up to and including
317
+ * {@link forkAtMessageId}. Mutually exclusive with {@link resumeSessionId}.
318
+ * Requires {@link forkAtMessageId}.
319
+ *
320
+ * Provider mapping:
321
+ * - claude-code: `query({ resume, resumeSessionAt, forkSession: true })`
322
+ * - opencode: `POST /session/:forkSessionId/fork { messageID }`
323
+ * - codex: emulated via `thread/fork` + `thread/rollback` (no native
324
+ * message-level fork in the codex app-server)
325
+ */
326
+ forkSessionId?: string;
327
+ /**
328
+ * Provider-native message id (claude-code: assistant message UUID;
329
+ * opencode: message info id; codex: turn id) to fork at — inclusive.
330
+ * The unified `messageId` field on `message.started` events carries the
331
+ * value to feed back here. Required when {@link forkSessionId} is set.
332
+ */
333
+ forkAtMessageId?: string;
310
334
  reasoning?: AgentReasoningEffort;
311
335
  }
312
336
  /**
@@ -396,6 +420,8 @@ interface AgentResult {
396
420
  provider: AgentProviderName;
397
421
  sessionId: string;
398
422
  text: string;
423
+ isCancelled: boolean;
424
+ error?: string;
399
425
  rawEvents: RawAgentEvent[];
400
426
  events: NormalizedAgentEvent[];
401
427
  costData?: AgentCostData | null;
@@ -427,6 +453,10 @@ interface AgentRunSink {
427
453
  text?: string;
428
454
  costData?: AgentCostData | null;
429
455
  }): void;
456
+ cancel(result?: {
457
+ text?: string;
458
+ costData?: AgentCostData | null;
459
+ }): void;
430
460
  fail(error: unknown): void;
431
461
  }
432
462
  interface AgentSetupRequest<P extends AgentProviderName = AgentProviderName> {
@@ -524,4 +554,4 @@ interface AgentProviderAdapter<P extends AgentProviderName = AgentProviderName>
524
554
  attachSendMessage(request: AgentAttachRequest<P>, content: UserContent): Promise<void>;
525
555
  }
526
556
 
527
- export { type OpenCodePluginHookConfig as $, type AISDKEvent as A, type ClaudeCodeHookConfig as B, type ClaudeCodeAgentOptions as C, type ClaudeCodeHookEvent as D, type ClaudeCodeHookHandler as E, type ClaudeCodeHookMatcherGroup as F, type ClaudeCodeHooksConfig as G, type ClaudeCodeProviderOptions as H, type CodexAgentOptions as I, type CodexCommandHook as J, type CodexHookEvent as K, type CodexHookMatcherGroup as L, type CodexHooksConfig as M, type CodexProviderOptions as N, type DataContent as O, type EmbeddedSkillConfig as P, type FilePart as Q, type ImagePart as R, type MessageCompletedEvent as S, type MessageInjectedEvent as T, type MessageStartedEvent as U, type NormalizedAgentEvent as V, type NormalizedAgentEventBase as W, type NormalizedAgentEventType as X, type OpenCodeAgentOptions as Y, type OpenCodePluginConfig as Z, type OpenCodePluginEvent as _, type AgentApprovalMode as a, type OpenCodeProviderOptions as a0, type PermissionRequestedEvent as a1, type PermissionResolvedEvent as a2, type RawAgentEvent as a3, type ReasoningDeltaEvent as a4, type RepoSkillConfig as a5, type RunCompletedEvent as a6, type RunErrorEvent as a7, type RunStartedEvent as a8, type TextDeltaEvent as a9, type TextPart as aa, type ToolCallCompletedEvent as ab, type ToolCallDeltaEvent as ac, type ToolCallStartedEvent as ad, type UserContent as ae, type UserContentPart as af, createNormalizedEvent as ag, normalizeRawAgentEvent as ah, toAISDKEvent as ai, toAISDKStream as aj, type AgentAttachRequest as b, type AgentCommandConfig as c, type AgentCostData as d, type AgentExecutionRequest as e, type AgentLocalMcpConfig as f, type AgentMcpConfig as g, type AgentOptions as h, type AgentOptionsBase as i, type AgentOptionsMap as j, type AgentPermissionDecision as k, type AgentPermissionKind as l, type AgentPermissionResponse as m, type AgentProviderAdapter as n, type AgentProviderName as o, type AgentReasoningEffort as p, type AgentRemoteMcpConfig as q, type AgentResult as r, type AgentRun as s, type AgentRunConfig as t, type AgentRunSink as u, type AgentSetupConfig as v, type AgentSetupRequest as w, type AgentSkillConfig as x, type AgentSubAgentConfig as y, type AttachedRun as z };
557
+ export { type OpenCodePluginHookConfig as $, type AISDKEvent as A, type ClaudeCodeHookConfig as B, type ClaudeCodeAgentOptions as C, type ClaudeCodeHookEvent as D, type ClaudeCodeHookHandler as E, type ClaudeCodeHookMatcherGroup as F, type ClaudeCodeHooksConfig as G, type ClaudeCodeProviderOptions as H, type CodexAgentOptions as I, type CodexCommandHook as J, type CodexHookEvent as K, type CodexHookMatcherGroup as L, type CodexHooksConfig as M, type CodexProviderOptions as N, type DataContent as O, type EmbeddedSkillConfig as P, type FilePart as Q, type ImagePart as R, type MessageCompletedEvent as S, type MessageInjectedEvent as T, type MessageStartedEvent as U, type NormalizedAgentEvent as V, type NormalizedAgentEventBase as W, type NormalizedAgentEventType as X, type OpenCodeAgentOptions as Y, type OpenCodePluginConfig as Z, type OpenCodePluginEvent as _, type AgentApprovalMode as a, type OpenCodeProviderOptions as a0, type PermissionRequestedEvent as a1, type PermissionResolvedEvent as a2, type RawAgentEvent as a3, type ReasoningDeltaEvent as a4, type RepoSkillConfig as a5, type RunCancelledEvent as a6, type RunCompletedEvent as a7, type RunErrorEvent as a8, type RunStartedEvent as a9, type TextDeltaEvent as aa, type TextPart as ab, type ToolCallCompletedEvent as ac, type ToolCallDeltaEvent as ad, type ToolCallStartedEvent as ae, type UserContent as af, type UserContentPart as ag, createNormalizedEvent as ah, normalizeRawAgentEvent as ai, toAISDKEvent as aj, toAISDKStream as ak, type AgentAttachRequest as b, type AgentCommandConfig as c, type AgentCostData as d, type AgentExecutionRequest as e, type AgentLocalMcpConfig as f, type AgentMcpConfig as g, type AgentOptions as h, type AgentOptionsBase as i, type AgentOptionsMap as j, type AgentPermissionDecision as k, type AgentPermissionKind as l, type AgentPermissionResponse as m, type AgentProviderAdapter as n, type AgentProviderName as o, type AgentReasoningEffort as p, type AgentRemoteMcpConfig as q, type AgentResult as r, type AgentRun as s, type AgentRunConfig as t, type AgentRunSink as u, type AgentSetupConfig as v, type AgentSetupRequest as w, type AgentSkillConfig as x, type AgentSubAgentConfig as y, type AttachedRun as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentbox-sdk",
3
- "version": "0.1.301",
3
+ "version": "0.1.302",
4
4
  "description": "Swappable coding agents and sandbox providers for Bun and TypeScript.",
5
5
  "license": "MIT",
6
6
  "repository": {