@band-ai/sdk 0.2.1 → 0.3.1

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 (37) hide show
  1. package/dist/{ClaudeSDKAdapter-Cna5P1dR.d.ts → ClaudeSDKAdapter-CXud2DBE.d.ts} +2 -1
  2. package/dist/{ClaudeSDKAdapter-BY4zEbCl.d.cts → ClaudeSDKAdapter-Cx6zhSaG.d.cts} +2 -1
  3. package/dist/adapters.cjs +246 -116
  4. package/dist/adapters.d.cts +14 -3
  5. package/dist/adapters.d.ts +14 -3
  6. package/dist/adapters.js +143 -44
  7. package/dist/chunk-F63TPOI3.js +29 -0
  8. package/dist/{chunk-3BKAC4OZ.js → chunk-JADCAMZY.js} +8 -0
  9. package/dist/{chunk-N2QTUMGO.js → chunk-JJF44XWA.js} +365 -249
  10. package/dist/{chunk-TLBCKDQO.js → chunk-K5KAEYPF.js} +2 -2
  11. package/dist/{chunk-ZZJRRBPQ.js → chunk-KXJ74J73.js} +1 -1
  12. package/dist/{chunk-NMZLX7TP.js → chunk-MQBBWYRP.js} +52 -45
  13. package/dist/{chunk-RV76SKFT.js → chunk-MQY74R7D.js} +2 -20
  14. package/dist/{chunk-LBWKISBS.js → chunk-OH6VVVKT.js} +21 -0
  15. package/dist/{chunk-EAI2M3WM.js → chunk-W5IAI6Z4.js} +1 -1
  16. package/dist/{chunk-4IAXZBXX.js → chunk-WA7CHXUS.js} +2 -2
  17. package/dist/{chunk-NT7TBFX2.js → chunk-XWHWJP4I.js} +2 -2
  18. package/dist/{chunk-WLCM2OXG.js → chunk-YJ42AZO4.js} +1 -1
  19. package/dist/converters.js +6 -5
  20. package/dist/index.cjs +405 -277
  21. package/dist/index.d.cts +5 -5
  22. package/dist/index.d.ts +5 -5
  23. package/dist/index.js +12 -11
  24. package/dist/mcp-claude.js +4 -3
  25. package/dist/mcp.js +5 -4
  26. package/dist/rest.js +3 -3
  27. package/dist/runtime.cjs +387 -362
  28. package/dist/runtime.d.cts +10 -39
  29. package/dist/runtime.d.ts +10 -39
  30. package/dist/runtime.js +20 -142
  31. package/dist/{schemas-BotL3ZLH.d.cts → schemas-BgJhlqqO.d.cts} +57 -13
  32. package/dist/{schemas-DBsC4J1g.d.ts → schemas-C4mK1WSs.d.ts} +57 -13
  33. package/dist/testing.cjs +11 -0
  34. package/dist/testing.js +8 -1
  35. package/dist/{types-D958TC71.d.cts → types-BNNtOXu3.d.cts} +1 -1
  36. package/dist/{types-BTN_ZETM.d.ts → types-DFUtpxah.d.ts} +1 -1
  37. package/package.json +2 -2
@@ -1,4 +1,4 @@
1
- export { A as A2AAdapter, a as A2AAdapterOptions, K as A2AClientFactory, M as A2AClientLike, b as A2AGatewayAdapter, c as AnthropicAdapter, d as AnthropicAdapterOptions, N as AnthropicClientFactory, Q as AnthropicToolCallingModel, R as AnthropicToolCallingModelOptions, C as CODEX_REASONING_EFFORTS, e as CODEX_REASONING_SUMMARIES, f as CODEX_WEB_SEARCH_MODES, g as ClaudePermissionMode, h as ClaudeSDKAdapter, i as ClaudeSDKAdapterOptions, S as ClaudeSDKQuery, U as ClaudeSDKQueryParams, j as CodexAdapter, k as CodexAdapterConfig, W as CodexAppServerStdioClient, l as CodexApprovalPolicy, X as CodexClientLike, Y as CodexJsonRpcError, m as CodexReasoningEffort, n as CodexReasoningSummary, o as CodexSandboxMode, p as CodexWebSearchMode, Z as DynamicToolCallParams, _ as DynamicToolCallResponse, $ as DynamicToolSpec, G as GeminiAdapter, q as GeminiAdapterOptions, a0 as GeminiClientFactory, a1 as GeminiToolCallingModel, a2 as GeminiToolCallingModelOptions, r as GenericAdapter, s as GenericAdapterHandler, t as GoogleADKAdapter, u as GoogleADKAdapterOptions, a3 as HttpOpencodeClient, a4 as HttpOpencodeClientOptions, a5 as HttpStatusError, L as LangGraphAdapter, v as LangGraphAdapterOptions, w as LangGraphGraph, x as LettaAdapter, y as LettaAdapterOptions, a6 as LettaAgentCreateParams, a7 as LettaClientFactory, a8 as LettaClientLike, a9 as LettaHistoryConverter, aa as LettaMessage, ab as LettaMessageCreateParams, ac as LettaMessages, ad as LettaRequestOptions, ae as LettaResponse, af as LettaResponseMessage, O as OpenAIAdapter, z as OpenAIAdapterOptions, ag as OpenAIClientFactory, ah as OpenAIToolCallingModel, ai as OpenAIToolCallingModelOptions, B as OpencodeAdapter, D as OpencodeAdapterConfig, E as OpencodeApprovalMode, F as OpencodeApprovalReply, aj as OpencodeClientLike, H as OpencodeQuestionMode, P as ParlantAdapter, I as ParlantAdapterOptions, ak as ParlantClientFactory, al as ParlantClientLike, am as ToolCall, an as ToolCallingAdapter, ao as ToolCallingAdapterOptions, T as ToolCallingModel, ap as ToolCallingModelRequest, aq as ToolCallingResponse, ar as ToolResult, as as TurnStartParams, V as VercelAISDKAdapter, J as VercelAISDKAdapterOptions, at as VercelAISDKToolCallingModel, au as VercelAISDKToolCallingModelOptions, av as runSingleToolRound } from './ClaudeSDKAdapter-Cna5P1dR.js';
1
+ export { A as A2AAdapter, a as A2AAdapterOptions, K as A2AClientFactory, M as A2AClientLike, b as A2AGatewayAdapter, c as AnthropicAdapter, d as AnthropicAdapterOptions, N as AnthropicClientFactory, Q as AnthropicToolCallingModel, R as AnthropicToolCallingModelOptions, C as CODEX_REASONING_EFFORTS, e as CODEX_REASONING_SUMMARIES, f as CODEX_WEB_SEARCH_MODES, g as ClaudePermissionMode, h as ClaudeSDKAdapter, i as ClaudeSDKAdapterOptions, S as ClaudeSDKQuery, U as ClaudeSDKQueryParams, j as CodexAdapter, k as CodexAdapterConfig, W as CodexAppServerStdioClient, l as CodexApprovalPolicy, X as CodexClientLike, Y as CodexJsonRpcError, m as CodexReasoningEffort, n as CodexReasoningSummary, o as CodexSandboxMode, p as CodexWebSearchMode, Z as DynamicToolCallParams, _ as DynamicToolCallResponse, $ as DynamicToolSpec, G as GeminiAdapter, q as GeminiAdapterOptions, a0 as GeminiClientFactory, a1 as GeminiToolCallingModel, a2 as GeminiToolCallingModelOptions, r as GenericAdapter, s as GenericAdapterHandler, t as GoogleADKAdapter, u as GoogleADKAdapterOptions, a3 as HttpOpencodeClient, a4 as HttpOpencodeClientOptions, a5 as HttpStatusError, L as LangGraphAdapter, v as LangGraphAdapterOptions, w as LangGraphGraph, x as LettaAdapter, y as LettaAdapterOptions, a6 as LettaAgentCreateParams, a7 as LettaClientFactory, a8 as LettaClientLike, a9 as LettaHistoryConverter, aa as LettaMessage, ab as LettaMessageCreateParams, ac as LettaMessages, ad as LettaRequestOptions, ae as LettaResponse, af as LettaResponseMessage, O as OpenAIAdapter, z as OpenAIAdapterOptions, ag as OpenAIClientFactory, ah as OpenAIToolCallingModel, ai as OpenAIToolCallingModelOptions, B as OpencodeAdapter, D as OpencodeAdapterConfig, E as OpencodeApprovalMode, F as OpencodeApprovalReply, aj as OpencodeClientLike, H as OpencodeQuestionMode, P as ParlantAdapter, I as ParlantAdapterOptions, ak as ParlantClientFactory, al as ParlantClientLike, am as ToolCall, an as ToolCallingAdapter, ao as ToolCallingAdapterOptions, T as ToolCallingModel, ap as ToolCallingModelRequest, aq as ToolCallingResponse, ar as ToolResult, as as TurnStartParams, V as VercelAISDKAdapter, J as VercelAISDKAdapterOptions, at as VercelAISDKToolCallingModel, au as VercelAISDKToolCallingModelOptions, av as runSingleToolRound } from './ClaudeSDKAdapter-CXud2DBE.js';
2
2
  import * as _agentclientprotocol_sdk from '@agentclientprotocol/sdk';
3
3
  import { Client, ClientSideConnection, McpServer, ClientCapabilities, RequestPermissionRequest, SessionMode, AgentSideConnection, SessionModeState, Agent, InitializeResponse, Implementation, Stream, InitializeRequest, LoadSessionRequest, LoadSessionResponse, ListSessionsRequest, ListSessionsResponse, ForkSessionRequest, ForkSessionResponse, ResumeSessionRequest, ResumeSessionResponse, SetSessionModeRequest, SetSessionModeResponse, SetSessionModelRequest, SetSessionModelResponse, SetSessionConfigOptionRequest, SetSessionConfigOptionResponse, AuthenticateRequest, AuthenticateResponse, PromptRequest, PromptResponse } from '@agentclientprotocol/sdk';
4
4
  import { A as ACPClientSessionState, a as ACPServerSessionState } from './acp-server-CiUqN3G3.js';
@@ -6,7 +6,7 @@ export { G as GatewayHistoryConverter } from './acp-server-CiUqN3G3.js';
6
6
  import { S as SimpleAdapter } from './simpleAdapter--wznuoOw.js';
7
7
  import { L as Logger } from './logger-CABQOnlR.js';
8
8
  import { A as AdapterToolsProtocol, c as MessagingTools } from './protocols-Bwwcql0h.js';
9
- import { P as PlatformMessage } from './types-BTN_ZETM.js';
9
+ import { P as PlatformMessage } from './types-DFUtpxah.js';
10
10
  import { M as McpToolRegistration } from './sdk-qKJtMma_.js';
11
11
  import { R as RestApi } from './types-BivGO7I9.js';
12
12
  import { b as GatewayServerLike, c as GatewayServerOptions } from './opencode-Bld62x5t.js';
@@ -41,6 +41,12 @@ type ACPClientConnectionFactory = (client: Client, options: {
41
41
  env?: Record<string, string>;
42
42
  }) => Promise<ACPClientConnectionHandle>;
43
43
 
44
+ interface ACPModeRequest {
45
+ roomId: string;
46
+ sessionId: string;
47
+ currentModeId: string;
48
+ modes: readonly SessionMode[];
49
+ }
44
50
  interface ACPClientAdapterOptions {
45
51
  command: string | string[];
46
52
  cwd?: string;
@@ -54,6 +60,7 @@ interface ACPClientAdapterOptions {
54
60
  connectionFactory?: ACPClientConnectionFactory;
55
61
  resolvePermission?: (request: RequestPermissionRequest, signal: AbortSignal) => Promise<string | undefined>;
56
62
  permissionTimeoutMs?: number;
63
+ resolveSessionMode?: (request: ACPModeRequest, signal: AbortSignal) => Promise<string | undefined>;
57
64
  logger?: Logger;
58
65
  }
59
66
  declare class ACPClientAdapter extends SimpleAdapter<ACPClientSessionState, AdapterToolsProtocol> {
@@ -73,6 +80,7 @@ declare class ACPClientAdapter extends SimpleAdapter<ACPClientSessionState, Adap
73
80
  private readonly bootstrappedSessions;
74
81
  private readonly pendingPermissions;
75
82
  private readonly resolvePermission?;
83
+ private readonly resolveSessionMode?;
76
84
  private readonly permissionTimeoutMs;
77
85
  private readonly logger;
78
86
  private backend;
@@ -86,7 +94,7 @@ declare class ACPClientAdapter extends SimpleAdapter<ACPClientSessionState, Adap
86
94
  private spawnPromise;
87
95
  constructor(options: ACPClientAdapterOptions);
88
96
  onStarted(agentName: string, agentDescription: string): Promise<void>;
89
- onMessage(message: PlatformMessage, tools: AdapterToolsProtocol, history: ACPClientSessionState, _participantsMessage: string | null, _contactsMessage: string | null, context: {
97
+ onMessage(message: PlatformMessage, tools: AdapterToolsProtocol, history: ACPClientSessionState, participantsMessage: string | null, contactsMessage: string | null, context: {
90
98
  isSessionBootstrap: boolean;
91
99
  roomId: string;
92
100
  }): Promise<void>;
@@ -97,6 +105,8 @@ declare class ACPClientAdapter extends SimpleAdapter<ACPClientSessionState, Adap
97
105
  private ensureConnection;
98
106
  private spawnConnection;
99
107
  private getOrCreateSession;
108
+ private configureSessionMode;
109
+ private resolveSessionModeManually;
100
110
  private tryRestoreSession;
101
111
  private buildSessionMcpServers;
102
112
  private getOrCreateBackend;
@@ -104,6 +114,7 @@ declare class ACPClientAdapter extends SimpleAdapter<ACPClientSessionState, Adap
104
114
  private buildSystemContext;
105
115
  private handlePermissionRequest;
106
116
  private toResponse;
117
+ private safeWarn;
107
118
  private resolveManually;
108
119
  private trackPending;
109
120
  private untrackPending;
package/dist/adapters.js CHANGED
@@ -23,14 +23,15 @@ import {
23
23
  ToolCallingAdapter,
24
24
  VercelAISDKAdapter,
25
25
  VercelAISDKToolCallingModel,
26
- runSingleToolRound
27
- } from "./chunk-NMZLX7TP.js";
26
+ runSingleToolRound,
27
+ systemUpdateParts
28
+ } from "./chunk-MQBBWYRP.js";
28
29
  import {
29
30
  BandMcpServer,
30
31
  BandMcpSseServer,
31
32
  generateAuthToken
32
- } from "./chunk-4IAXZBXX.js";
33
- import "./chunk-NT7TBFX2.js";
33
+ } from "./chunk-WA7CHXUS.js";
34
+ import "./chunk-XWHWJP4I.js";
34
35
  import {
35
36
  ACPClientHistoryConverter,
36
37
  ACPServerHistoryConverter
@@ -48,21 +49,26 @@ import {
48
49
  createGatewayServer,
49
50
  parseToolCall,
50
51
  parseToolResult
51
- } from "./chunk-TLBCKDQO.js";
52
+ } from "./chunk-K5KAEYPF.js";
52
53
  import {
53
54
  SimpleAdapter
54
55
  } from "./chunk-AVVDPXP4.js";
55
56
  import {
56
- ensureHandlePrefix
57
- } from "./chunk-LBWKISBS.js";
57
+ ensureHandlePrefix,
58
+ mentionSubjectsFromMetadata,
59
+ replaceUuidMentions
60
+ } from "./chunk-OH6VVVKT.js";
58
61
  import {
59
62
  renderSystemPrompt
60
- } from "./chunk-WLCM2OXG.js";
63
+ } from "./chunk-YJ42AZO4.js";
61
64
  import {
62
65
  MCP_SERVER_NAME
63
- } from "./chunk-RV76SKFT.js";
64
- import "./chunk-ZZJRRBPQ.js";
65
- import "./chunk-3BKAC4OZ.js";
66
+ } from "./chunk-MQY74R7D.js";
67
+ import {
68
+ isBlankEventContent
69
+ } from "./chunk-F63TPOI3.js";
70
+ import "./chunk-KXJ74J73.js";
71
+ import "./chunk-JADCAMZY.js";
66
72
  import {
67
73
  NoopLogger
68
74
  } from "./chunk-OD2G5LFQ.js";
@@ -75,6 +81,21 @@ import {
75
81
  import { spawn } from "child_process";
76
82
  import { Readable, Writable } from "stream";
77
83
 
84
+ // src/adapters/shared/withTimeout.ts
85
+ async function withTimeout(promise, timeoutMs, message) {
86
+ let timer;
87
+ try {
88
+ return await Promise.race([
89
+ promise,
90
+ new Promise((_, reject) => {
91
+ timer = setTimeout(() => reject(new Error(message)), timeoutMs);
92
+ })
93
+ ]);
94
+ } finally {
95
+ clearTimeout(timer);
96
+ }
97
+ }
98
+
78
99
  // src/adapters/acp/types.ts
79
100
  var DEFAULT_ACP_SERVER_MODES = [
80
101
  {
@@ -348,6 +369,7 @@ var acpModule = new LazyAsyncValue({
348
369
 
349
370
  // src/adapters/acp/ACPClientAdapter.ts
350
371
  var DEFAULT_PERMISSION_TIMEOUT_MS = 5 * 6e4;
372
+ var SET_SESSION_MODE_TIMEOUT_MS = 1e4;
351
373
  var ACPClientAdapter = class extends SimpleAdapter {
352
374
  command;
353
375
  cwd;
@@ -365,6 +387,7 @@ var ACPClientAdapter = class extends SimpleAdapter {
365
387
  bootstrappedSessions = /* @__PURE__ */ new Set();
366
388
  pendingPermissions = /* @__PURE__ */ new Map();
367
389
  resolvePermission;
390
+ resolveSessionMode;
368
391
  permissionTimeoutMs;
369
392
  logger;
370
393
  backend = null;
@@ -394,9 +417,10 @@ var ACPClientAdapter = class extends SimpleAdapter {
394
417
  this.clientCapabilities = options.clientCapabilities;
395
418
  this.connectionFactory = options.connectionFactory ?? createSubprocessConnection;
396
419
  this.resolvePermission = options.resolvePermission;
420
+ this.resolveSessionMode = options.resolveSessionMode;
397
421
  this.logger = options.logger ?? new NoopLogger();
398
422
  this.permissionTimeoutMs = options.permissionTimeoutMs ?? DEFAULT_PERMISSION_TIMEOUT_MS;
399
- if (this.resolvePermission && (!Number.isFinite(this.permissionTimeoutMs) || this.permissionTimeoutMs <= 0)) {
423
+ if ((this.resolvePermission || this.resolveSessionMode) && (!Number.isFinite(this.permissionTimeoutMs) || this.permissionTimeoutMs <= 0)) {
400
424
  throw new ValidationError(`permissionTimeoutMs must be a positive finite number, got ${options.permissionTimeoutMs}`);
401
425
  }
402
426
  }
@@ -410,7 +434,7 @@ var ACPClientAdapter = class extends SimpleAdapter {
410
434
  });
411
435
  await this.ensureConnection();
412
436
  }
413
- async onMessage(message, tools, history, _participantsMessage, _contactsMessage, context) {
437
+ async onMessage(message, tools, history, participantsMessage, contactsMessage, context) {
414
438
  if (context.isSessionBootstrap) {
415
439
  this.rehydrate(history);
416
440
  }
@@ -426,9 +450,11 @@ var ACPClientAdapter = class extends SimpleAdapter {
426
450
  sessionId,
427
451
  (params) => this.handlePermissionRequest(tools, context.roomId, params)
428
452
  );
429
- const promptText = this.bootstrappedSessions.has(sessionId) ? message.content : `${this.buildSystemContext(context.roomId, message)}
453
+ const content = replaceUuidMentions(message.content, mentionSubjectsFromMetadata(message.metadata));
454
+ const messageWithContext = [...systemUpdateParts(participantsMessage, contactsMessage), content].join("\n\n");
455
+ const promptText = this.bootstrappedSessions.has(sessionId) ? messageWithContext : `${this.buildSystemContext(context.roomId, message)}
430
456
 
431
- ${message.content}`;
457
+ ${messageWithContext}`;
432
458
  this.bootstrappedSessions.add(sessionId);
433
459
  try {
434
460
  await connection.prompt({
@@ -555,9 +581,10 @@ ${message.content}`;
555
581
  const mcpServers = await this.buildSessionMcpServers();
556
582
  if (existingSessionId) {
557
583
  const restored = await this.tryRestoreSession(connection, existingSessionId, mcpServers);
558
- if (restored) {
584
+ if (restored.ok) {
559
585
  this.activeSessions.add(existingSessionId);
560
586
  this.bootstrappedSessions.add(existingSessionId);
587
+ await this.configureSessionMode(roomId, existingSessionId, restored.modes, connection);
561
588
  return existingSessionId;
562
589
  }
563
590
  }
@@ -567,30 +594,92 @@ ${message.content}`;
567
594
  });
568
595
  this.roomToSession.set(roomId, created.sessionId);
569
596
  this.activeSessions.add(created.sessionId);
597
+ await this.configureSessionMode(roomId, created.sessionId, created.modes, connection);
570
598
  return created.sessionId;
571
599
  }
600
+ // Best-effort: never throws, so a mode switch going wrong can't take a
601
+ // session establishment down with it.
602
+ async configureSessionMode(roomId, sessionId, modes, connection) {
603
+ if (!this.resolveSessionMode || !modes) {
604
+ return;
605
+ }
606
+ const availableModes = Array.isArray(modes.availableModes) ? modes.availableModes : [];
607
+ if (availableModes.length === 0) {
608
+ return;
609
+ }
610
+ const selectedModeId = await this.resolveSessionModeManually(
611
+ (signal) => this.resolveSessionMode({
612
+ roomId,
613
+ sessionId,
614
+ currentModeId: modes.currentModeId,
615
+ modes: availableModes
616
+ }, signal),
617
+ connection.signal
618
+ );
619
+ if (!selectedModeId || selectedModeId === modes.currentModeId) {
620
+ return;
621
+ }
622
+ if (!availableModes.some((mode) => mode?.id === selectedModeId)) {
623
+ this.safeWarn("resolveSessionMode selected a mode id this session does not advertise", {
624
+ sessionId,
625
+ selectedModeId,
626
+ availableModeIds: availableModes.map((mode) => mode?.id)
627
+ });
628
+ return;
629
+ }
630
+ try {
631
+ await withTimeout(
632
+ connection.setSessionMode({ sessionId, modeId: selectedModeId }),
633
+ SET_SESSION_MODE_TIMEOUT_MS,
634
+ `setSessionMode did not respond within ${SET_SESSION_MODE_TIMEOUT_MS}ms`
635
+ );
636
+ } catch (error) {
637
+ this.safeWarn("failed to switch session into the selected mode", {
638
+ sessionId,
639
+ selectedModeId,
640
+ error: String(error)
641
+ });
642
+ }
643
+ }
644
+ async resolveSessionModeManually(resolver, signal) {
645
+ const controller = new AbortController();
646
+ const abort = () => controller.abort();
647
+ signal.addEventListener("abort", abort, { once: true });
648
+ let timer;
649
+ try {
650
+ const cancelled = new Promise((resolve) => {
651
+ controller.signal.addEventListener("abort", () => resolve(void 0), { once: true });
652
+ });
653
+ const timeout = new Promise((resolve) => {
654
+ timer = setTimeout(() => resolve(void 0), this.permissionTimeoutMs);
655
+ });
656
+ return await Promise.race([
657
+ Promise.resolve().then(() => resolver(controller.signal)).catch((error) => {
658
+ this.safeWarn("resolveSessionMode threw; preserving the harness default", { error: String(error) });
659
+ return void 0;
660
+ }),
661
+ timeout,
662
+ cancelled
663
+ ]);
664
+ } finally {
665
+ clearTimeout(timer);
666
+ signal.removeEventListener("abort", abort);
667
+ controller.abort();
668
+ }
669
+ }
572
670
  async tryRestoreSession(connection, sessionId, mcpServers) {
671
+ const capabilities = this.connectionState?.agentCapabilities;
672
+ const params = { cwd: this.cwd, mcpServers, sessionId };
673
+ const restore = capabilities?.loadSession ? () => connection.loadSession(params) : capabilities?.sessionCapabilities?.resume ? () => connection.unstable_resumeSession(params) : null;
674
+ if (!restore) {
675
+ return { ok: false };
676
+ }
573
677
  try {
574
- if (this.connectionState?.agentCapabilities?.loadSession) {
575
- await connection.loadSession({
576
- cwd: this.cwd,
577
- mcpServers,
578
- sessionId
579
- });
580
- return true;
581
- }
582
- if (this.connectionState?.agentCapabilities?.sessionCapabilities?.resume) {
583
- await connection.unstable_resumeSession({
584
- cwd: this.cwd,
585
- mcpServers,
586
- sessionId
587
- });
588
- return true;
589
- }
678
+ const restored = await restore();
679
+ return { ok: true, modes: restored?.modes };
590
680
  } catch {
591
- return false;
681
+ return { ok: false };
592
682
  }
593
- return false;
594
683
  }
595
684
  async buildSessionMcpServers() {
596
685
  const mcpServers = [...this.mcpServers];
@@ -729,6 +818,18 @@ ${message.content}`;
729
818
  const matched = chosenId !== void 0 && options.some((option) => option.optionId === chosenId);
730
819
  return matched ? { outcome: { outcome: "selected", optionId: chosenId } } : { outcome: { outcome: "cancelled" } };
731
820
  }
821
+ // A caller-supplied `Logger` isn't guaranteed to be synchronous or
822
+ // non-throwing. Every best-effort warning in this file routes through here
823
+ // so one failing sink — a synchronous throw, or an `async` implementation
824
+ // rejecting (the `Logger` interface's `void` return type permits either;
825
+ // a bare try/catch only ever catches the former) — can't turn a warning
826
+ // into an unhandled rejection in its place.
827
+ safeWarn(message, context) {
828
+ try {
829
+ Promise.resolve(this.logger.warn(message, context)).catch(() => void 0);
830
+ } catch {
831
+ }
832
+ }
732
833
  // Races the caller-supplied resolver against a timeout and against
733
834
  // `controller`'s own abort signal — aborted externally by
734
835
  // `cancelPendingPermissions`/`cancelAllPendingPermissions` (fired from
@@ -752,10 +853,7 @@ ${message.content}`;
752
853
  // rejected promise, so both land in the `.catch` below rather than
753
854
  // escaping this race uncaught.
754
855
  Promise.resolve().then(() => this.resolvePermission(params, controller.signal)).catch((error) => {
755
- try {
756
- this.logger.warn("resolvePermission threw; treating as no answer", { error: String(error) });
757
- } catch {
758
- }
856
+ this.safeWarn("resolvePermission threw; treating as no answer", { error: String(error) });
759
857
  return void 0;
760
858
  }),
761
859
  timeout,
@@ -795,13 +893,14 @@ ${message.content}`;
795
893
  return;
796
894
  }
797
895
  for (const chunk of client.getCollectedChunks(input.sessionId)) {
896
+ if (isBlankEventContent(chunk.content)) {
897
+ continue;
898
+ }
798
899
  if (chunk.chunkType === "text") {
799
- if (chunk.content.length > 0) {
800
- await input.tools.sendMessage(chunk.content, [{
801
- id: input.senderId,
802
- handle: input.senderHandle
803
- }]);
804
- }
900
+ await input.tools.sendMessage(chunk.content, [{
901
+ id: input.senderId,
902
+ handle: input.senderHandle
903
+ }]);
805
904
  continue;
806
905
  }
807
906
  const messageType = chunk.chunkType === "plan" ? "task" : chunk.chunkType;
@@ -0,0 +1,29 @@
1
+ import {
2
+ ValidationError
3
+ } from "./chunk-JY75VSQK.js";
4
+
5
+ // src/contracts/chatEvents.ts
6
+ var CHAT_EVENT_TYPES = ["tool_call", "tool_result", "thought", "error", "task"];
7
+ var CHAT_MESSAGE_TYPES = ["text", ...CHAT_EVENT_TYPES];
8
+ function isChatEventType(value) {
9
+ return CHAT_EVENT_TYPES.includes(value);
10
+ }
11
+ function assertChatEventType(value) {
12
+ if (!isChatEventType(value)) {
13
+ throw new ValidationError(
14
+ `Invalid event message_type '${value}'. Expected one of: ${CHAT_EVENT_TYPES.join(", ")}`
15
+ );
16
+ }
17
+ }
18
+ var VISIBLE_CONTENT_PATTERN = /[\p{L}\p{N}\p{P}\p{S}]/u;
19
+ function isBlankEventContent(content) {
20
+ return !VISIBLE_CONTENT_PATTERN.test(content);
21
+ }
22
+
23
+ export {
24
+ CHAT_EVENT_TYPES,
25
+ CHAT_MESSAGE_TYPES,
26
+ isChatEventType,
27
+ assertChatEventType,
28
+ isBlankEventContent
29
+ };
@@ -21,6 +21,13 @@ function isToolExecutorError(value) {
21
21
  const candidate = value;
22
22
  return candidate.ok === false && typeof candidate.errorType === "string" && TOOL_EXECUTOR_ERROR_TYPES.includes(candidate.errorType) && typeof candidate.toolName === "string" && typeof candidate.message === "string" && typeof candidate.legacyMessage === "string";
23
23
  }
24
+ function isStructuredToolFailure(value) {
25
+ if (!value || typeof value !== "object") {
26
+ return false;
27
+ }
28
+ const payload = value;
29
+ return payload.ok === false && typeof payload.message === "string";
30
+ }
24
31
  function toLegacyToolExecutorErrorMessage(value) {
25
32
  if (typeof value === "string") {
26
33
  return value;
@@ -39,6 +46,7 @@ var DEFAULT_AGENT_TOOLS_CAPABILITIES = {
39
46
  export {
40
47
  createToolExecutorError,
41
48
  isToolExecutorError,
49
+ isStructuredToolFailure,
42
50
  toLegacyToolExecutorErrorMessage,
43
51
  DEFAULT_AGENT_TOOLS_CAPABILITIES
44
52
  };