@yourgpt/copilot-sdk 2.1.8 → 2.1.9-alpha.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 (33) hide show
  1. package/dist/{chunk-ISOMZAYN.js → chunk-RBULQ6EJ.js} +207 -62
  2. package/dist/chunk-RBULQ6EJ.js.map +1 -0
  3. package/dist/chunk-RPR5GMWF.js +52 -0
  4. package/dist/chunk-RPR5GMWF.js.map +1 -0
  5. package/dist/{chunk-IDAQU3FP.cjs → chunk-TD7NF6OE.cjs} +207 -62
  6. package/dist/chunk-TD7NF6OE.cjs.map +1 -0
  7. package/dist/{chunk-JFVTY757.cjs → chunk-WYFJZNFT.cjs} +16 -16
  8. package/dist/{chunk-JFVTY757.cjs.map → chunk-WYFJZNFT.cjs.map} +1 -1
  9. package/dist/{chunk-H3LX6FTP.js → chunk-XVKKLLKW.js} +3 -3
  10. package/dist/{chunk-H3LX6FTP.js.map → chunk-XVKKLLKW.js.map} +1 -1
  11. package/dist/chunk-YBLAHX2Z.cjs +55 -0
  12. package/dist/chunk-YBLAHX2Z.cjs.map +1 -0
  13. package/dist/experimental/index.cjs +416 -536
  14. package/dist/experimental/index.cjs.map +1 -1
  15. package/dist/experimental/index.d.cts +189 -853
  16. package/dist/experimental/index.d.ts +189 -853
  17. package/dist/experimental/index.js +415 -530
  18. package/dist/experimental/index.js.map +1 -1
  19. package/dist/react/index.cjs +62 -62
  20. package/dist/react/index.d.cts +18 -0
  21. package/dist/react/index.d.ts +18 -0
  22. package/dist/react/index.js +2 -2
  23. package/dist/ui/index.cjs +521 -263
  24. package/dist/ui/index.cjs.map +1 -1
  25. package/dist/ui/index.js +352 -94
  26. package/dist/ui/index.js.map +1 -1
  27. package/package.json +2 -1
  28. package/dist/chunk-5EGBIQYS.cjs +0 -292
  29. package/dist/chunk-5EGBIQYS.cjs.map +0 -1
  30. package/dist/chunk-IDAQU3FP.cjs.map +0 -1
  31. package/dist/chunk-ISOMZAYN.js.map +0 -1
  32. package/dist/chunk-TXQ37MAO.js +0 -287
  33. package/dist/chunk-TXQ37MAO.js.map +0 -1
@@ -0,0 +1,52 @@
1
+ import { clsx } from 'clsx';
2
+ import { twMerge } from 'tailwind-merge';
3
+ import { memo } from 'react';
4
+ import { Streamdown } from 'streamdown';
5
+ import { code } from '@streamdown/code';
6
+ import { math } from '@streamdown/math';
7
+ import { jsx } from 'react/jsx-runtime';
8
+
9
+ // src/ui/lib/utils.ts
10
+ function cn(...inputs) {
11
+ return twMerge(clsx(inputs));
12
+ }
13
+ var createHeading = (Tag) => {
14
+ const HeadingComponent = ({
15
+ children,
16
+ className: _,
17
+ ...props
18
+ }) => /* @__PURE__ */ jsx(Tag, { className: "text-[1em] font-semibold my-2 first:mt-0", ...props, children });
19
+ HeadingComponent.displayName = Tag.toUpperCase();
20
+ return HeadingComponent;
21
+ };
22
+ var headingComponents = {
23
+ h1: createHeading("h1"),
24
+ h2: createHeading("h2"),
25
+ h3: createHeading("h3"),
26
+ h4: createHeading("h4"),
27
+ h5: createHeading("h5"),
28
+ h6: createHeading("h6")
29
+ };
30
+ function MarkdownComponent({
31
+ children,
32
+ className,
33
+ isStreaming = false,
34
+ linkSafety = { enabled: false }
35
+ }) {
36
+ return /* @__PURE__ */ jsx("div", { className, children: /* @__PURE__ */ jsx(
37
+ Streamdown,
38
+ {
39
+ plugins: { code, math },
40
+ isAnimating: isStreaming,
41
+ components: headingComponents,
42
+ linkSafety,
43
+ children
44
+ }
45
+ ) });
46
+ }
47
+ var Markdown = memo(MarkdownComponent);
48
+ Markdown.displayName = "Markdown";
49
+
50
+ export { Markdown, cn };
51
+ //# sourceMappingURL=chunk-RPR5GMWF.js.map
52
+ //# sourceMappingURL=chunk-RPR5GMWF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ui/lib/utils.ts","../src/ui/components/ui/markdown.tsx"],"names":[],"mappings":";;;;;;;;;AAGO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACWA,IAAM,aAAA,GAAgB,CAAC,GAAA,KAAiD;AACtE,EAAA,MAAM,mBAAmB,CAAC;AAAA,IACxB,QAAA;AAAA,IACA,SAAA,EAAW,CAAA;AAAA,IACX,GAAG;AAAA,wBAEH,GAAA,CAAC,GAAA,EAAA,EAAI,WAAU,0CAAA,EAA4C,GAAG,OAC3D,QAAA,EACH,CAAA;AAEF,EAAA,gBAAA,CAAiB,WAAA,GAAc,IAAI,WAAA,EAAY;AAC/C,EAAA,OAAO,gBAAA;AACT,CAAA;AAEA,IAAM,iBAAA,GAAoB;AAAA,EACxB,EAAA,EAAI,cAAc,IAAI,CAAA;AAAA,EACtB,EAAA,EAAI,cAAc,IAAI,CAAA;AAAA,EACtB,EAAA,EAAI,cAAc,IAAI,CAAA;AAAA,EACtB,EAAA,EAAI,cAAc,IAAI,CAAA;AAAA,EACtB,EAAA,EAAI,cAAc,IAAI,CAAA;AAAA,EACtB,EAAA,EAAI,cAAc,IAAI;AACxB,CAAA;AAEA,SAAS,iBAAA,CAAkB;AAAA,EACzB,QAAA;AAAA,EACA,SAAA;AAAA,EACA,WAAA,GAAc,KAAA;AAAA,EACd,UAAA,GAAa,EAAE,OAAA,EAAS,KAAA;AAC1B,CAAA,EAAkB;AAChB,EAAA,uBACE,GAAA,CAAC,SAAI,SAAA,EACH,QAAA,kBAAA,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,OAAA,EAAS,EAAE,IAAA,EAAM,IAAA,EAAK;AAAA,MACtB,WAAA,EAAa,WAAA;AAAA,MACb,UAAA,EAAY,iBAAA;AAAA,MACZ,UAAA;AAAA,MAEC;AAAA;AAAA,GACH,EACF,CAAA;AAEJ;AAEA,IAAM,QAAA,GAAW,KAAK,iBAAiB;AACvC,QAAA,CAAS,WAAA,GAAc,UAAA","file":"chunk-RPR5GMWF.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import { memo, ComponentProps } from \"react\";\nimport { Streamdown, LinkSafetyConfig } from \"streamdown\";\nimport { code } from \"@streamdown/code\";\nimport { math } from \"@streamdown/math\";\n\nexport type MarkdownProps = {\n children: string;\n id?: string;\n className?: string;\n isStreaming?: boolean;\n /** Link safety modal configuration. Disabled by default. */\n linkSafety?: LinkSafetyConfig;\n};\n\n// Normalized heading component for chat UI (same size, just bold)\n// Ignore Streamdown's className to prevent its text-3xl etc. from overriding\nconst createHeading = (Tag: \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\") => {\n const HeadingComponent = ({\n children,\n className: _,\n ...props\n }: ComponentProps<typeof Tag>) => (\n <Tag className=\"text-[1em] font-semibold my-2 first:mt-0\" {...props}>\n {children}\n </Tag>\n );\n HeadingComponent.displayName = Tag.toUpperCase();\n return HeadingComponent;\n};\n\nconst headingComponents = {\n h1: createHeading(\"h1\"),\n h2: createHeading(\"h2\"),\n h3: createHeading(\"h3\"),\n h4: createHeading(\"h4\"),\n h5: createHeading(\"h5\"),\n h6: createHeading(\"h6\"),\n};\n\nfunction MarkdownComponent({\n children,\n className,\n isStreaming = false,\n linkSafety = { enabled: false },\n}: MarkdownProps) {\n return (\n <div className={className}>\n <Streamdown\n plugins={{ code, math }}\n isAnimating={isStreaming}\n components={headingComponents}\n linkSafety={linkSafety}\n >\n {children}\n </Streamdown>\n </div>\n );\n}\n\nconst Markdown = memo(MarkdownComponent);\nMarkdown.displayName = \"Markdown\";\n\nexport { Markdown };\nexport type { LinkSafetyConfig } from \"streamdown\";\n"]}
@@ -45,6 +45,19 @@ function isStreamDone(chunk) {
45
45
  }
46
46
 
47
47
  // src/chat/functions/stream/processChunk.ts
48
+ function parsePartialJson(partial) {
49
+ if (!partial || !partial.startsWith("{")) return null;
50
+ const result = {};
51
+ const stringPairs = partial.matchAll(/"(\w+)"\s*:\s*"((?:[^"\\]|\\.)*)"/g);
52
+ for (const m of stringPairs) {
53
+ result[m[1]] = m[2];
54
+ }
55
+ const openString = partial.match(/"(\w+)"\s*:\s*"((?:[^"\\]|\\.)*)$/);
56
+ if (openString) {
57
+ result[openString[1]] = openString[2];
58
+ }
59
+ return Object.keys(result).length > 0 ? result : null;
60
+ }
48
61
  function processStreamChunk(chunk, state) {
49
62
  switch (chunk.type) {
50
63
  case "message:start":
@@ -85,12 +98,17 @@ function processStreamChunk(chunk, state) {
85
98
  const existing = state.toolResults.get(chunk.id);
86
99
  if (existing) {
87
100
  const newResults = new Map(state.toolResults);
101
+ let parsed = null;
88
102
  try {
103
+ parsed = JSON.parse(chunk.args);
104
+ } catch {
105
+ parsed = parsePartialJson(chunk.args);
106
+ }
107
+ if (parsed) {
89
108
  newResults.set(chunk.id, {
90
109
  ...existing,
91
- args: JSON.parse(chunk.args)
110
+ args: parsed
92
111
  });
93
- } catch {
94
112
  }
95
113
  return { ...state, toolResults: newResults };
96
114
  }
@@ -1529,7 +1547,8 @@ var AbstractChat = class {
1529
1547
  threadId: init.threadId,
1530
1548
  debug: init.debug,
1531
1549
  optimization: init.optimization,
1532
- yourgptConfig: init.yourgptConfig
1550
+ yourgptConfig: init.yourgptConfig,
1551
+ streamMode: init.streamMode
1533
1552
  };
1534
1553
  this.state = init.state ?? new SimpleChatState();
1535
1554
  this.transport = init.transport ?? new HttpTransport({
@@ -1755,6 +1774,12 @@ var AbstractChat = class {
1755
1774
  this.callbacks.onMessagesChange?.(this._allMessages());
1756
1775
  this.callbacks.onStatusChange?.("submitted");
1757
1776
  await new Promise((resolve) => setTimeout(resolve, 0));
1777
+ if (this.status === "ready" || this.status === "error") {
1778
+ this.debug(
1779
+ "Skipping processRequest \u2014 status reset during yield (stop was called)"
1780
+ );
1781
+ return;
1782
+ }
1758
1783
  await this.processRequest();
1759
1784
  } catch (error) {
1760
1785
  this.handleError(error);
@@ -2193,11 +2218,19 @@ ${this.dynamicContext}`.trim() : this.config.systemPrompt;
2193
2218
  if (existing) {
2194
2219
  assistantMessage = existing;
2195
2220
  } else {
2196
- assistantMessage = createEmptyAssistantMessage();
2221
+ const visibleMessages = this.state.messages;
2222
+ const currentLeafId = visibleMessages.length > 0 ? visibleMessages[visibleMessages.length - 1].id : void 0;
2223
+ assistantMessage = createEmptyAssistantMessage(void 0, {
2224
+ parentId: currentLeafId
2225
+ });
2197
2226
  this.state.pushMessage(assistantMessage);
2198
2227
  }
2199
2228
  } else {
2200
- assistantMessage = createEmptyAssistantMessage();
2229
+ const visibleMessages = this.state.messages;
2230
+ const currentLeafId = visibleMessages.length > 0 ? visibleMessages[visibleMessages.length - 1].id : void 0;
2231
+ assistantMessage = createEmptyAssistantMessage(void 0, {
2232
+ parentId: currentLeafId
2233
+ });
2201
2234
  this.state.pushMessage(assistantMessage);
2202
2235
  }
2203
2236
  this.streamState = createStreamState(assistantMessage.id);
@@ -2217,37 +2250,58 @@ ${this.dynamicContext}`.trim() : this.config.systemPrompt;
2217
2250
  this.handleError(error);
2218
2251
  return;
2219
2252
  }
2220
- if (chunk.type === "message:end" && this.streamState !== null && (this.streamState.content || (this.streamState.toolResults?.size ?? 0) > 0)) {
2221
- this.debug("message:end mid-stream", {
2222
- messageId: this.streamState.messageId,
2223
- contentLength: this.streamState.content.length,
2224
- toolCallsInState: this.streamState.toolCalls?.length ?? 0,
2225
- chunkCount
2226
- });
2227
- const turnMessage = streamStateToMessage(this.streamState);
2228
- const toolCallsHidden = {};
2229
- for (const [id, result] of this.streamState.toolResults) {
2230
- if (result.hidden !== void 0) {
2231
- toolCallsHidden[id] = result.hidden;
2253
+ if (chunk.type === "message:end" && this.streamState) {
2254
+ if (this.config.streamMode === "single-turn") {
2255
+ this.debug(
2256
+ "message:end mid-stream (single-turn: keeping streamState alive)",
2257
+ {
2258
+ messageId: this.streamState.messageId,
2259
+ contentLength: this.streamState.content.length,
2260
+ chunkCount
2261
+ }
2262
+ );
2263
+ continue;
2264
+ }
2265
+ if (!this.streamState.content && (this.streamState.toolResults?.size ?? 0) === 0) ; else {
2266
+ this.debug("message:end mid-stream", {
2267
+ messageId: this.streamState.messageId,
2268
+ contentLength: this.streamState.content.length,
2269
+ toolCallsInState: this.streamState.toolCalls?.length ?? 0,
2270
+ chunkCount
2271
+ });
2272
+ const turnMessage = streamStateToMessage(this.streamState);
2273
+ const toolCallsHidden = {};
2274
+ for (const [id, result] of this.streamState.toolResults) {
2275
+ if (result.hidden !== void 0) {
2276
+ toolCallsHidden[id] = result.hidden;
2277
+ }
2278
+ }
2279
+ if (turnMessage.toolCalls?.length && Object.keys(toolCallsHidden).length > 0) {
2280
+ turnMessage.metadata = {
2281
+ ...turnMessage.metadata,
2282
+ toolCallsHidden
2283
+ };
2232
2284
  }
2285
+ this.state.updateMessageById(
2286
+ this.streamState.messageId,
2287
+ (existing) => ({
2288
+ ...turnMessage,
2289
+ ...existing.parentId !== void 0 ? { parentId: existing.parentId } : {},
2290
+ ...existing.childrenIds !== void 0 ? { childrenIds: existing.childrenIds } : {}
2291
+ })
2292
+ );
2293
+ this.callbacks.onMessageFinish?.(turnMessage);
2294
+ this.streamState = null;
2295
+ continue;
2233
2296
  }
2234
- if (turnMessage.toolCalls?.length && Object.keys(toolCallsHidden).length > 0) {
2235
- turnMessage.metadata = {
2236
- ...turnMessage.metadata,
2237
- toolCallsHidden
2238
- };
2297
+ }
2298
+ if (chunk.type === "message:start" && this.streamState !== null) {
2299
+ if (this.config.streamMode === "single-turn") {
2300
+ this.debug(
2301
+ "message:start mid-stream (single-turn: streamState already active, skipping)"
2302
+ );
2303
+ continue;
2239
2304
  }
2240
- this.state.updateMessageById(
2241
- this.streamState.messageId,
2242
- (existing) => ({
2243
- ...turnMessage,
2244
- ...existing.parentId !== void 0 ? { parentId: existing.parentId } : {},
2245
- ...existing.childrenIds !== void 0 ? { childrenIds: existing.childrenIds } : {}
2246
- })
2247
- );
2248
- this.callbacks.onMessageFinish?.(turnMessage);
2249
- this.streamState = null;
2250
- continue;
2251
2305
  }
2252
2306
  if (chunk.type === "message:start" && this.streamState === null) {
2253
2307
  this.debug("message:start after mid-stream end - creating new message");
@@ -2262,6 +2316,45 @@ ${this.dynamicContext}`.trim() : this.config.systemPrompt;
2262
2316
  continue;
2263
2317
  }
2264
2318
  if (!this.streamState) {
2319
+ if (chunk.type === "action:start") {
2320
+ this.callbacks.onServerToolStart?.({
2321
+ id: chunk.id,
2322
+ name: chunk.name,
2323
+ hidden: chunk.hidden
2324
+ });
2325
+ continue;
2326
+ }
2327
+ if (chunk.type === "action:args") {
2328
+ let args = {};
2329
+ try {
2330
+ args = JSON.parse(chunk.args);
2331
+ } catch {
2332
+ try {
2333
+ const partial = chunk.args;
2334
+ if (partial && partial.startsWith("{")) {
2335
+ const extracted = {};
2336
+ const pairs = partial.matchAll(
2337
+ /"(\w+)"\s*:\s*"((?:[^"\\]|\\.)*)"/g
2338
+ );
2339
+ for (const m of pairs) extracted[m[1]] = m[2];
2340
+ const open = partial.match(/"(\w+)"\s*:\s*"((?:[^"\\]|\\.)*)$/);
2341
+ if (open) extracted[open[1]] = open[2];
2342
+ if (Object.keys(extracted).length > 0) args = extracted;
2343
+ }
2344
+ } catch {
2345
+ }
2346
+ }
2347
+ const execName = chunk.id;
2348
+ this.callbacks.onServerToolArgs?.({
2349
+ id: chunk.id,
2350
+ name: execName,
2351
+ args
2352
+ });
2353
+ continue;
2354
+ }
2355
+ if (chunk.type === "action:end") {
2356
+ continue;
2357
+ }
2265
2358
  if (chunk.type === "tool_calls") {
2266
2359
  pendingClientToolCalls = chunk.toolCalls;
2267
2360
  this.debug("tool_calls (post-message:end, stored as pending)", {
@@ -2284,6 +2377,8 @@ ${this.dynamicContext}`.trim() : this.config.systemPrompt;
2284
2377
  );
2285
2378
  const messagesToInsert = [];
2286
2379
  let clientAssistantToolCalls;
2380
+ const lastVisibleMsgs = this.state.messages;
2381
+ let postEndInsertParentId = lastVisibleMsgs.length > 0 ? lastVisibleMsgs[lastVisibleMsgs.length - 1].id : void 0;
2287
2382
  for (const msg of chunk.messages) {
2288
2383
  if (msg.role === "assistant" && msg.tool_calls?.length && pendingIds.size > 0 && msg.tool_calls.every(
2289
2384
  (tc) => pendingIds.has(tc?.id ?? "")
@@ -2298,14 +2393,17 @@ ${this.dynamicContext}`.trim() : this.config.systemPrompt;
2298
2393
  continue;
2299
2394
  if (msg.role === "tool" && msg.tool_call_id && pendingIds.has(msg.tool_call_id))
2300
2395
  continue;
2301
- messagesToInsert.push({
2396
+ const insertedMsg = {
2302
2397
  id: generateMessageId(),
2303
2398
  role: msg.role,
2304
2399
  content: msg.content ?? "",
2305
2400
  toolCalls: msg.tool_calls,
2306
2401
  toolCallId: msg.tool_call_id,
2307
- createdAt: /* @__PURE__ */ new Date()
2308
- });
2402
+ createdAt: /* @__PURE__ */ new Date(),
2403
+ ...postEndInsertParentId ? { parentId: postEndInsertParentId } : {}
2404
+ };
2405
+ postEndInsertParentId = insertedMsg.id;
2406
+ messagesToInsert.push(insertedMsg);
2309
2407
  }
2310
2408
  if (clientAssistantToolCalls) {
2311
2409
  const currentMessages = this.state.messages;
@@ -2323,7 +2421,7 @@ ${this.dynamicContext}`.trim() : this.config.systemPrompt;
2323
2421
  }
2324
2422
  }
2325
2423
  if (messagesToInsert.length > 0) {
2326
- const currentMessages = this.state.messages;
2424
+ const currentMessages = this._allMessages();
2327
2425
  let insertIdx = currentMessages.length;
2328
2426
  for (let i = currentMessages.length - 1; i >= 0; i--) {
2329
2427
  if (currentMessages[i].role === "assistant") {
@@ -2379,6 +2477,20 @@ ${this.dynamicContext}`.trim() : this.config.systemPrompt;
2379
2477
  try {
2380
2478
  args = JSON.parse(chunk.args);
2381
2479
  } catch {
2480
+ try {
2481
+ const partial = chunk.args;
2482
+ if (partial && partial.startsWith("{")) {
2483
+ const extracted = {};
2484
+ const pairs = partial.matchAll(
2485
+ /"(\w+)"\s*:\s*"((?:[^"\\]|\\.)*)"/g
2486
+ );
2487
+ for (const m of pairs) extracted[m[1]] = m[2];
2488
+ const open = partial.match(/"(\w+)"\s*:\s*"((?:[^"\\]|\\.)*)$/);
2489
+ if (open) extracted[open[1]] = open[2];
2490
+ if (Object.keys(extracted).length > 0) args = extracted;
2491
+ }
2492
+ } catch {
2493
+ }
2382
2494
  }
2383
2495
  const existingResult = this.streamState?.toolResults.get(chunk.id);
2384
2496
  if (existingResult) {
@@ -2449,10 +2561,21 @@ ${this.dynamicContext}`.trim() : this.config.systemPrompt;
2449
2561
  (m) => `${m.role}${m.tool_calls?.length ? `[${m.tool_calls.length}tc]` : ""}`
2450
2562
  )
2451
2563
  });
2452
- const currentStreamToolCallIds = new Set(
2453
- this.streamState?.toolCalls?.map((toolCall) => toolCall.id) ?? []
2454
- );
2564
+ const currentStreamToolCallIds = /* @__PURE__ */ new Set([
2565
+ ...this.streamState?.toolCalls?.map((toolCall) => toolCall.id) ?? [],
2566
+ ...this.config.streamMode === "single-turn" && this.streamState?.toolResults ? Array.from(this.streamState.toolResults.keys()) : []
2567
+ ]);
2455
2568
  const messagesToInsert = [];
2569
+ let insertChainParentId;
2570
+ if (this.config.streamMode === "single-turn" && this.streamState) {
2571
+ const allMsgs = this._allMessages();
2572
+ const streamIdx = allMsgs.findIndex(
2573
+ (m) => m.id === this.streamState.messageId
2574
+ );
2575
+ insertChainParentId = streamIdx > 0 ? allMsgs[streamIdx - 1].id : void 0;
2576
+ } else {
2577
+ insertChainParentId = this.streamState?.messageId;
2578
+ }
2456
2579
  const toolCallsHidden = {};
2457
2580
  if (this.streamState?.toolResults) {
2458
2581
  for (const [id, result] of this.streamState.toolResults) {
@@ -2465,6 +2588,12 @@ ${this.dynamicContext}`.trim() : this.config.systemPrompt;
2465
2588
  if (msg.role === "assistant" && !msg.tool_calls?.length) {
2466
2589
  continue;
2467
2590
  }
2591
+ if (this.config.streamMode === "single-turn" && msg.role === "assistant") {
2592
+ continue;
2593
+ }
2594
+ if (this.config.streamMode === "single-turn" && msg.role === "tool") {
2595
+ continue;
2596
+ }
2468
2597
  if (msg.role === "assistant" && msg.tool_calls?.length && msg.tool_calls.every(
2469
2598
  (toolCall) => currentStreamToolCallIds.has(toolCall.id)
2470
2599
  )) {
@@ -2481,12 +2610,14 @@ ${this.dynamicContext}`.trim() : this.config.systemPrompt;
2481
2610
  toolCalls: msg.tool_calls,
2482
2611
  toolCallId: msg.tool_call_id,
2483
2612
  createdAt: /* @__PURE__ */ new Date(),
2484
- metadata
2613
+ metadata,
2614
+ ...insertChainParentId ? { parentId: insertChainParentId } : {}
2485
2615
  };
2616
+ insertChainParentId = message.id;
2486
2617
  messagesToInsert.push(message);
2487
2618
  }
2488
2619
  if (messagesToInsert.length > 0) {
2489
- const currentMessages = this.state.messages;
2620
+ const currentMessages = this._allMessages();
2490
2621
  const currentStreamIndex = this.streamState ? currentMessages.findIndex(
2491
2622
  (message) => message.id === this.streamState.messageId
2492
2623
  ) : -1;
@@ -2903,7 +3034,6 @@ var AbstractAgentLoop = class {
2903
3034
  return [];
2904
3035
  }
2905
3036
  this.abortController = new AbortController();
2906
- this._isCancelled = false;
2907
3037
  this._isProcessing = true;
2908
3038
  this.setIteration(this._iteration + 1);
2909
3039
  const results = await Promise.all(
@@ -2926,17 +3056,28 @@ var AbstractAgentLoop = class {
2926
3056
  */
2927
3057
  async executeSingleTool(toolCall) {
2928
3058
  const tool = this.getTool(toolCall.name);
2929
- const execution = {
2930
- id: toolCall.id,
2931
- toolCallId: toolCall.id,
2932
- name: toolCall.name,
2933
- args: toolCall.args,
2934
- status: "pending",
2935
- approvalStatus: "none",
2936
- startedAt: /* @__PURE__ */ new Date(),
2937
- hidden: tool?.hidden
2938
- };
2939
- this.addToolExecution(execution);
3059
+ const existingExecution = this._toolExecutions.find(
3060
+ (e) => e.id === toolCall.id
3061
+ );
3062
+ let execution;
3063
+ if (existingExecution) {
3064
+ execution = existingExecution;
3065
+ this.updateToolExecution(toolCall.id, {
3066
+ args: toolCall.args
3067
+ });
3068
+ } else {
3069
+ execution = {
3070
+ id: toolCall.id,
3071
+ toolCallId: toolCall.id,
3072
+ name: toolCall.name,
3073
+ args: toolCall.args,
3074
+ status: "pending",
3075
+ approvalStatus: "none",
3076
+ startedAt: /* @__PURE__ */ new Date(),
3077
+ hidden: tool?.hidden
3078
+ };
3079
+ this.addToolExecution(execution);
3080
+ }
2940
3081
  this.callbacks.onToolStart?.(execution);
2941
3082
  if (!tool) {
2942
3083
  const errorResult = {
@@ -3541,6 +3682,7 @@ var ChatWithTools = class {
3541
3682
  onCreateSession: config.onCreateSession,
3542
3683
  yourgptConfig: config.yourgptConfig,
3543
3684
  debug: config.debug,
3685
+ streamMode: config.streamMode,
3544
3686
  initialMessages: config.initialMessages,
3545
3687
  state: config.state,
3546
3688
  transport: config.transport,
@@ -3581,7 +3723,8 @@ var ChatWithTools = class {
3581
3723
  (t) => t.name === info.name && t.location === "client"
3582
3724
  );
3583
3725
  if (isClientTool) {
3584
- this.debug("Skipping server tracking for client tool:", info.name);
3726
+ this.debug("Tracking client tool for streaming render:", info.name);
3727
+ this.agentLoop.addServerToolExecution(info);
3585
3728
  return;
3586
3729
  }
3587
3730
  this.debug("Server tool started:", info.name, {
@@ -3591,10 +3734,6 @@ var ChatWithTools = class {
3591
3734
  this.agentLoop.addServerToolExecution(info);
3592
3735
  },
3593
3736
  onServerToolArgs: (info) => {
3594
- const isClientTool = this.agentLoop.tools.some(
3595
- (t) => t.name === info.name && t.location === "client"
3596
- );
3597
- if (isClientTool) return;
3598
3737
  this.debug("Server tool args:", info.name, info.args);
3599
3738
  this.agentLoop.updateServerToolArgs(info.id, info.args ?? {});
3600
3739
  },
@@ -3642,6 +3781,10 @@ var ChatWithTools = class {
3642
3781
  try {
3643
3782
  const results = await this.agentLoop.executeToolCalls(toolCallInfos);
3644
3783
  this.debug("Tool results:", results);
3784
+ if (this.agentLoop.isCancelled) {
3785
+ this.debug("Skipping continueWithToolResults \u2014 loop was cancelled");
3786
+ return;
3787
+ }
3645
3788
  if (results.length > 0) {
3646
3789
  const toolResults = results.map((r) => ({
3647
3790
  toolCallId: r.toolCallId,
@@ -5085,7 +5228,7 @@ function useTools(tools) {
5085
5228
  const registeredToolsRef = React2.useRef([]);
5086
5229
  const toolsRef = React2.useRef(tools);
5087
5230
  toolsRef.current = tools;
5088
- const toolsKey = Object.keys(tools).sort().join(",");
5231
+ const toolsKey = Object.entries(tools).sort(([a], [b]) => a.localeCompare(b)).map(([name, def]) => `${name}:${def.available ?? true}`).join(",");
5089
5232
  React2.useEffect(() => {
5090
5233
  const currentTools = toolsRef.current;
5091
5234
  const toolNames = [];
@@ -5420,6 +5563,7 @@ function CopilotProvider(props) {
5420
5563
  onError,
5421
5564
  parseError,
5422
5565
  streaming,
5566
+ streamMode,
5423
5567
  headers,
5424
5568
  body,
5425
5569
  debug = false,
@@ -5482,6 +5626,7 @@ function CopilotProvider(props) {
5482
5626
  yourgptConfig,
5483
5627
  initialMessages: uiInitialMessages,
5484
5628
  streaming,
5629
+ streamMode,
5485
5630
  headers,
5486
5631
  body,
5487
5632
  parseError,
@@ -5984,5 +6129,5 @@ exports.useMessageHistoryContext = useMessageHistoryContext;
5984
6129
  exports.useSkillContext = useSkillContext;
5985
6130
  exports.useTool = useTool;
5986
6131
  exports.useTools = useTools;
5987
- //# sourceMappingURL=chunk-IDAQU3FP.cjs.map
5988
- //# sourceMappingURL=chunk-IDAQU3FP.cjs.map
6132
+ //# sourceMappingURL=chunk-TD7NF6OE.cjs.map
6133
+ //# sourceMappingURL=chunk-TD7NF6OE.cjs.map