agentbox-sdk 0.1.309 → 0.1.311

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, t as AgentRunConfig, s as AgentRun, r as AgentResult, a2 as RawAgentEvent, b as AgentAttachRequest, y as AttachedRun, a9 as SetupLayout } from '../types-DmkbgYmn.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, v as AgentSetupRequest, w as AgentSkillConfig, x as AgentSubAgentConfig, C as ClaudeCodeAgentOptions, z as ClaudeCodeHookConfig, B as ClaudeCodeHookEvent, D as ClaudeCodeHookHandler, E as ClaudeCodeHookMatcherGroup, F as ClaudeCodeHooksConfig, G as ClaudeCodeProviderOptions, H as CodexAgentOptions, I as CodexCommandHook, J as CodexHookEvent, K as CodexHookMatcherGroup, L as CodexHooksConfig, M as CodexProviderOptions, N as DataContent, O as EmbeddedSkillConfig, P as FilePart, Q as ImagePart, X as OpenCodeAgentOptions, Y as OpenCodePluginConfig, Z as OpenCodePluginEvent, _ as OpenCodePluginHookConfig, $ as OpenCodeProviderOptions, a4 as RepoSkillConfig, ab as TextPart, af as UserContent, ag as UserContentPart } from '../types-DmkbgYmn.js';
1
+ import { o as AgentProviderName, h as AgentOptions, t as AgentRunConfig, s as AgentRun, r as AgentResult, a2 as RawAgentEvent, b as AgentAttachRequest, y as AttachedRun, a9 as SetupLayout } from '../types-du-Kkn53.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, v as AgentSetupRequest, w as AgentSkillConfig, x as AgentSubAgentConfig, C as ClaudeCodeAgentOptions, z as ClaudeCodeHookConfig, B as ClaudeCodeHookEvent, D as ClaudeCodeHookHandler, E as ClaudeCodeHookMatcherGroup, F as ClaudeCodeHooksConfig, G as ClaudeCodeProviderOptions, H as CodexAgentOptions, I as CodexCommandHook, J as CodexHookEvent, K as CodexHookMatcherGroup, L as CodexHooksConfig, M as CodexProviderOptions, N as DataContent, O as EmbeddedSkillConfig, P as FilePart, Q as ImagePart, X as OpenCodeAgentOptions, Y as OpenCodePluginConfig, Z as OpenCodePluginEvent, _ as OpenCodePluginHookConfig, $ as OpenCodeProviderOptions, a4 as RepoSkillConfig, ab as TextPart, af as UserContent, ag as UserContentPart } from '../types-du-Kkn53.js';
3
3
  import { S as Sandbox } from '../Sandbox-DcKAU-E3.js';
4
4
  export { AgentProvider } from '../enums.js';
5
5
  import 'e2b';
@@ -2,8 +2,8 @@ import {
2
2
  Agent,
3
3
  agentboxRoot,
4
4
  getAgentLayout
5
- } from "../chunk-VBMMNUB7.js";
6
- import "../chunk-ZDSHOGJ4.js";
5
+ } from "../chunk-BNBEOIGX.js";
6
+ import "../chunk-764MJCER.js";
7
7
  import {
8
8
  AGENT_RESERVED_PORTS,
9
9
  collectAllAgentReservedPorts
@@ -291,11 +291,29 @@ var CodexLogAssembler = class {
291
291
  this.byItemId.set(itemId, next);
292
292
  return clone(next);
293
293
  }
294
+ getSnapshots() {
295
+ return Array.from(this.byItemId.values()).map(clone);
296
+ }
294
297
  };
295
298
  var OpenCodeLogAssembler = class {
296
299
  userMessageIds = /* @__PURE__ */ new Set();
297
300
  textByPartId = /* @__PURE__ */ new Map();
298
301
  byPartId = /* @__PURE__ */ new Map();
302
+ // Sub-agent (`task` tool) linkage. opencode multiplexes the parent task
303
+ // tool's `state.metadata.sessionId` update and the child session's first
304
+ // stream events onto the same SSE bus with no ordering guarantee, so
305
+ // child events frequently arrive before the parent has published its
306
+ // child sessionID. We bind FIFO instead: every task tool we see goes
307
+ // onto a queue; the first non-main sessionID that lacks an explicit
308
+ // binding gets paired with the queue head. Once a binding is established
309
+ // we stamp every emitted snapshot for that child session with
310
+ // `parentTaskCallId` on the part so consumers don't have to re-derive
311
+ // the linkage from snapshots.
312
+ mainSessionID = null;
313
+ pendingTaskCallIds = [];
314
+ childSessionToTaskCallId = /* @__PURE__ */ new Map();
315
+ childMessageIdToTaskCallId = /* @__PURE__ */ new Map();
316
+ messageIdToSessionId = /* @__PURE__ */ new Map();
299
317
  process(event) {
300
318
  if (!isRecord(event)) {
301
319
  return [];
@@ -303,10 +321,48 @@ var OpenCodeLogAssembler = class {
303
321
  const type = typeof event.type === "string" ? event.type : "";
304
322
  const properties = isRecord(event.properties) ? event.properties : {};
305
323
  const info = isRecord(properties.info) ? properties.info : null;
324
+ const eventPart = isRecord(properties.part) ? properties.part : isRecord(event.part) ? event.part : null;
325
+ if (this.mainSessionID === null) {
326
+ const candidate = (typeof info?.sessionID === "string" ? info.sessionID : null) ?? (eventPart && typeof eventPart.sessionID === "string" ? eventPart.sessionID : null) ?? (typeof properties.sessionID === "string" ? properties.sessionID : null);
327
+ if (candidate) this.mainSessionID = candidate;
328
+ }
329
+ if (info && typeof info.id === "string" && typeof info.sessionID === "string") {
330
+ this.messageIdToSessionId.set(info.id, info.sessionID);
331
+ }
332
+ if (eventPart && typeof eventPart.id === "string" && typeof eventPart.messageID === "string" && typeof eventPart.sessionID === "string") {
333
+ this.messageIdToSessionId.set(eventPart.messageID, eventPart.sessionID);
334
+ }
335
+ if (eventPart && this.isTaskToolPart(eventPart)) {
336
+ const callId = typeof eventPart.callID === "string" ? eventPart.callID : typeof eventPart.id === "string" ? eventPart.id : null;
337
+ if (callId) {
338
+ const metaSid = this.extractTaskMetadataSessionId(eventPart);
339
+ if (metaSid && !this.childSessionToTaskCallId.has(metaSid)) {
340
+ this.childSessionToTaskCallId.set(metaSid, callId);
341
+ this.pendingTaskCallIds = this.pendingTaskCallIds.filter(
342
+ (id) => id !== callId
343
+ );
344
+ } else if (!metaSid) {
345
+ const alreadyBound = this.taskCallIdAlreadyBound(callId);
346
+ if (!alreadyBound && !this.pendingTaskCallIds.includes(callId)) {
347
+ this.pendingTaskCallIds.push(callId);
348
+ }
349
+ }
350
+ }
351
+ }
352
+ const effectiveSid = this.extractSessionID(properties, eventPart, info);
353
+ if (effectiveSid && effectiveSid !== this.mainSessionID && !this.childSessionToTaskCallId.has(effectiveSid) && this.pendingTaskCallIds.length > 0) {
354
+ const taskCallId = this.pendingTaskCallIds.shift();
355
+ this.childSessionToTaskCallId.set(effectiveSid, taskCallId);
356
+ }
306
357
  if (type === "message.updated" && typeof info?.id === "string" && info.role === "user") {
307
358
  this.userMessageIds.add(info.id);
308
359
  return [clone(event)];
309
360
  }
361
+ const parentTaskCallId = this.resolveParentTaskCallId(
362
+ effectiveSid,
363
+ eventPart,
364
+ info
365
+ );
310
366
  if (type === "message.part.delta") {
311
367
  const partId = typeof properties.partID === "string" ? properties.partID : null;
312
368
  const messageId = typeof properties.messageID === "string" ? properties.messageID : null;
@@ -314,32 +370,50 @@ var OpenCodeLogAssembler = class {
314
370
  if (!partId || !delta || properties.field !== "text" || messageId && this.userMessageIds.has(messageId)) {
315
371
  return [];
316
372
  }
373
+ if (messageId && effectiveSid) {
374
+ this.messageIdToSessionId.set(messageId, effectiveSid);
375
+ }
317
376
  const text = (this.textByPartId.get(partId) ?? "") + delta;
318
377
  this.textByPartId.set(partId, text);
319
- return [
320
- this.upsertPart(partId, {
321
- id: partId,
322
- messageID: messageId ?? void 0,
323
- type: "text",
324
- text
325
- })
326
- ];
378
+ const part = {
379
+ id: partId,
380
+ messageID: messageId ?? void 0,
381
+ type: "text",
382
+ text
383
+ };
384
+ if (parentTaskCallId) {
385
+ part.parentTaskCallId = parentTaskCallId;
386
+ if (messageId) {
387
+ this.childMessageIdToTaskCallId.set(messageId, parentTaskCallId);
388
+ }
389
+ }
390
+ return [this.upsertPart(partId, part)];
327
391
  }
328
- const part = isRecord(properties.part) ? properties.part : isRecord(event.part) ? event.part : null;
329
- if (part && typeof part.id === "string") {
330
- if (part.messageID && this.userMessageIds.has(String(part.messageID))) {
392
+ if (eventPart && typeof eventPart.id === "string") {
393
+ if (eventPart.messageID && this.userMessageIds.has(String(eventPart.messageID))) {
331
394
  return [];
332
395
  }
333
- const previous = this.byPartId.get(part.id);
334
- if (part.type === "text" && previous && isRecord(previous.properties?.part)) {
396
+ const previous = this.byPartId.get(eventPart.id);
397
+ if (eventPart.type === "text" && previous && isRecord(previous.properties?.part)) {
335
398
  const previousPart = previous.properties.part;
336
399
  const previousText = typeof previousPart.text === "string" ? previousPart.text : "";
337
- const nextText = typeof part.text === "string" ? part.text : "";
400
+ const nextText = typeof eventPart.text === "string" ? eventPart.text : "";
338
401
  if (nextText.length < previousText.length) {
339
402
  return [clone(previous)];
340
403
  }
341
404
  }
342
- this.byPartId.set(part.id, clone(event));
405
+ const enriched = clone(event);
406
+ if (parentTaskCallId) {
407
+ this.stampParentTaskCallId(enriched, parentTaskCallId);
408
+ if (typeof eventPart.messageID === "string") {
409
+ this.childMessageIdToTaskCallId.set(
410
+ eventPart.messageID,
411
+ parentTaskCallId
412
+ );
413
+ }
414
+ }
415
+ this.byPartId.set(eventPart.id, enriched);
416
+ return [clone(enriched)];
343
417
  }
344
418
  return [clone(event)];
345
419
  }
@@ -347,11 +421,23 @@ var OpenCodeLogAssembler = class {
347
421
  this.userMessageIds.clear();
348
422
  this.textByPartId.clear();
349
423
  this.byPartId.clear();
424
+ this.mainSessionID = null;
425
+ this.pendingTaskCallIds = [];
426
+ this.childSessionToTaskCallId.clear();
427
+ this.childMessageIdToTaskCallId.clear();
428
+ this.messageIdToSessionId.clear();
350
429
  for (const snapshot of snapshots) {
351
430
  if (!isRecord(snapshot)) continue;
352
431
  const type = typeof snapshot.type === "string" ? snapshot.type : "";
353
432
  const properties = isRecord(snapshot.properties) ? snapshot.properties : {};
354
433
  const info = isRecord(properties.info) ? properties.info : null;
434
+ if (this.mainSessionID === null) {
435
+ const candidate = (typeof info?.sessionID === "string" ? info.sessionID : null) ?? (typeof properties.sessionID === "string" ? properties.sessionID : null);
436
+ if (candidate) this.mainSessionID = candidate;
437
+ }
438
+ if (info && typeof info.id === "string" && typeof info.sessionID === "string") {
439
+ this.messageIdToSessionId.set(info.id, info.sessionID);
440
+ }
355
441
  if (type === "message.updated" && typeof info?.id === "string" && info.role === "user") {
356
442
  this.userMessageIds.add(info.id);
357
443
  continue;
@@ -362,9 +448,88 @@ var OpenCodeLogAssembler = class {
362
448
  if (typeof part.text === "string") {
363
449
  this.textByPartId.set(part.id, part.text);
364
450
  }
451
+ if (typeof part.messageID === "string" && typeof part.sessionID === "string") {
452
+ this.messageIdToSessionId.set(part.messageID, part.sessionID);
453
+ }
454
+ if (typeof part.parentTaskCallId === "string") {
455
+ if (typeof part.sessionID === "string" && !this.childSessionToTaskCallId.has(part.sessionID)) {
456
+ this.childSessionToTaskCallId.set(
457
+ part.sessionID,
458
+ part.parentTaskCallId
459
+ );
460
+ }
461
+ if (typeof part.messageID === "string") {
462
+ this.childMessageIdToTaskCallId.set(
463
+ part.messageID,
464
+ part.parentTaskCallId
465
+ );
466
+ }
467
+ }
468
+ if (this.isTaskToolPart(part)) {
469
+ const callId = typeof part.callID === "string" ? part.callID : typeof part.id === "string" ? part.id : null;
470
+ const metaSid = this.extractTaskMetadataSessionId(part);
471
+ if (callId && metaSid && !this.childSessionToTaskCallId.has(metaSid)) {
472
+ this.childSessionToTaskCallId.set(metaSid, callId);
473
+ }
474
+ }
365
475
  }
366
476
  }
367
477
  }
478
+ isTaskToolPart(part) {
479
+ if (part.type !== "tool") return false;
480
+ const tool = typeof part.tool === "string" ? part.tool.toLowerCase() : "";
481
+ return tool === "task";
482
+ }
483
+ taskCallIdAlreadyBound(callId) {
484
+ for (const v of this.childSessionToTaskCallId.values()) {
485
+ if (v === callId) return true;
486
+ }
487
+ return false;
488
+ }
489
+ extractTaskMetadataSessionId(part) {
490
+ const state = isRecord(part.state) ? part.state : null;
491
+ const metadata = state && isRecord(state.metadata) ? state.metadata : null;
492
+ if (!metadata) return null;
493
+ if (typeof metadata.sessionId === "string") return metadata.sessionId;
494
+ if (typeof metadata.sessionID === "string") return metadata.sessionID;
495
+ return null;
496
+ }
497
+ extractSessionID(properties, part, info) {
498
+ if (typeof properties.sessionID === "string") return properties.sessionID;
499
+ if (part && typeof part.sessionID === "string") return part.sessionID;
500
+ if (info && typeof info.sessionID === "string") return info.sessionID;
501
+ return null;
502
+ }
503
+ resolveParentTaskCallId(sessionID, part, info) {
504
+ if (sessionID && this.childSessionToTaskCallId.has(sessionID)) {
505
+ return this.childSessionToTaskCallId.get(sessionID) ?? null;
506
+ }
507
+ const candidateMessageIds = [];
508
+ if (part && typeof part.messageID === "string") {
509
+ candidateMessageIds.push(part.messageID);
510
+ }
511
+ if (info && typeof info.id === "string") {
512
+ candidateMessageIds.push(info.id);
513
+ }
514
+ for (const messageId of candidateMessageIds) {
515
+ const cached = this.childMessageIdToTaskCallId.get(messageId);
516
+ if (cached) return cached;
517
+ const mappedSid = this.messageIdToSessionId.get(messageId);
518
+ if (mappedSid && this.childSessionToTaskCallId.has(mappedSid)) {
519
+ const tcid = this.childSessionToTaskCallId.get(mappedSid);
520
+ this.childMessageIdToTaskCallId.set(messageId, tcid);
521
+ return tcid;
522
+ }
523
+ }
524
+ return null;
525
+ }
526
+ stampParentTaskCallId(snapshot, parentTaskCallId) {
527
+ const properties = isRecord(snapshot.properties) ? snapshot.properties : null;
528
+ const part = properties && isRecord(properties.part) ? properties.part : isRecord(snapshot.part) ? snapshot.part : null;
529
+ if (part) {
530
+ part.parentTaskCallId = parentTaskCallId;
531
+ }
532
+ }
368
533
  upsertPart(partId, part) {
369
534
  const next = {
370
535
  type: "message.part.updated",
@@ -376,12 +541,22 @@ var OpenCodeLogAssembler = class {
376
541
  this.byPartId.set(partId, next);
377
542
  return clone(next);
378
543
  }
544
+ getSnapshots() {
545
+ return Array.from(this.byPartId.values()).map(clone);
546
+ }
379
547
  };
380
548
  var ClaudeCodeLogAssembler = class {
381
549
  currentMessageId = null;
382
550
  textByMessageId = /* @__PURE__ */ new Map();
383
551
  thinkingByMessageId = /* @__PURE__ */ new Map();
384
552
  byMessageId = /* @__PURE__ */ new Map();
553
+ // Per-message tool_use / image / other non-text-non-thinking content blocks.
554
+ // Tracked persistently so any `upsertMessage` call (including those from a
555
+ // post-assistant `message_start` re-anchor) still renders them — otherwise
556
+ // a later stream_event for the same messageId would emit a snapshot without
557
+ // tool_use blocks, and the UI's dedup-by-messageId would wipe the running
558
+ // command from the trace.
559
+ extraBlocksByMessageId = /* @__PURE__ */ new Map();
385
560
  process(event) {
386
561
  if (!isRecord(event)) return [];
387
562
  const type = typeof event.type === "string" ? event.type : "";
@@ -429,7 +604,8 @@ var ClaudeCodeLogAssembler = class {
429
604
  if (final.thinking) {
430
605
  this.thinkingByMessageId.set(id, final.thinking);
431
606
  }
432
- const snapshot = this.upsertMessage(id, final.extraBlocks);
607
+ this.mergeExtraBlocks(id, final.extraBlocks);
608
+ const snapshot = this.upsertMessage(id);
433
609
  this.currentMessageId = null;
434
610
  return [snapshot];
435
611
  }
@@ -440,6 +616,7 @@ var ClaudeCodeLogAssembler = class {
440
616
  this.textByMessageId.clear();
441
617
  this.thinkingByMessageId.clear();
442
618
  this.byMessageId.clear();
619
+ this.extraBlocksByMessageId.clear();
443
620
  for (const snapshot of snapshots) {
444
621
  if (!isRecord(snapshot)) continue;
445
622
  if (snapshot.type !== "message.updated") continue;
@@ -450,25 +627,46 @@ var ClaudeCodeLogAssembler = class {
450
627
  const content = message && Array.isArray(message.content) ? message.content : [];
451
628
  let text = "";
452
629
  let thinking = "";
630
+ const extraBlocks = [];
453
631
  for (const block of content) {
454
632
  if (!isRecord(block)) continue;
455
633
  if (block.type === "text" && typeof block.text === "string") {
456
634
  text += block.text;
457
635
  } else if (block.type === "thinking" && typeof block.thinking === "string") {
458
636
  thinking += block.thinking;
637
+ } else {
638
+ extraBlocks.push(block);
459
639
  }
460
640
  }
461
641
  this.textByMessageId.set(messageId, text);
462
642
  this.thinkingByMessageId.set(messageId, thinking);
643
+ if (extraBlocks.length > 0) {
644
+ this.mergeExtraBlocks(messageId, extraBlocks);
645
+ }
646
+ }
647
+ }
648
+ mergeExtraBlocks(messageId, blocks) {
649
+ if (blocks.length === 0) return;
650
+ let map = this.extraBlocksByMessageId.get(messageId);
651
+ if (!map) {
652
+ map = /* @__PURE__ */ new Map();
653
+ this.extraBlocksByMessageId.set(messageId, map);
654
+ }
655
+ for (const block of blocks) {
656
+ const key = typeof block.id === "string" && block.id ? `id:${block.id}` : `idx:${map.size}`;
657
+ map.set(key, clone(block));
463
658
  }
464
659
  }
465
- upsertMessage(messageId, extraBlocks = []) {
660
+ upsertMessage(messageId) {
466
661
  const text = this.textByMessageId.get(messageId) ?? "";
467
662
  const thinking = this.thinkingByMessageId.get(messageId) ?? "";
468
663
  const content = [];
469
664
  if (thinking) content.push({ type: "thinking", thinking });
470
665
  if (text) content.push({ type: "text", text });
471
- for (const block of extraBlocks) content.push(clone(block));
666
+ const extras = this.extraBlocksByMessageId.get(messageId);
667
+ if (extras) {
668
+ for (const block of extras.values()) content.push(clone(block));
669
+ }
472
670
  const next = {
473
671
  type: "message.updated",
474
672
  messageId,
@@ -481,6 +679,9 @@ var ClaudeCodeLogAssembler = class {
481
679
  this.byMessageId.set(messageId, next);
482
680
  return clone(next);
483
681
  }
682
+ getSnapshots() {
683
+ return Array.from(this.byMessageId.values()).map(clone);
684
+ }
484
685
  };
485
686
  function extractClaudeAssistantContent(message) {
486
687
  const content = Array.isArray(message.content) ? message.content : [];
@@ -523,6 +724,29 @@ var ProviderLogAssembler = class {
523
724
  }
524
725
  return [];
525
726
  }
727
+ /**
728
+ * Return the current deduped snapshot set held by the active per-provider
729
+ * assembler. Equivalent to running `dedupeSnapshots` over the full sequence
730
+ * of snapshots emitted by `process()` since construction (or last seed), but
731
+ * read directly from in-memory state — no transport or persistence layer
732
+ * involved. Used end-of-run to persist the full trace without paying a
733
+ * Redis LRANGE + parse roundtrip.
734
+ *
735
+ * Snapshots are returned in first-seen order (Map insertion order). Entries
736
+ * are cloned, so the caller can serialize them freely.
737
+ */
738
+ getSnapshots(provider) {
739
+ if (provider === AgentProvider.Codex || provider === "codex") {
740
+ return this.codex.getSnapshots();
741
+ }
742
+ if (provider === AgentProvider.OpenCode || provider === "opencode") {
743
+ return this.openCode.getSnapshots();
744
+ }
745
+ if (provider === AgentProvider.ClaudeCode || provider === "claude-code") {
746
+ return this.claudeCode.getSnapshots();
747
+ }
748
+ return [];
749
+ }
526
750
  /**
527
751
  * Re-seed the assembler from a sequence of previously-assembled snapshots
528
752
  * so that subsequent `process()` calls produce snapshots consistent with
@@ -2,7 +2,7 @@ import {
2
2
  createNormalizedEvent,
3
3
  normalizeRawAgentEvent,
4
4
  toAISDKStream
5
- } from "./chunk-ZDSHOGJ4.js";
5
+ } from "./chunk-764MJCER.js";
6
6
  import {
7
7
  AgentBoxError,
8
8
  AsyncQueue,
@@ -1662,6 +1662,7 @@ function buildClaudeQueryOptions(params) {
1662
1662
  if (run.systemPrompt) {
1663
1663
  extraArgs["append-system-prompt"] = run.systemPrompt;
1664
1664
  }
1665
+ const includeHookEvents = provider?.includeHookEvents ?? false;
1665
1666
  return {
1666
1667
  cwd: params.cwd ?? params.request.options.cwd,
1667
1668
  env: params.env,
@@ -1669,7 +1670,9 @@ function buildClaudeQueryOptions(params) {
1669
1670
  settings: params.settingsPath,
1670
1671
  extraArgs,
1671
1672
  includePartialMessages: true,
1673
+ includeHookEvents,
1672
1674
  thinking: { type: "adaptive", display: "summarized" },
1675
+ ...provider?.additionalDirectories?.length ? { additionalDirectories: provider.additionalDirectories } : {},
1673
1676
  ...run.model ? { model: run.model } : {},
1674
1677
  ...run.reasoning ? { effort: run.reasoning } : {},
1675
1678
  ...provider?.permissionMode ? { permissionMode: provider.permissionMode } : {},
@@ -2355,12 +2358,33 @@ var ClaudeCodeAgentAdapter = class {
2355
2358
  rawPayloads.push(message);
2356
2359
  sink.emitRaw(toRawEvent(request.runId, message, message.type));
2357
2360
  if (message.type === "system") {
2358
- const sys = message;
2359
- if (sys.subtype === "init" && sys.session_id) {
2361
+ const sub = message.subtype;
2362
+ if (sub === "init") {
2363
+ const sys = message;
2364
+ if (sys.session_id) {
2365
+ debugClaude(
2366
+ "\u2605 session.init session_id=%s (%dms)",
2367
+ sys.session_id.slice(0, 8),
2368
+ Date.now() - executeStartedAt
2369
+ );
2370
+ }
2371
+ } else if (sub === "hook_started") {
2372
+ const h = message;
2360
2373
  debugClaude(
2361
- "\u2605 session.init session_id=%s (%dms)",
2362
- sys.session_id.slice(0, 8),
2363
- Date.now() - executeStartedAt
2374
+ "hook.started name=%s event=%s hook_id=%s",
2375
+ h.hook_name,
2376
+ h.hook_event,
2377
+ h.hook_id
2378
+ );
2379
+ } else if (sub === "hook_response") {
2380
+ const h = message;
2381
+ const stderr = h.stderr && h.stderr.length > 0 ? h.stderr.replace(/\s+$/, "") : void 0;
2382
+ debugClaude(
2383
+ "hook.response name=%s exit=%s outcome=%s%s",
2384
+ h.hook_name,
2385
+ h.exit_code,
2386
+ h.outcome,
2387
+ stderr ? ` stderr=${JSON.stringify(stderr).slice(0, 200)}` : ""
2364
2388
  );
2365
2389
  }
2366
2390
  continue;
@@ -1,4 +1,4 @@
1
- export { A as AISDKEvent, R as MessageCompletedEvent, S as MessageInjectedEvent, T as MessageStartedEvent, U as NormalizedAgentEvent, V as NormalizedAgentEventBase, W as NormalizedAgentEventType, a0 as PermissionRequestedEvent, a1 as PermissionResolvedEvent, a2 as RawAgentEvent, a3 as ReasoningDeltaEvent, a5 as RunCancelledEvent, a6 as RunCompletedEvent, a7 as RunErrorEvent, a8 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-DmkbgYmn.js';
1
+ export { A as AISDKEvent, R as MessageCompletedEvent, S as MessageInjectedEvent, T as MessageStartedEvent, U as NormalizedAgentEvent, V as NormalizedAgentEventBase, W as NormalizedAgentEventType, a0 as PermissionRequestedEvent, a1 as PermissionResolvedEvent, a2 as RawAgentEvent, a3 as ReasoningDeltaEvent, a5 as RunCancelledEvent, a6 as RunCompletedEvent, a7 as RunErrorEvent, a8 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-du-Kkn53.js';
2
2
  import { AgentProvider } from '../enums.js';
3
3
  import '../Sandbox-DcKAU-E3.js';
4
4
  import 'e2b';
@@ -69,6 +69,18 @@ declare class ProviderLogAssembler {
69
69
  * a delta with no payload) or already represented by a previous snapshot.
70
70
  */
71
71
  process(provider: AgentProvider | string | null | undefined, event: unknown): JsonRecord[];
72
+ /**
73
+ * Return the current deduped snapshot set held by the active per-provider
74
+ * assembler. Equivalent to running `dedupeSnapshots` over the full sequence
75
+ * of snapshots emitted by `process()` since construction (or last seed), but
76
+ * read directly from in-memory state — no transport or persistence layer
77
+ * involved. Used end-of-run to persist the full trace without paying a
78
+ * Redis LRANGE + parse roundtrip.
79
+ *
80
+ * Snapshots are returned in first-seen order (Map insertion order). Entries
81
+ * are cloned, so the caller can serialize them freely.
82
+ */
83
+ getSnapshots(provider: AgentProvider | string | null | undefined): JsonRecord[];
72
84
  /**
73
85
  * Re-seed the assembler from a sequence of previously-assembled snapshots
74
86
  * so that subsequent `process()` calls produce snapshots consistent with
@@ -4,7 +4,7 @@ import {
4
4
  normalizeRawAgentEvent,
5
5
  toAISDKEvent,
6
6
  toAISDKStream
7
- } from "../chunk-ZDSHOGJ4.js";
7
+ } from "../chunk-764MJCER.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 AgentSetupRequest, w as AgentSkillConfig, x as AgentSubAgentConfig, y as AttachedRun, C as ClaudeCodeAgentOptions, z as ClaudeCodeHookConfig, B as ClaudeCodeHookEvent, D as ClaudeCodeHookHandler, E as ClaudeCodeHookMatcherGroup, F as ClaudeCodeHooksConfig, G as ClaudeCodeProviderOptions, H as CodexAgentOptions, I as CodexCommandHook, J as CodexHookEvent, K as CodexHookMatcherGroup, L as CodexHooksConfig, M as CodexProviderOptions, N as DataContent, O as EmbeddedSkillConfig, P as FilePart, Q as ImagePart, R as MessageCompletedEvent, S as MessageInjectedEvent, T as MessageStartedEvent, U as NormalizedAgentEvent, V as NormalizedAgentEventBase, W as NormalizedAgentEventType, X as OpenCodeAgentOptions, Y as OpenCodePluginConfig, Z as OpenCodePluginEvent, _ as OpenCodePluginHookConfig, $ as OpenCodeProviderOptions, a0 as PermissionRequestedEvent, a1 as PermissionResolvedEvent, a2 as RawAgentEvent, a3 as ReasoningDeltaEvent, a4 as RepoSkillConfig, a5 as RunCancelledEvent, a6 as RunCompletedEvent, a7 as RunErrorEvent, a8 as RunStartedEvent, a9 as SetupLayout, 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-DmkbgYmn.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 AgentSetupRequest, w as AgentSkillConfig, x as AgentSubAgentConfig, y as AttachedRun, C as ClaudeCodeAgentOptions, z as ClaudeCodeHookConfig, B as ClaudeCodeHookEvent, D as ClaudeCodeHookHandler, E as ClaudeCodeHookMatcherGroup, F as ClaudeCodeHooksConfig, G as ClaudeCodeProviderOptions, H as CodexAgentOptions, I as CodexCommandHook, J as CodexHookEvent, K as CodexHookMatcherGroup, L as CodexHooksConfig, M as CodexProviderOptions, N as DataContent, O as EmbeddedSkillConfig, P as FilePart, Q as ImagePart, R as MessageCompletedEvent, S as MessageInjectedEvent, T as MessageStartedEvent, U as NormalizedAgentEvent, V as NormalizedAgentEventBase, W as NormalizedAgentEventType, X as OpenCodeAgentOptions, Y as OpenCodePluginConfig, Z as OpenCodePluginEvent, _ as OpenCodePluginHookConfig, $ as OpenCodeProviderOptions, a0 as PermissionRequestedEvent, a1 as PermissionResolvedEvent, a2 as RawAgentEvent, a3 as ReasoningDeltaEvent, a4 as RepoSkillConfig, a5 as RunCancelledEvent, a6 as RunCompletedEvent, a7 as RunErrorEvent, a8 as RunStartedEvent, a9 as SetupLayout, 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-du-Kkn53.js';
2
2
  export { AGENT_RESERVED_PORTS, Agent, agentboxRoot, collectAllAgentReservedPorts, getAgentLayout } 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-DcKAU-E3.js';
4
4
  export { SandboxAdapter, buildGitCloneCommand } from './sandboxes/index.js';
package/dist/index.js CHANGED
@@ -2,14 +2,14 @@ import {
2
2
  Agent,
3
3
  agentboxRoot,
4
4
  getAgentLayout
5
- } from "./chunk-VBMMNUB7.js";
5
+ } from "./chunk-BNBEOIGX.js";
6
6
  import {
7
7
  ProviderLogAssembler,
8
8
  createNormalizedEvent,
9
9
  normalizeRawAgentEvent,
10
10
  toAISDKEvent,
11
11
  toAISDKStream
12
- } from "./chunk-ZDSHOGJ4.js";
12
+ } from "./chunk-764MJCER.js";
13
13
  import {
14
14
  Sandbox,
15
15
  SandboxAdapter,
@@ -401,6 +401,23 @@ interface ClaudeCodeProviderOptions {
401
401
  allowedTools?: string[];
402
402
  autoApproveTools?: boolean;
403
403
  verbose?: boolean;
404
+ /**
405
+ * Extra directories Claude Code is allowed to read/write outside `cwd`.
406
+ * Passed through to `--add-dir` (one flag per entry). Use absolute paths.
407
+ *
408
+ * Common case: cwd points at a parent directory and tasks need access
409
+ * to sibling repos cloned under it. Listing each repo here surfaces it
410
+ * to the agent without changing the working directory.
411
+ */
412
+ additionalDirectories?: string[];
413
+ /**
414
+ * When `true` (the default), the in-sandbox CLI emits `hook_started` and
415
+ * `hook_response` system messages so the host can observe every hook
416
+ * fire — useful to confirm a project-defined hook actually ran and to
417
+ * surface its stdout/stderr/exit_code on failures. Set `false` to
418
+ * silence them when hook noise drowns out the rest of the event stream.
419
+ */
420
+ includeHookEvents?: boolean;
404
421
  }
405
422
  interface CodexAgentOptions extends AgentOptionsBase {
406
423
  provider?: CodexProviderOptions;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentbox-sdk",
3
- "version": "0.1.309",
3
+ "version": "0.1.311",
4
4
  "description": "Swappable coding agents and sandbox providers for Bun and TypeScript.",
5
5
  "license": "MIT",
6
6
  "repository": {