@witqq/agent-sdk 0.6.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/README.md +433 -6
  2. package/dist/auth/index.cjs +188 -1
  3. package/dist/auth/index.cjs.map +1 -1
  4. package/dist/auth/index.d.cts +154 -138
  5. package/dist/auth/index.d.ts +154 -138
  6. package/dist/auth/index.js +188 -2
  7. package/dist/auth/index.js.map +1 -1
  8. package/dist/backends/claude.cjs +315 -21
  9. package/dist/backends/claude.cjs.map +1 -1
  10. package/dist/backends/claude.d.cts +2 -1
  11. package/dist/backends/claude.d.ts +2 -1
  12. package/dist/backends/claude.js +315 -21
  13. package/dist/backends/claude.js.map +1 -1
  14. package/dist/backends/copilot.cjs +132 -24
  15. package/dist/backends/copilot.cjs.map +1 -1
  16. package/dist/backends/copilot.d.cts +2 -1
  17. package/dist/backends/copilot.d.ts +2 -1
  18. package/dist/backends/copilot.js +132 -24
  19. package/dist/backends/copilot.js.map +1 -1
  20. package/dist/backends/vercel-ai.cjs +56 -17
  21. package/dist/backends/vercel-ai.cjs.map +1 -1
  22. package/dist/backends/vercel-ai.d.cts +1 -1
  23. package/dist/backends/vercel-ai.d.ts +1 -1
  24. package/dist/backends/vercel-ai.js +56 -17
  25. package/dist/backends/vercel-ai.js.map +1 -1
  26. package/dist/chat/accumulator.cjs +147 -0
  27. package/dist/chat/accumulator.cjs.map +1 -0
  28. package/dist/chat/accumulator.d.cts +61 -0
  29. package/dist/chat/accumulator.d.ts +61 -0
  30. package/dist/chat/accumulator.js +145 -0
  31. package/dist/chat/accumulator.js.map +1 -0
  32. package/dist/chat/backends.cjs +3534 -0
  33. package/dist/chat/backends.cjs.map +1 -0
  34. package/dist/chat/backends.d.cts +62 -0
  35. package/dist/chat/backends.d.ts +62 -0
  36. package/dist/chat/backends.js +3501 -0
  37. package/dist/chat/backends.js.map +1 -0
  38. package/dist/chat/context.cjs +230 -0
  39. package/dist/chat/context.cjs.map +1 -0
  40. package/dist/chat/context.d.cts +167 -0
  41. package/dist/chat/context.d.ts +167 -0
  42. package/dist/chat/context.js +227 -0
  43. package/dist/chat/context.js.map +1 -0
  44. package/dist/chat/core.cjs +282 -0
  45. package/dist/chat/core.cjs.map +1 -0
  46. package/dist/chat/core.d.cts +435 -0
  47. package/dist/chat/core.d.ts +435 -0
  48. package/dist/chat/core.js +261 -0
  49. package/dist/chat/core.js.map +1 -0
  50. package/dist/chat/errors.cjs +251 -0
  51. package/dist/chat/errors.cjs.map +1 -0
  52. package/dist/chat/errors.d.cts +122 -0
  53. package/dist/chat/errors.d.ts +122 -0
  54. package/dist/chat/errors.js +243 -0
  55. package/dist/chat/errors.js.map +1 -0
  56. package/dist/chat/events.cjs +203 -0
  57. package/dist/chat/events.cjs.map +1 -0
  58. package/dist/chat/events.d.cts +241 -0
  59. package/dist/chat/events.d.ts +241 -0
  60. package/dist/chat/events.js +196 -0
  61. package/dist/chat/events.js.map +1 -0
  62. package/dist/chat/index.cjs +5359 -0
  63. package/dist/chat/index.cjs.map +1 -0
  64. package/dist/chat/index.d.cts +52 -0
  65. package/dist/chat/index.d.ts +52 -0
  66. package/dist/chat/index.js +5296 -0
  67. package/dist/chat/index.js.map +1 -0
  68. package/dist/chat/react.cjs +2739 -0
  69. package/dist/chat/react.cjs.map +1 -0
  70. package/dist/chat/react.d.cts +619 -0
  71. package/dist/chat/react.d.ts +619 -0
  72. package/dist/chat/react.js +2714 -0
  73. package/dist/chat/react.js.map +1 -0
  74. package/dist/chat/runtime.cjs +1030 -0
  75. package/dist/chat/runtime.cjs.map +1 -0
  76. package/dist/chat/runtime.d.cts +118 -0
  77. package/dist/chat/runtime.d.ts +118 -0
  78. package/dist/chat/runtime.js +1028 -0
  79. package/dist/chat/runtime.js.map +1 -0
  80. package/dist/chat/server.cjs +643 -0
  81. package/dist/chat/server.cjs.map +1 -0
  82. package/dist/chat/server.d.cts +287 -0
  83. package/dist/chat/server.d.ts +287 -0
  84. package/dist/chat/server.js +617 -0
  85. package/dist/chat/server.js.map +1 -0
  86. package/dist/chat/sessions.cjs +398 -0
  87. package/dist/chat/sessions.cjs.map +1 -0
  88. package/dist/chat/sessions.d.cts +239 -0
  89. package/dist/chat/sessions.d.ts +239 -0
  90. package/dist/chat/sessions.js +394 -0
  91. package/dist/chat/sessions.js.map +1 -0
  92. package/dist/chat/state.cjs +177 -0
  93. package/dist/chat/state.cjs.map +1 -0
  94. package/dist/chat/state.d.cts +92 -0
  95. package/dist/chat/state.d.ts +92 -0
  96. package/dist/chat/state.js +167 -0
  97. package/dist/chat/state.js.map +1 -0
  98. package/dist/chat/storage.cjs +240 -0
  99. package/dist/chat/storage.cjs.map +1 -0
  100. package/dist/chat/storage.d.cts +191 -0
  101. package/dist/chat/storage.d.ts +191 -0
  102. package/dist/chat/storage.js +236 -0
  103. package/dist/chat/storage.js.map +1 -0
  104. package/dist/errors-BDLbNu9w.d.cts +13 -0
  105. package/dist/errors-BDLbNu9w.d.ts +13 -0
  106. package/dist/in-process-transport-C2oPTYs6.d.ts +223 -0
  107. package/dist/in-process-transport-DG-w5G6k.d.cts +223 -0
  108. package/dist/index.cjs +25 -13
  109. package/dist/index.cjs.map +1 -1
  110. package/dist/index.d.cts +32 -4
  111. package/dist/index.d.ts +32 -4
  112. package/dist/index.js +25 -13
  113. package/dist/index.js.map +1 -1
  114. package/dist/transport-D1OaUgRk.d.ts +67 -0
  115. package/dist/transport-DX1Nhm4N.d.cts +67 -0
  116. package/dist/types-Bh5AhqD-.d.ts +141 -0
  117. package/dist/types-CGF7AEX1.d.cts +141 -0
  118. package/dist/{types-BvwNzZCj.d.cts → types-CqvUAYxt.d.cts} +21 -3
  119. package/dist/{types-BvwNzZCj.d.ts → types-CqvUAYxt.d.ts} +21 -3
  120. package/dist/types-DLZzlJxt.d.ts +39 -0
  121. package/dist/types-tE0CXwBl.d.cts +39 -0
  122. package/package.json +149 -2
@@ -6,10 +6,16 @@ function getTextContent(content) {
6
6
 
7
7
  // src/errors.ts
8
8
  var AgentSDKError = class extends Error {
9
+ /** @internal Marker for cross-bundle identity checks */
10
+ _agentSDKError = true;
9
11
  constructor(message, options) {
10
12
  super(message, options);
11
13
  this.name = "AgentSDKError";
12
14
  }
15
+ /** Check if an error is an AgentSDKError (works across bundled copies) */
16
+ static is(error) {
17
+ return error instanceof Error && "_agentSDKError" in error && error._agentSDKError === true;
18
+ }
13
19
  };
14
20
  var ReentrancyError = class extends AgentSDKError {
15
21
  constructor() {
@@ -41,6 +47,7 @@ var BaseAgent = class {
41
47
  state = "idle";
42
48
  abortController = null;
43
49
  config;
50
+ _cleanupExternalSignal = null;
44
51
  /** CLI session ID for persistent mode. Override in backends that support it. */
45
52
  get sessionId() {
46
53
  return void 0;
@@ -60,8 +67,7 @@ var BaseAgent = class {
60
67
  this.enrichAndNotifyUsage(result);
61
68
  return result;
62
69
  } finally {
63
- this.state = "idle";
64
- this.abortController = null;
70
+ this.cleanupRun();
65
71
  }
66
72
  }
67
73
  async runWithContext(messages, options) {
@@ -74,8 +80,7 @@ var BaseAgent = class {
74
80
  this.enrichAndNotifyUsage(result);
75
81
  return result;
76
82
  } finally {
77
- this.state = "idle";
78
- this.abortController = null;
83
+ this.cleanupRun();
79
84
  }
80
85
  }
81
86
  async runStructured(prompt, schema, options) {
@@ -94,8 +99,7 @@ var BaseAgent = class {
94
99
  this.enrichAndNotifyUsage(result);
95
100
  return result;
96
101
  } finally {
97
- this.state = "idle";
98
- this.abortController = null;
102
+ this.cleanupRun();
99
103
  }
100
104
  }
101
105
  async *stream(prompt, options) {
@@ -108,8 +112,7 @@ var BaseAgent = class {
108
112
  const enriched = this.enrichStream(this.executeStream(messages, options, ac.signal));
109
113
  yield* this.heartbeatStream(enriched);
110
114
  } finally {
111
- this.state = "idle";
112
- this.abortController = null;
115
+ this.cleanupRun();
113
116
  }
114
117
  }
115
118
  async *streamWithContext(messages, options) {
@@ -121,8 +124,7 @@ var BaseAgent = class {
121
124
  const enriched = this.enrichStream(this.executeStream(messages, options, ac.signal));
122
125
  yield* this.heartbeatStream(enriched);
123
126
  } finally {
124
- this.state = "idle";
125
- this.abortController = null;
127
+ this.cleanupRun();
126
128
  }
127
129
  }
128
130
  abort() {
@@ -142,6 +144,8 @@ var BaseAgent = class {
142
144
  }
143
145
  /** Mark agent as disposed. Override to add cleanup. */
144
146
  dispose() {
147
+ this._cleanupExternalSignal?.();
148
+ this._cleanupExternalSignal = null;
145
149
  this.abort();
146
150
  this.state = "disposed";
147
151
  }
@@ -252,16 +256,24 @@ var BaseAgent = class {
252
256
  }
253
257
  }
254
258
  // ─── Internal Helpers ─────────────────────────────────────────
259
+ /** Clean up after a run completes (success, error, or abort). */
260
+ cleanupRun() {
261
+ this._cleanupExternalSignal?.();
262
+ this._cleanupExternalSignal = null;
263
+ this.state = "idle";
264
+ this.abortController = null;
265
+ }
255
266
  createAbortController(externalSignal) {
256
267
  const ac = new AbortController();
257
268
  this.abortController = ac;
269
+ this._cleanupExternalSignal = null;
258
270
  if (externalSignal) {
259
271
  if (externalSignal.aborted) {
260
272
  ac.abort();
261
273
  } else {
262
- externalSignal.addEventListener("abort", () => ac.abort(), {
263
- once: true
264
- });
274
+ const listener = () => ac.abort();
275
+ externalSignal.addEventListener("abort", listener, { once: true });
276
+ this._cleanupExternalSignal = () => externalSignal.removeEventListener("abort", listener);
265
277
  }
266
278
  }
267
279
  return ac;
@@ -347,9 +359,25 @@ function mapToolsToSDK(tools) {
347
359
  return tools.map((tool) => ({
348
360
  name: tool.name,
349
361
  description: tool.description,
350
- // Pass Zod schema directly — Copilot SDK accepts ZodSchema natively
351
- // and handles conversion internally, avoiding potential schema format issues.
352
- parameters: tool.parameters,
362
+ parameters: convertParameters(tool.parameters),
363
+ handler: async (args) => {
364
+ const result = await tool.execute(args);
365
+ return typeof result === "string" ? result : JSON.stringify(result);
366
+ }
367
+ }));
368
+ }
369
+ function convertParameters(params) {
370
+ if (!params) return void 0;
371
+ if (params && typeof params === "object" && "_def" in params) {
372
+ return zodToJsonSchema(params);
373
+ }
374
+ return params;
375
+ }
376
+ async function mapToolsToSDKAsync(tools) {
377
+ return tools.map((tool) => ({
378
+ name: tool.name,
379
+ description: tool.description,
380
+ parameters: convertParameters(tool.parameters),
353
381
  handler: async (args) => {
354
382
  const result = await tool.execute(args);
355
383
  return typeof result === "string" ? result : JSON.stringify(result);
@@ -541,12 +569,14 @@ var CopilotAgent = class extends BaseAgent {
541
569
  persistentSession = null;
542
570
  _sessionId;
543
571
  activeSession = null;
544
- constructor(config, getClient, sendAndWaitTimeout) {
572
+ _resumeSessionId;
573
+ _toolsReady = null;
574
+ constructor(config, getClient, sendAndWaitTimeout, resumeSessionId) {
545
575
  super(config);
546
576
  this.getClient = getClient;
547
577
  this.sendAndWaitTimeout = sendAndWaitTimeout;
548
578
  this.isPersistent = config.sessionMode === "persistent";
549
- this.sdkTools = mapToolsToSDK(config.tools);
579
+ this.sdkTools = mapToolsToSDK(config.tools ?? []);
550
580
  this.sessionConfig = {
551
581
  model: config.model,
552
582
  tools: this.sdkTools,
@@ -556,8 +586,16 @@ var CopilotAgent = class extends BaseAgent {
556
586
  },
557
587
  onPermissionRequest: buildPermissionHandler(config),
558
588
  onUserInputRequest: buildUserInputHandler(config),
559
- ...config.availableTools ? { availableTools: config.availableTools } : {}
589
+ ...config.availableTools?.length ? { availableTools: config.availableTools } : {}
560
590
  };
591
+ this._toolsReady = this._initToolsAsync(config);
592
+ this._resumeSessionId = resumeSessionId;
593
+ }
594
+ /** Pre-convert Zod schemas to JSON Schema asynchronously.
595
+ * Updates sdkTools and sessionConfig.tools before first session creation. */
596
+ async _initToolsAsync(config) {
597
+ this.sdkTools = await mapToolsToSDKAsync(config.tools ?? []);
598
+ this.sessionConfig.tools = this.sdkTools;
561
599
  }
562
600
  get sessionId() {
563
601
  return this._sessionId;
@@ -586,7 +624,27 @@ var CopilotAgent = class extends BaseAgent {
586
624
  if (this.isPersistent && this.persistentSession) {
587
625
  return { session: this.persistentSession, isNew: false };
588
626
  }
627
+ if (this._toolsReady) {
628
+ await this._toolsReady;
629
+ this._toolsReady = null;
630
+ }
589
631
  const client = await this.getClient();
632
+ if (this._resumeSessionId) {
633
+ const storedId = this._resumeSessionId;
634
+ this._resumeSessionId = void 0;
635
+ try {
636
+ const session2 = await client.resumeSession(storedId, {
637
+ ...this.sessionConfig,
638
+ streaming: this.isPersistent ? true : streaming
639
+ });
640
+ if (this.isPersistent) {
641
+ this.persistentSession = session2;
642
+ this._sessionId = session2.sessionId;
643
+ }
644
+ return { session: session2, isNew: false };
645
+ } catch {
646
+ }
647
+ }
590
648
  const session = await client.createSession({
591
649
  ...this.sessionConfig,
592
650
  streaming: this.isPersistent ? true : streaming
@@ -794,13 +852,43 @@ function extractLastUserPrompt(messages) {
794
852
  }
795
853
  return "";
796
854
  }
855
+ function serializeToolCall(tc) {
856
+ const args = typeof tc.args === "string" ? tc.args : JSON.stringify(tc.args);
857
+ return ` Tool call: ${tc.name}(${args})`;
858
+ }
859
+ function serializeToolResult(tr) {
860
+ const result = typeof tr.result === "string" ? tr.result : JSON.stringify(tr.result);
861
+ const prefix = tr.isError ? "[ERROR] " : "";
862
+ return ` ${tr.name} \u2192 ${prefix}${result}`;
863
+ }
797
864
  function buildContextualPrompt(messages) {
798
865
  if (messages.length <= 1) {
799
866
  return extractLastUserPrompt(messages);
800
867
  }
801
868
  const history = messages.slice(0, -1).map((msg) => {
869
+ if (msg.role === "user") {
870
+ return `User: ${msg.content ? getTextContent(msg.content) : ""}`;
871
+ }
872
+ if (msg.role === "tool" && msg.toolResults) {
873
+ const results = msg.toolResults.map(serializeToolResult).join("\n");
874
+ return `Tool results:
875
+ ${results}`;
876
+ }
877
+ if (msg.role === "assistant") {
878
+ const parts = [];
879
+ const thinking = msg.thinking;
880
+ if (thinking) {
881
+ parts.push(`[reasoning: ${thinking}]`);
882
+ }
883
+ const text2 = msg.content ? getTextContent(msg.content) : "";
884
+ if (text2) parts.push(text2);
885
+ if (msg.toolCalls && msg.toolCalls.length > 0) {
886
+ parts.push(msg.toolCalls.map(serializeToolCall).join("\n"));
887
+ }
888
+ return `Assistant: ${parts.join("\n")}`;
889
+ }
802
890
  const text = msg.content ? getTextContent(msg.content) : "";
803
- return msg.role === "user" ? `User: ${text}` : `Assistant: ${text}`;
891
+ return `${msg.role}: ${text}`;
804
892
  }).join("\n");
805
893
  const lastPrompt = extractLastUserPrompt(messages);
806
894
  return `Conversation history:
@@ -808,6 +896,21 @@ ${history}
808
896
 
809
897
  User: ${lastPrompt}`;
810
898
  }
899
+ function withTimeout(promise, ms, message) {
900
+ return new Promise((resolve, reject) => {
901
+ const timer = setTimeout(() => reject(new SubprocessError(message)), ms);
902
+ promise.then(
903
+ (val) => {
904
+ clearTimeout(timer);
905
+ resolve(val);
906
+ },
907
+ (err) => {
908
+ clearTimeout(timer);
909
+ reject(err);
910
+ }
911
+ );
912
+ });
913
+ }
811
914
  var CopilotAgentService = class {
812
915
  name = "copilot";
813
916
  client = null;
@@ -832,12 +935,17 @@ var CopilotAgentService = class {
832
935
  autoRestart: true,
833
936
  logLevel: "error",
834
937
  githubToken: this.options.githubToken,
835
- useLoggedInUser: this.options.useLoggedInUser ?? true,
938
+ useLoggedInUser: this.options.useLoggedInUser ?? !this.options.githubToken,
836
939
  ...this.options.cliArgs ? { cliArgs: this.options.cliArgs } : {},
837
940
  ...this.options.env ? { env: { ...process.env, ...this.options.env } } : {}
838
941
  });
839
- await client.start();
840
- const auth = await client.getAuthStatus();
942
+ const startupTimeout = this.options.startupTimeoutMs ?? 3e4;
943
+ await withTimeout(client.start(), startupTimeout, "CLI startup timed out");
944
+ const auth = await withTimeout(
945
+ client.getAuthStatus(),
946
+ startupTimeout,
947
+ "Auth status check timed out \u2014 token may be expired"
948
+ );
841
949
  if (!auth.isAuthenticated) {
842
950
  await client.stop();
843
951
  throw new SubprocessError(
@@ -855,7 +963,7 @@ var CopilotAgentService = class {
855
963
  }
856
964
  createAgent(config) {
857
965
  if (this.disposed) throw new DisposedError("CopilotAgentService");
858
- return new CopilotAgent(config, () => this.ensureClient(), this.options.timeout);
966
+ return new CopilotAgent(config, () => this.ensureClient(), this.options.timeout, this.options.resumeSessionId);
859
967
  }
860
968
  async listModels() {
861
969
  const client = await this.ensureClient();