@yourgpt/llm-sdk 2.5.1-beta.4 → 2.5.1-beta.6

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.
@@ -213,6 +213,12 @@ function toGeminiSchema(rf) {
213
213
  GEMINI_UNSUPPORTED_KEYS
214
214
  );
215
215
  }
216
+ function parameterToGeminiSchema(param) {
217
+ return stripSchemaKeys(
218
+ parameterToJsonSchema(param),
219
+ GEMINI_UNSUPPORTED_KEYS
220
+ );
221
+ }
216
222
  function toOllamaFormat(rf) {
217
223
  if (!rf) return void 0;
218
224
  if (rf.type === "json_object") return "json";
@@ -1188,11 +1194,7 @@ var AnthropicAdapter = class {
1188
1194
  properties: action.parameters ? Object.fromEntries(
1189
1195
  Object.entries(action.parameters).map(([key, param]) => [
1190
1196
  key,
1191
- {
1192
- type: param.type,
1193
- description: param.description,
1194
- enum: param.enum
1195
- }
1197
+ parameterToJsonSchema(param)
1196
1198
  ])
1197
1199
  ) : {},
1198
1200
  required: action.parameters ? Object.entries(action.parameters).filter(([, param]) => param.required).map(([key]) => key) : []
@@ -1828,11 +1830,7 @@ function formatToolsForGemini(actions) {
1828
1830
  properties: Object.fromEntries(
1829
1831
  Object.entries(action.parameters).map(([key, param]) => [
1830
1832
  key,
1831
- {
1832
- type: param.type,
1833
- description: param.description,
1834
- enum: param.enum
1835
- }
1833
+ parameterToGeminiSchema(param)
1836
1834
  ])
1837
1835
  ),
1838
1836
  required: Object.entries(action.parameters).filter(([, param]) => param.required).map(([key]) => key)
@@ -211,6 +211,12 @@ function toGeminiSchema(rf) {
211
211
  GEMINI_UNSUPPORTED_KEYS
212
212
  );
213
213
  }
214
+ function parameterToGeminiSchema(param) {
215
+ return stripSchemaKeys(
216
+ parameterToJsonSchema(param),
217
+ GEMINI_UNSUPPORTED_KEYS
218
+ );
219
+ }
214
220
  function toOllamaFormat(rf) {
215
221
  if (!rf) return void 0;
216
222
  if (rf.type === "json_object") return "json";
@@ -1186,11 +1192,7 @@ var AnthropicAdapter = class {
1186
1192
  properties: action.parameters ? Object.fromEntries(
1187
1193
  Object.entries(action.parameters).map(([key, param]) => [
1188
1194
  key,
1189
- {
1190
- type: param.type,
1191
- description: param.description,
1192
- enum: param.enum
1193
- }
1195
+ parameterToJsonSchema(param)
1194
1196
  ])
1195
1197
  ) : {},
1196
1198
  required: action.parameters ? Object.entries(action.parameters).filter(([, param]) => param.required).map(([key]) => key) : []
@@ -1826,11 +1828,7 @@ function formatToolsForGemini(actions) {
1826
1828
  properties: Object.fromEntries(
1827
1829
  Object.entries(action.parameters).map(([key, param]) => [
1828
1830
  key,
1829
- {
1830
- type: param.type,
1831
- description: param.description,
1832
- enum: param.enum
1833
- }
1831
+ parameterToGeminiSchema(param)
1834
1832
  ])
1835
1833
  ),
1836
1834
  required: Object.entries(action.parameters).filter(([, param]) => param.required).map(([key]) => key)
package/dist/index.js CHANGED
@@ -1052,6 +1052,14 @@ var StreamResult = class {
1052
1052
  }
1053
1053
  if (event.requiresAction) {
1054
1054
  collected.requiresAction = true;
1055
+ const resolvedToolIds = new Set(
1056
+ (event.messages ?? []).filter((m) => m.role === "tool" && m.tool_call_id).map((m) => m.tool_call_id)
1057
+ );
1058
+ if (resolvedToolIds.size > 0) {
1059
+ collected.toolCalls = collected.toolCalls.filter(
1060
+ (tc) => !resolvedToolIds.has(tc.id)
1061
+ );
1062
+ }
1055
1063
  }
1056
1064
  if (event.usage) {
1057
1065
  this.capturedUsage = event.usage;
@@ -2353,6 +2361,49 @@ var Runtime = class {
2353
2361
  const clientToolCalls = toolCalls.filter(
2354
2362
  (tc) => !serverToolIds.has(tc.id)
2355
2363
  );
2364
+ const serverToolResultMessages = serverToolResults.map((tr) => {
2365
+ const aiContent = buildToolResultForAI(tr.tool, tr.result, tr.args);
2366
+ const content = typeof aiContent === "string" ? aiContent : JSON.stringify(serializeToolResultContent(aiContent));
2367
+ return {
2368
+ role: "tool",
2369
+ content,
2370
+ tool_call_id: tr.id
2371
+ };
2372
+ });
2373
+ if (serverToolResults.length > 0 && clientToolCalls.length > 0) {
2374
+ if (debug) {
2375
+ console.log(
2376
+ `[Copilot SDK] Mixed turn: ${serverToolResults.length} server + ${clientToolCalls.length} client tool(s). Suspending for client tools.`
2377
+ );
2378
+ }
2379
+ const assistantMessage = {
2380
+ role: "assistant",
2381
+ content: accumulatedText || null,
2382
+ tool_calls: toolCalls.map((tc) => ({
2383
+ id: tc.id,
2384
+ type: "function",
2385
+ function: {
2386
+ name: tc.name,
2387
+ arguments: JSON.stringify(tc.args)
2388
+ },
2389
+ ...tc.extra_content ? { extra_content: tc.extra_content } : {}
2390
+ }))
2391
+ };
2392
+ newMessages.push(assistantMessage);
2393
+ newMessages.push(...serverToolResultMessages);
2394
+ yield {
2395
+ type: "tool_calls",
2396
+ toolCalls: clientToolCalls,
2397
+ assistantMessage
2398
+ };
2399
+ yield {
2400
+ type: "done",
2401
+ requiresAction: true,
2402
+ messages: newMessages,
2403
+ usage: adapterUsage
2404
+ };
2405
+ return;
2406
+ }
2356
2407
  if (serverToolResults.length > 0) {
2357
2408
  if (debug) {
2358
2409
  console.log(
@@ -2375,17 +2426,7 @@ var Runtime = class {
2375
2426
  };
2376
2427
  })
2377
2428
  };
2378
- const toolResultMessages = serverToolResults.map(
2379
- (tr) => {
2380
- const aiContent = buildToolResultForAI(tr.tool, tr.result, tr.args);
2381
- const content = typeof aiContent === "string" ? aiContent : JSON.stringify(serializeToolResultContent(aiContent));
2382
- return {
2383
- role: "tool",
2384
- content,
2385
- tool_call_id: tr.id
2386
- };
2387
- }
2388
- );
2429
+ const toolResultMessages = serverToolResultMessages;
2389
2430
  newMessages.push(assistantWithToolCalls);
2390
2431
  newMessages.push(...toolResultMessages);
2391
2432
  const messagesWithResults = [
@@ -2640,6 +2681,48 @@ var Runtime = class {
2640
2681
  }
2641
2682
  }
2642
2683
  }
2684
+ const serverToolResultMessages = serverToolResults.map((tr) => {
2685
+ const aiContent = buildToolResultForAI(
2686
+ tr.tool,
2687
+ tr.result,
2688
+ tr.args
2689
+ );
2690
+ const content = typeof aiContent === "string" ? aiContent : JSON.stringify(serializeToolResultContent(aiContent));
2691
+ return {
2692
+ role: "tool",
2693
+ content,
2694
+ tool_call_id: tr.id
2695
+ };
2696
+ });
2697
+ if (serverToolResults.length > 0 && clientToolCalls.length > 0) {
2698
+ const assistantMessage = {
2699
+ role: "assistant",
2700
+ content: result.content || null,
2701
+ tool_calls: result.toolCalls.map((tc) => ({
2702
+ id: tc.id,
2703
+ type: "function",
2704
+ function: {
2705
+ name: tc.name,
2706
+ arguments: JSON.stringify(tc.args)
2707
+ },
2708
+ ...tc.extra_content ? { extra_content: tc.extra_content } : {}
2709
+ }))
2710
+ };
2711
+ newMessages.push(assistantMessage);
2712
+ newMessages.push(...serverToolResultMessages);
2713
+ yield {
2714
+ type: "tool_calls",
2715
+ toolCalls: clientToolCalls,
2716
+ assistantMessage
2717
+ };
2718
+ yield {
2719
+ type: "done",
2720
+ requiresAction: true,
2721
+ messages: newMessages,
2722
+ usage: accumulatedUsage.total_tokens > 0 ? accumulatedUsage : void 0
2723
+ };
2724
+ return;
2725
+ }
2643
2726
  if (serverToolResults.length > 0) {
2644
2727
  const assistantWithToolCalls = {
2645
2728
  role: "assistant",
@@ -2654,19 +2737,7 @@ var Runtime = class {
2654
2737
  ...tc.extra_content ? { extra_content: tc.extra_content } : {}
2655
2738
  }))
2656
2739
  };
2657
- const toolResultMessages = serverToolResults.map((tr) => {
2658
- const aiContent = buildToolResultForAI(
2659
- tr.tool,
2660
- tr.result,
2661
- tr.args
2662
- );
2663
- const content = typeof aiContent === "string" ? aiContent : JSON.stringify(serializeToolResultContent(aiContent));
2664
- return {
2665
- role: "tool",
2666
- content,
2667
- tool_call_id: tr.id
2668
- };
2669
- });
2740
+ const toolResultMessages = serverToolResultMessages;
2670
2741
  newMessages.push(assistantWithToolCalls);
2671
2742
  newMessages.push(...toolResultMessages);
2672
2743
  conversationMessages = [
@@ -3005,10 +3076,23 @@ var Runtime = class {
3005
3076
  result: event.result || event.error
3006
3077
  });
3007
3078
  break;
3008
- case "done":
3079
+ case "done": {
3009
3080
  messages = event.messages || [];
3010
3081
  requiresAction = event.requiresAction || false;
3082
+ if (requiresAction) {
3083
+ const resolvedToolIds = new Set(
3084
+ messages.filter((m) => m.role === "tool" && m.tool_call_id).map((m) => m.tool_call_id)
3085
+ );
3086
+ if (resolvedToolIds.size > 0) {
3087
+ for (let i = toolCalls.length - 1; i >= 0; i--) {
3088
+ if (resolvedToolIds.has(toolCalls[i].id)) {
3089
+ toolCalls.splice(i, 1);
3090
+ }
3091
+ }
3092
+ }
3093
+ }
3011
3094
  break;
3095
+ }
3012
3096
  case "error":
3013
3097
  error = { message: event.message, code: event.code };
3014
3098
  break;
package/dist/index.mjs CHANGED
@@ -1050,6 +1050,14 @@ var StreamResult = class {
1050
1050
  }
1051
1051
  if (event.requiresAction) {
1052
1052
  collected.requiresAction = true;
1053
+ const resolvedToolIds = new Set(
1054
+ (event.messages ?? []).filter((m) => m.role === "tool" && m.tool_call_id).map((m) => m.tool_call_id)
1055
+ );
1056
+ if (resolvedToolIds.size > 0) {
1057
+ collected.toolCalls = collected.toolCalls.filter(
1058
+ (tc) => !resolvedToolIds.has(tc.id)
1059
+ );
1060
+ }
1053
1061
  }
1054
1062
  if (event.usage) {
1055
1063
  this.capturedUsage = event.usage;
@@ -2351,6 +2359,49 @@ var Runtime = class {
2351
2359
  const clientToolCalls = toolCalls.filter(
2352
2360
  (tc) => !serverToolIds.has(tc.id)
2353
2361
  );
2362
+ const serverToolResultMessages = serverToolResults.map((tr) => {
2363
+ const aiContent = buildToolResultForAI(tr.tool, tr.result, tr.args);
2364
+ const content = typeof aiContent === "string" ? aiContent : JSON.stringify(serializeToolResultContent(aiContent));
2365
+ return {
2366
+ role: "tool",
2367
+ content,
2368
+ tool_call_id: tr.id
2369
+ };
2370
+ });
2371
+ if (serverToolResults.length > 0 && clientToolCalls.length > 0) {
2372
+ if (debug) {
2373
+ console.log(
2374
+ `[Copilot SDK] Mixed turn: ${serverToolResults.length} server + ${clientToolCalls.length} client tool(s). Suspending for client tools.`
2375
+ );
2376
+ }
2377
+ const assistantMessage = {
2378
+ role: "assistant",
2379
+ content: accumulatedText || null,
2380
+ tool_calls: toolCalls.map((tc) => ({
2381
+ id: tc.id,
2382
+ type: "function",
2383
+ function: {
2384
+ name: tc.name,
2385
+ arguments: JSON.stringify(tc.args)
2386
+ },
2387
+ ...tc.extra_content ? { extra_content: tc.extra_content } : {}
2388
+ }))
2389
+ };
2390
+ newMessages.push(assistantMessage);
2391
+ newMessages.push(...serverToolResultMessages);
2392
+ yield {
2393
+ type: "tool_calls",
2394
+ toolCalls: clientToolCalls,
2395
+ assistantMessage
2396
+ };
2397
+ yield {
2398
+ type: "done",
2399
+ requiresAction: true,
2400
+ messages: newMessages,
2401
+ usage: adapterUsage
2402
+ };
2403
+ return;
2404
+ }
2354
2405
  if (serverToolResults.length > 0) {
2355
2406
  if (debug) {
2356
2407
  console.log(
@@ -2373,17 +2424,7 @@ var Runtime = class {
2373
2424
  };
2374
2425
  })
2375
2426
  };
2376
- const toolResultMessages = serverToolResults.map(
2377
- (tr) => {
2378
- const aiContent = buildToolResultForAI(tr.tool, tr.result, tr.args);
2379
- const content = typeof aiContent === "string" ? aiContent : JSON.stringify(serializeToolResultContent(aiContent));
2380
- return {
2381
- role: "tool",
2382
- content,
2383
- tool_call_id: tr.id
2384
- };
2385
- }
2386
- );
2427
+ const toolResultMessages = serverToolResultMessages;
2387
2428
  newMessages.push(assistantWithToolCalls);
2388
2429
  newMessages.push(...toolResultMessages);
2389
2430
  const messagesWithResults = [
@@ -2638,6 +2679,48 @@ var Runtime = class {
2638
2679
  }
2639
2680
  }
2640
2681
  }
2682
+ const serverToolResultMessages = serverToolResults.map((tr) => {
2683
+ const aiContent = buildToolResultForAI(
2684
+ tr.tool,
2685
+ tr.result,
2686
+ tr.args
2687
+ );
2688
+ const content = typeof aiContent === "string" ? aiContent : JSON.stringify(serializeToolResultContent(aiContent));
2689
+ return {
2690
+ role: "tool",
2691
+ content,
2692
+ tool_call_id: tr.id
2693
+ };
2694
+ });
2695
+ if (serverToolResults.length > 0 && clientToolCalls.length > 0) {
2696
+ const assistantMessage = {
2697
+ role: "assistant",
2698
+ content: result.content || null,
2699
+ tool_calls: result.toolCalls.map((tc) => ({
2700
+ id: tc.id,
2701
+ type: "function",
2702
+ function: {
2703
+ name: tc.name,
2704
+ arguments: JSON.stringify(tc.args)
2705
+ },
2706
+ ...tc.extra_content ? { extra_content: tc.extra_content } : {}
2707
+ }))
2708
+ };
2709
+ newMessages.push(assistantMessage);
2710
+ newMessages.push(...serverToolResultMessages);
2711
+ yield {
2712
+ type: "tool_calls",
2713
+ toolCalls: clientToolCalls,
2714
+ assistantMessage
2715
+ };
2716
+ yield {
2717
+ type: "done",
2718
+ requiresAction: true,
2719
+ messages: newMessages,
2720
+ usage: accumulatedUsage.total_tokens > 0 ? accumulatedUsage : void 0
2721
+ };
2722
+ return;
2723
+ }
2641
2724
  if (serverToolResults.length > 0) {
2642
2725
  const assistantWithToolCalls = {
2643
2726
  role: "assistant",
@@ -2652,19 +2735,7 @@ var Runtime = class {
2652
2735
  ...tc.extra_content ? { extra_content: tc.extra_content } : {}
2653
2736
  }))
2654
2737
  };
2655
- const toolResultMessages = serverToolResults.map((tr) => {
2656
- const aiContent = buildToolResultForAI(
2657
- tr.tool,
2658
- tr.result,
2659
- tr.args
2660
- );
2661
- const content = typeof aiContent === "string" ? aiContent : JSON.stringify(serializeToolResultContent(aiContent));
2662
- return {
2663
- role: "tool",
2664
- content,
2665
- tool_call_id: tr.id
2666
- };
2667
- });
2738
+ const toolResultMessages = serverToolResultMessages;
2668
2739
  newMessages.push(assistantWithToolCalls);
2669
2740
  newMessages.push(...toolResultMessages);
2670
2741
  conversationMessages = [
@@ -3003,10 +3074,23 @@ var Runtime = class {
3003
3074
  result: event.result || event.error
3004
3075
  });
3005
3076
  break;
3006
- case "done":
3077
+ case "done": {
3007
3078
  messages = event.messages || [];
3008
3079
  requiresAction = event.requiresAction || false;
3080
+ if (requiresAction) {
3081
+ const resolvedToolIds = new Set(
3082
+ messages.filter((m) => m.role === "tool" && m.tool_call_id).map((m) => m.tool_call_id)
3083
+ );
3084
+ if (resolvedToolIds.size > 0) {
3085
+ for (let i = toolCalls.length - 1; i >= 0; i--) {
3086
+ if (resolvedToolIds.has(toolCalls[i].id)) {
3087
+ toolCalls.splice(i, 1);
3088
+ }
3089
+ }
3090
+ }
3091
+ }
3009
3092
  break;
3093
+ }
3010
3094
  case "error":
3011
3095
  error = { message: event.message, code: event.code };
3012
3096
  break;
@@ -39,6 +39,34 @@ ${stringifyForDebug(payload)}`
39
39
  );
40
40
  }
41
41
  }
42
+ function parameterToJsonSchema(param) {
43
+ const schema = {
44
+ type: param.type
45
+ };
46
+ if (param.description) {
47
+ schema.description = param.description;
48
+ }
49
+ if (param.enum) {
50
+ schema.enum = param.enum;
51
+ }
52
+ if (param.type === "array" && param.items) {
53
+ schema.items = parameterToJsonSchema(
54
+ param.items
55
+ );
56
+ }
57
+ if (param.type === "object" && param.properties) {
58
+ schema.properties = Object.fromEntries(
59
+ Object.entries(param.properties).map(([key, prop]) => [
60
+ key,
61
+ parameterToJsonSchema(
62
+ prop
63
+ )
64
+ ])
65
+ );
66
+ schema.additionalProperties = false;
67
+ }
68
+ return schema;
69
+ }
42
70
  function stripSchemaKeys(schema, keysToDrop, options = {}) {
43
71
  if (Array.isArray(schema)) {
44
72
  return schema.map((item) => stripSchemaKeys(item, keysToDrop, options));
@@ -863,11 +891,7 @@ var AnthropicAdapter = class {
863
891
  properties: action.parameters ? Object.fromEntries(
864
892
  Object.entries(action.parameters).map(([key, param]) => [
865
893
  key,
866
- {
867
- type: param.type,
868
- description: param.description,
869
- enum: param.enum
870
- }
894
+ parameterToJsonSchema(param)
871
895
  ])
872
896
  ) : {},
873
897
  required: action.parameters ? Object.entries(action.parameters).filter(([, param]) => param.required).map(([key]) => key) : []
@@ -37,6 +37,34 @@ ${stringifyForDebug(payload)}`
37
37
  );
38
38
  }
39
39
  }
40
+ function parameterToJsonSchema(param) {
41
+ const schema = {
42
+ type: param.type
43
+ };
44
+ if (param.description) {
45
+ schema.description = param.description;
46
+ }
47
+ if (param.enum) {
48
+ schema.enum = param.enum;
49
+ }
50
+ if (param.type === "array" && param.items) {
51
+ schema.items = parameterToJsonSchema(
52
+ param.items
53
+ );
54
+ }
55
+ if (param.type === "object" && param.properties) {
56
+ schema.properties = Object.fromEntries(
57
+ Object.entries(param.properties).map(([key, prop]) => [
58
+ key,
59
+ parameterToJsonSchema(
60
+ prop
61
+ )
62
+ ])
63
+ );
64
+ schema.additionalProperties = false;
65
+ }
66
+ return schema;
67
+ }
40
68
  function stripSchemaKeys(schema, keysToDrop, options = {}) {
41
69
  if (Array.isArray(schema)) {
42
70
  return schema.map((item) => stripSchemaKeys(item, keysToDrop, options));
@@ -861,11 +889,7 @@ var AnthropicAdapter = class {
861
889
  properties: action.parameters ? Object.fromEntries(
862
890
  Object.entries(action.parameters).map(([key, param]) => [
863
891
  key,
864
- {
865
- type: param.type,
866
- description: param.description,
867
- enum: param.enum
868
- }
892
+ parameterToJsonSchema(param)
869
893
  ])
870
894
  ) : {},
871
895
  required: action.parameters ? Object.entries(action.parameters).filter(([, param]) => param.required).map(([key]) => key) : []
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yourgpt/llm-sdk",
3
- "version": "2.5.1-beta.4",
3
+ "version": "2.5.1-beta.6",
4
4
  "description": "AI SDK for building AI Agents with any LLM",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",