@anuma/sdk 3.11.0 → 3.11.2

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.
@@ -9268,6 +9268,9 @@ var CompletionsStrategy = class {
9268
9268
  }
9269
9269
  }
9270
9270
  }
9271
+ if (choice.finish_reason) {
9272
+ accumulator.finishReason = choice.finish_reason;
9273
+ }
9271
9274
  if (choice.finish_reason === "tool_calls" || choice.finish_reason === "stop") {
9272
9275
  if (accumulator.toolCalls.size > 0) {
9273
9276
  accumulator.content = mergeXaiInlineParameterTags(
@@ -9350,7 +9353,9 @@ var CompletionsStrategy = class {
9350
9353
  content: finalContent,
9351
9354
  ...toolCalls && { tool_calls: toolCalls }
9352
9355
  },
9353
- finish_reason: toolCalls ? "tool_calls" : "stop"
9356
+ // Prefer what the provider actually said; fall back to the derived
9357
+ // value only when the stream carried no finish_reason at all.
9358
+ finish_reason: accumulator.finishReason ?? (toolCalls ? "tool_calls" : "stop")
9354
9359
  }
9355
9360
  ],
9356
9361
  ...usage && { usage },
@@ -10021,7 +10026,7 @@ var ResponsesStrategy = class {
10021
10026
  }
10022
10027
  return result;
10023
10028
  }
10024
- if (typedChunk.type === "response.completed") {
10029
+ if (typedChunk.type === "response.completed" || typedChunk.type === "response.incomplete") {
10025
10030
  if (typedChunk.response?.usage) {
10026
10031
  const u = typedChunk.response.usage;
10027
10032
  const promptTokens = u.input_tokens ?? u.prompt_tokens ?? 0;
@@ -10037,6 +10042,11 @@ var ResponsesStrategy = class {
10037
10042
  ...creditsExhausted !== void 0 && { credits_exhausted: creditsExhausted }
10038
10043
  };
10039
10044
  }
10045
+ const resp = typedChunk.response;
10046
+ const looksIncomplete = typedChunk.type === "response.incomplete" || resp?.status === "incomplete";
10047
+ if (looksIncomplete && resp?.incomplete_details?.reason === "max_output_tokens") {
10048
+ accumulator.finishReason = "length";
10049
+ }
10040
10050
  if (typedChunk.response?.tools_checksum && !accumulator.toolsChecksum) {
10041
10051
  accumulator.toolsChecksum = typedChunk.response.tools_checksum;
10042
10052
  }
@@ -11573,7 +11583,17 @@ Executing tool: ${toolInfo}
11573
11583
  flushDeAnon();
11574
11584
  currentAccumulator.content += tip;
11575
11585
  }
11586
+ const truncatedToNothing = (acc) => acc.finishReason === "length" && acc.toolCalls.size === 0 && acc.content.trim() === "";
11587
+ const TRUNCATION_ERROR = "Model response was truncated at the output-token limit before it produced any usable content or tool call. Retry with a higher `maxOutputTokens`, or prompt for fewer/smaller tool calls per turn.";
11576
11588
  if (toolIteration > 0) {
11589
+ if (truncatedToNothing(currentAccumulator)) {
11590
+ await fireRunError({ error: TRUNCATION_ERROR, stage: "model" });
11591
+ return {
11592
+ data: buildResponseFinal(currentAccumulator),
11593
+ error: TRUNCATION_ERROR,
11594
+ toolsChecksum: currentAccumulator.toolsChecksum
11595
+ };
11596
+ }
11577
11597
  const finalResponse = buildResponseFinal(currentAccumulator);
11578
11598
  if (onFinish) onFinish(finalResponse);
11579
11599
  await fireRunEnd({
@@ -11587,6 +11607,14 @@ Executing tool: ${toolInfo}
11587
11607
  autoExecutedToolResults: accumulatedToolResults
11588
11608
  };
11589
11609
  }
11610
+ if (truncatedToNothing(accumulator)) {
11611
+ await fireRunError({ error: TRUNCATION_ERROR, stage: "model" });
11612
+ return {
11613
+ data: response,
11614
+ error: TRUNCATION_ERROR,
11615
+ toolsChecksum: accumulator.toolsChecksum
11616
+ };
11617
+ }
11590
11618
  if (onFinish) onFinish(response);
11591
11619
  await fireRunEnd({
11592
11620
  finalContent: finalContentText(accumulator),
@@ -1069,6 +1069,9 @@ var CompletionsStrategy = class {
1069
1069
  }
1070
1070
  }
1071
1071
  }
1072
+ if (choice.finish_reason) {
1073
+ accumulator.finishReason = choice.finish_reason;
1074
+ }
1072
1075
  if (choice.finish_reason === "tool_calls" || choice.finish_reason === "stop") {
1073
1076
  if (accumulator.toolCalls.size > 0) {
1074
1077
  accumulator.content = mergeXaiInlineParameterTags(
@@ -1151,7 +1154,9 @@ var CompletionsStrategy = class {
1151
1154
  content: finalContent,
1152
1155
  ...toolCalls && { tool_calls: toolCalls }
1153
1156
  },
1154
- finish_reason: toolCalls ? "tool_calls" : "stop"
1157
+ // Prefer what the provider actually said; fall back to the derived
1158
+ // value only when the stream carried no finish_reason at all.
1159
+ finish_reason: accumulator.finishReason ?? (toolCalls ? "tool_calls" : "stop")
1155
1160
  }
1156
1161
  ],
1157
1162
  ...usage && { usage },
@@ -1822,7 +1827,7 @@ var ResponsesStrategy = class {
1822
1827
  }
1823
1828
  return result;
1824
1829
  }
1825
- if (typedChunk.type === "response.completed") {
1830
+ if (typedChunk.type === "response.completed" || typedChunk.type === "response.incomplete") {
1826
1831
  if (typedChunk.response?.usage) {
1827
1832
  const u = typedChunk.response.usage;
1828
1833
  const promptTokens = u.input_tokens ?? u.prompt_tokens ?? 0;
@@ -1838,6 +1843,11 @@ var ResponsesStrategy = class {
1838
1843
  ...creditsExhausted !== void 0 && { credits_exhausted: creditsExhausted }
1839
1844
  };
1840
1845
  }
1846
+ const resp = typedChunk.response;
1847
+ const looksIncomplete = typedChunk.type === "response.incomplete" || resp?.status === "incomplete";
1848
+ if (looksIncomplete && resp?.incomplete_details?.reason === "max_output_tokens") {
1849
+ accumulator.finishReason = "length";
1850
+ }
1841
1851
  if (typedChunk.response?.tools_checksum && !accumulator.toolsChecksum) {
1842
1852
  accumulator.toolsChecksum = typedChunk.response.tools_checksum;
1843
1853
  }
@@ -3374,7 +3384,17 @@ Executing tool: ${toolInfo}
3374
3384
  flushDeAnon();
3375
3385
  currentAccumulator.content += tip;
3376
3386
  }
3387
+ const truncatedToNothing = (acc) => acc.finishReason === "length" && acc.toolCalls.size === 0 && acc.content.trim() === "";
3388
+ const TRUNCATION_ERROR = "Model response was truncated at the output-token limit before it produced any usable content or tool call. Retry with a higher `maxOutputTokens`, or prompt for fewer/smaller tool calls per turn.";
3377
3389
  if (toolIteration > 0) {
3390
+ if (truncatedToNothing(currentAccumulator)) {
3391
+ await fireRunError({ error: TRUNCATION_ERROR, stage: "model" });
3392
+ return {
3393
+ data: buildResponseFinal(currentAccumulator),
3394
+ error: TRUNCATION_ERROR,
3395
+ toolsChecksum: currentAccumulator.toolsChecksum
3396
+ };
3397
+ }
3378
3398
  const finalResponse = buildResponseFinal(currentAccumulator);
3379
3399
  if (onFinish) onFinish(finalResponse);
3380
3400
  await fireRunEnd({
@@ -3388,6 +3408,14 @@ Executing tool: ${toolInfo}
3388
3408
  autoExecutedToolResults: accumulatedToolResults
3389
3409
  };
3390
3410
  }
3411
+ if (truncatedToNothing(accumulator)) {
3412
+ await fireRunError({ error: TRUNCATION_ERROR, stage: "model" });
3413
+ return {
3414
+ data: response,
3415
+ error: TRUNCATION_ERROR,
3416
+ toolsChecksum: accumulator.toolsChecksum
3417
+ };
3418
+ }
3391
3419
  if (onFinish) onFinish(response);
3392
3420
  await fireRunEnd({
3393
3421
  finalContent: finalContentText(accumulator),
@@ -9646,6 +9646,9 @@ var CompletionsStrategy = class {
9646
9646
  }
9647
9647
  }
9648
9648
  }
9649
+ if (choice.finish_reason) {
9650
+ accumulator.finishReason = choice.finish_reason;
9651
+ }
9649
9652
  if (choice.finish_reason === "tool_calls" || choice.finish_reason === "stop") {
9650
9653
  if (accumulator.toolCalls.size > 0) {
9651
9654
  accumulator.content = mergeXaiInlineParameterTags(
@@ -9728,7 +9731,9 @@ var CompletionsStrategy = class {
9728
9731
  content: finalContent,
9729
9732
  ...toolCalls && { tool_calls: toolCalls }
9730
9733
  },
9731
- finish_reason: toolCalls ? "tool_calls" : "stop"
9734
+ // Prefer what the provider actually said; fall back to the derived
9735
+ // value only when the stream carried no finish_reason at all.
9736
+ finish_reason: accumulator.finishReason ?? (toolCalls ? "tool_calls" : "stop")
9732
9737
  }
9733
9738
  ],
9734
9739
  ...usage && { usage },
@@ -10399,7 +10404,7 @@ var ResponsesStrategy = class {
10399
10404
  }
10400
10405
  return result;
10401
10406
  }
10402
- if (typedChunk.type === "response.completed") {
10407
+ if (typedChunk.type === "response.completed" || typedChunk.type === "response.incomplete") {
10403
10408
  if (typedChunk.response?.usage) {
10404
10409
  const u = typedChunk.response.usage;
10405
10410
  const promptTokens = u.input_tokens ?? u.prompt_tokens ?? 0;
@@ -10415,6 +10420,11 @@ var ResponsesStrategy = class {
10415
10420
  ...creditsExhausted !== void 0 && { credits_exhausted: creditsExhausted }
10416
10421
  };
10417
10422
  }
10423
+ const resp = typedChunk.response;
10424
+ const looksIncomplete = typedChunk.type === "response.incomplete" || resp?.status === "incomplete";
10425
+ if (looksIncomplete && resp?.incomplete_details?.reason === "max_output_tokens") {
10426
+ accumulator.finishReason = "length";
10427
+ }
10418
10428
  if (typedChunk.response?.tools_checksum && !accumulator.toolsChecksum) {
10419
10429
  accumulator.toolsChecksum = typedChunk.response.tools_checksum;
10420
10430
  }
@@ -11951,7 +11961,17 @@ Executing tool: ${toolInfo}
11951
11961
  flushDeAnon();
11952
11962
  currentAccumulator.content += tip;
11953
11963
  }
11964
+ const truncatedToNothing = (acc) => acc.finishReason === "length" && acc.toolCalls.size === 0 && acc.content.trim() === "";
11965
+ const TRUNCATION_ERROR = "Model response was truncated at the output-token limit before it produced any usable content or tool call. Retry with a higher `maxOutputTokens`, or prompt for fewer/smaller tool calls per turn.";
11954
11966
  if (toolIteration > 0) {
11967
+ if (truncatedToNothing(currentAccumulator)) {
11968
+ await fireRunError({ error: TRUNCATION_ERROR, stage: "model" });
11969
+ return {
11970
+ data: buildResponseFinal(currentAccumulator),
11971
+ error: TRUNCATION_ERROR,
11972
+ toolsChecksum: currentAccumulator.toolsChecksum
11973
+ };
11974
+ }
11955
11975
  const finalResponse = buildResponseFinal(currentAccumulator);
11956
11976
  if (onFinish) onFinish(finalResponse);
11957
11977
  await fireRunEnd({
@@ -11965,6 +11985,14 @@ Executing tool: ${toolInfo}
11965
11985
  autoExecutedToolResults: accumulatedToolResults
11966
11986
  };
11967
11987
  }
11988
+ if (truncatedToNothing(accumulator)) {
11989
+ await fireRunError({ error: TRUNCATION_ERROR, stage: "model" });
11990
+ return {
11991
+ data: response,
11992
+ error: TRUNCATION_ERROR,
11993
+ toolsChecksum: accumulator.toolsChecksum
11994
+ };
11995
+ }
11968
11996
  if (onFinish) onFinish(response);
11969
11997
  await fireRunEnd({
11970
11998
  finalContent: finalContentText(accumulator),
@@ -946,6 +946,9 @@ var CompletionsStrategy = class {
946
946
  }
947
947
  }
948
948
  }
949
+ if (choice.finish_reason) {
950
+ accumulator.finishReason = choice.finish_reason;
951
+ }
949
952
  if (choice.finish_reason === "tool_calls" || choice.finish_reason === "stop") {
950
953
  if (accumulator.toolCalls.size > 0) {
951
954
  accumulator.content = mergeXaiInlineParameterTags(
@@ -1028,7 +1031,9 @@ var CompletionsStrategy = class {
1028
1031
  content: finalContent,
1029
1032
  ...toolCalls && { tool_calls: toolCalls }
1030
1033
  },
1031
- finish_reason: toolCalls ? "tool_calls" : "stop"
1034
+ // Prefer what the provider actually said; fall back to the derived
1035
+ // value only when the stream carried no finish_reason at all.
1036
+ finish_reason: accumulator.finishReason ?? (toolCalls ? "tool_calls" : "stop")
1032
1037
  }
1033
1038
  ],
1034
1039
  ...usage && { usage },
@@ -1699,7 +1704,7 @@ var ResponsesStrategy = class {
1699
1704
  }
1700
1705
  return result;
1701
1706
  }
1702
- if (typedChunk.type === "response.completed") {
1707
+ if (typedChunk.type === "response.completed" || typedChunk.type === "response.incomplete") {
1703
1708
  if (typedChunk.response?.usage) {
1704
1709
  const u = typedChunk.response.usage;
1705
1710
  const promptTokens = u.input_tokens ?? u.prompt_tokens ?? 0;
@@ -1715,6 +1720,11 @@ var ResponsesStrategy = class {
1715
1720
  ...creditsExhausted !== void 0 && { credits_exhausted: creditsExhausted }
1716
1721
  };
1717
1722
  }
1723
+ const resp = typedChunk.response;
1724
+ const looksIncomplete = typedChunk.type === "response.incomplete" || resp?.status === "incomplete";
1725
+ if (looksIncomplete && resp?.incomplete_details?.reason === "max_output_tokens") {
1726
+ accumulator.finishReason = "length";
1727
+ }
1718
1728
  if (typedChunk.response?.tools_checksum && !accumulator.toolsChecksum) {
1719
1729
  accumulator.toolsChecksum = typedChunk.response.tools_checksum;
1720
1730
  }
@@ -3251,7 +3261,17 @@ Executing tool: ${toolInfo}
3251
3261
  flushDeAnon();
3252
3262
  currentAccumulator.content += tip;
3253
3263
  }
3264
+ const truncatedToNothing = (acc) => acc.finishReason === "length" && acc.toolCalls.size === 0 && acc.content.trim() === "";
3265
+ const TRUNCATION_ERROR = "Model response was truncated at the output-token limit before it produced any usable content or tool call. Retry with a higher `maxOutputTokens`, or prompt for fewer/smaller tool calls per turn.";
3254
3266
  if (toolIteration > 0) {
3267
+ if (truncatedToNothing(currentAccumulator)) {
3268
+ await fireRunError({ error: TRUNCATION_ERROR, stage: "model" });
3269
+ return {
3270
+ data: buildResponseFinal(currentAccumulator),
3271
+ error: TRUNCATION_ERROR,
3272
+ toolsChecksum: currentAccumulator.toolsChecksum
3273
+ };
3274
+ }
3255
3275
  const finalResponse = buildResponseFinal(currentAccumulator);
3256
3276
  if (onFinish) onFinish(finalResponse);
3257
3277
  await fireRunEnd({
@@ -3265,6 +3285,14 @@ Executing tool: ${toolInfo}
3265
3285
  autoExecutedToolResults: accumulatedToolResults
3266
3286
  };
3267
3287
  }
3288
+ if (truncatedToNothing(accumulator)) {
3289
+ await fireRunError({ error: TRUNCATION_ERROR, stage: "model" });
3290
+ return {
3291
+ data: response,
3292
+ error: TRUNCATION_ERROR,
3293
+ toolsChecksum: accumulator.toolsChecksum
3294
+ };
3295
+ }
3268
3296
  if (onFinish) onFinish(response);
3269
3297
  await fireRunEnd({
3270
3298
  finalContent: finalContentText(accumulator),
@@ -32749,6 +32749,9 @@ var CompletionsStrategy = class {
32749
32749
  }
32750
32750
  }
32751
32751
  }
32752
+ if (choice.finish_reason) {
32753
+ accumulator.finishReason = choice.finish_reason;
32754
+ }
32752
32755
  if (choice.finish_reason === "tool_calls" || choice.finish_reason === "stop") {
32753
32756
  if (accumulator.toolCalls.size > 0) {
32754
32757
  accumulator.content = mergeXaiInlineParameterTags(
@@ -32831,7 +32834,9 @@ var CompletionsStrategy = class {
32831
32834
  content: finalContent,
32832
32835
  ...toolCalls && { tool_calls: toolCalls }
32833
32836
  },
32834
- finish_reason: toolCalls ? "tool_calls" : "stop"
32837
+ // Prefer what the provider actually said; fall back to the derived
32838
+ // value only when the stream carried no finish_reason at all.
32839
+ finish_reason: accumulator.finishReason ?? (toolCalls ? "tool_calls" : "stop")
32835
32840
  }
32836
32841
  ],
32837
32842
  ...usage && { usage },
@@ -33502,7 +33507,7 @@ var ResponsesStrategy = class {
33502
33507
  }
33503
33508
  return result;
33504
33509
  }
33505
- if (typedChunk.type === "response.completed") {
33510
+ if (typedChunk.type === "response.completed" || typedChunk.type === "response.incomplete") {
33506
33511
  if (typedChunk.response?.usage) {
33507
33512
  const u = typedChunk.response.usage;
33508
33513
  const promptTokens = u.input_tokens ?? u.prompt_tokens ?? 0;
@@ -33518,6 +33523,11 @@ var ResponsesStrategy = class {
33518
33523
  ...creditsExhausted !== void 0 && { credits_exhausted: creditsExhausted }
33519
33524
  };
33520
33525
  }
33526
+ const resp = typedChunk.response;
33527
+ const looksIncomplete = typedChunk.type === "response.incomplete" || resp?.status === "incomplete";
33528
+ if (looksIncomplete && resp?.incomplete_details?.reason === "max_output_tokens") {
33529
+ accumulator.finishReason = "length";
33530
+ }
33521
33531
  if (typedChunk.response?.tools_checksum && !accumulator.toolsChecksum) {
33522
33532
  accumulator.toolsChecksum = typedChunk.response.tools_checksum;
33523
33533
  }
@@ -35054,7 +35064,17 @@ Executing tool: ${toolInfo}
35054
35064
  flushDeAnon();
35055
35065
  currentAccumulator.content += tip;
35056
35066
  }
35067
+ const truncatedToNothing = (acc) => acc.finishReason === "length" && acc.toolCalls.size === 0 && acc.content.trim() === "";
35068
+ const TRUNCATION_ERROR = "Model response was truncated at the output-token limit before it produced any usable content or tool call. Retry with a higher `maxOutputTokens`, or prompt for fewer/smaller tool calls per turn.";
35057
35069
  if (toolIteration > 0) {
35070
+ if (truncatedToNothing(currentAccumulator)) {
35071
+ await fireRunError({ error: TRUNCATION_ERROR, stage: "model" });
35072
+ return {
35073
+ data: buildResponseFinal(currentAccumulator),
35074
+ error: TRUNCATION_ERROR,
35075
+ toolsChecksum: currentAccumulator.toolsChecksum
35076
+ };
35077
+ }
35058
35078
  const finalResponse = buildResponseFinal(currentAccumulator);
35059
35079
  if (onFinish) onFinish(finalResponse);
35060
35080
  await fireRunEnd({
@@ -35068,6 +35088,14 @@ Executing tool: ${toolInfo}
35068
35088
  autoExecutedToolResults: accumulatedToolResults
35069
35089
  };
35070
35090
  }
35091
+ if (truncatedToNothing(accumulator)) {
35092
+ await fireRunError({ error: TRUNCATION_ERROR, stage: "model" });
35093
+ return {
35094
+ data: response,
35095
+ error: TRUNCATION_ERROR,
35096
+ toolsChecksum: accumulator.toolsChecksum
35097
+ };
35098
+ }
35071
35099
  if (onFinish) onFinish(response);
35072
35100
  await fireRunEnd({
35073
35101
  finalContent: finalContentText(accumulator),
@@ -10175,6 +10175,9 @@ var CompletionsStrategy = class {
10175
10175
  }
10176
10176
  }
10177
10177
  }
10178
+ if (choice.finish_reason) {
10179
+ accumulator.finishReason = choice.finish_reason;
10180
+ }
10178
10181
  if (choice.finish_reason === "tool_calls" || choice.finish_reason === "stop") {
10179
10182
  if (accumulator.toolCalls.size > 0) {
10180
10183
  accumulator.content = mergeXaiInlineParameterTags(
@@ -10257,7 +10260,9 @@ var CompletionsStrategy = class {
10257
10260
  content: finalContent,
10258
10261
  ...toolCalls && { tool_calls: toolCalls }
10259
10262
  },
10260
- finish_reason: toolCalls ? "tool_calls" : "stop"
10263
+ // Prefer what the provider actually said; fall back to the derived
10264
+ // value only when the stream carried no finish_reason at all.
10265
+ finish_reason: accumulator.finishReason ?? (toolCalls ? "tool_calls" : "stop")
10261
10266
  }
10262
10267
  ],
10263
10268
  ...usage && { usage },
@@ -10928,7 +10933,7 @@ var ResponsesStrategy = class {
10928
10933
  }
10929
10934
  return result;
10930
10935
  }
10931
- if (typedChunk.type === "response.completed") {
10936
+ if (typedChunk.type === "response.completed" || typedChunk.type === "response.incomplete") {
10932
10937
  if (typedChunk.response?.usage) {
10933
10938
  const u = typedChunk.response.usage;
10934
10939
  const promptTokens = u.input_tokens ?? u.prompt_tokens ?? 0;
@@ -10944,6 +10949,11 @@ var ResponsesStrategy = class {
10944
10949
  ...creditsExhausted !== void 0 && { credits_exhausted: creditsExhausted }
10945
10950
  };
10946
10951
  }
10952
+ const resp = typedChunk.response;
10953
+ const looksIncomplete = typedChunk.type === "response.incomplete" || resp?.status === "incomplete";
10954
+ if (looksIncomplete && resp?.incomplete_details?.reason === "max_output_tokens") {
10955
+ accumulator.finishReason = "length";
10956
+ }
10947
10957
  if (typedChunk.response?.tools_checksum && !accumulator.toolsChecksum) {
10948
10958
  accumulator.toolsChecksum = typedChunk.response.tools_checksum;
10949
10959
  }
@@ -12480,7 +12490,17 @@ Executing tool: ${toolInfo}
12480
12490
  flushDeAnon();
12481
12491
  currentAccumulator.content += tip;
12482
12492
  }
12493
+ const truncatedToNothing = (acc) => acc.finishReason === "length" && acc.toolCalls.size === 0 && acc.content.trim() === "";
12494
+ const TRUNCATION_ERROR = "Model response was truncated at the output-token limit before it produced any usable content or tool call. Retry with a higher `maxOutputTokens`, or prompt for fewer/smaller tool calls per turn.";
12483
12495
  if (toolIteration > 0) {
12496
+ if (truncatedToNothing(currentAccumulator)) {
12497
+ await fireRunError({ error: TRUNCATION_ERROR, stage: "model" });
12498
+ return {
12499
+ data: buildResponseFinal(currentAccumulator),
12500
+ error: TRUNCATION_ERROR,
12501
+ toolsChecksum: currentAccumulator.toolsChecksum
12502
+ };
12503
+ }
12484
12504
  const finalResponse = buildResponseFinal(currentAccumulator);
12485
12505
  if (onFinish) onFinish(finalResponse);
12486
12506
  await fireRunEnd({
@@ -12494,6 +12514,14 @@ Executing tool: ${toolInfo}
12494
12514
  autoExecutedToolResults: accumulatedToolResults
12495
12515
  };
12496
12516
  }
12517
+ if (truncatedToNothing(accumulator)) {
12518
+ await fireRunError({ error: TRUNCATION_ERROR, stage: "model" });
12519
+ return {
12520
+ data: response,
12521
+ error: TRUNCATION_ERROR,
12522
+ toolsChecksum: accumulator.toolsChecksum
12523
+ };
12524
+ }
12497
12525
  if (onFinish) onFinish(response);
12498
12526
  await fireRunEnd({
12499
12527
  finalContent: finalContentText(accumulator),
@@ -5655,6 +5655,20 @@ function createAppGenerationTools({
5655
5655
  if (!Array.isArray(filesArg) || filesArg.length === 0) {
5656
5656
  return { error: "files array is required and must not be empty" };
5657
5657
  }
5658
+ const malformed = filesArg.map((f, i) => {
5659
+ if (!f || typeof f !== "object") return `files[${i}] is not an object`;
5660
+ if (typeof f.path !== "string" || f.path.trim() === "")
5661
+ return `files[${i}] is missing a non-empty "path"`;
5662
+ if (typeof f.content !== "string")
5663
+ return `files[${i}] ("${f.path}") is missing a string "content"`;
5664
+ return null;
5665
+ }).filter((m) => m !== null);
5666
+ if (malformed.length > 0) {
5667
+ return {
5668
+ error: `Malformed files array \u2014 nothing was written. Every item needs both "path" and "content" as strings: ${malformed.join("; ")}`,
5669
+ malformed
5670
+ };
5671
+ }
5658
5672
  const normalizedPaths = filesArg.map((f) => normalizePath(f.path));
5659
5673
  const existsInStorage = await Promise.all(
5660
5674
  normalizedPaths.map((p) => storage.getFile(conversationId, p))
@@ -5506,6 +5506,20 @@ function createAppGenerationTools({
5506
5506
  if (!Array.isArray(filesArg) || filesArg.length === 0) {
5507
5507
  return { error: "files array is required and must not be empty" };
5508
5508
  }
5509
+ const malformed = filesArg.map((f, i) => {
5510
+ if (!f || typeof f !== "object") return `files[${i}] is not an object`;
5511
+ if (typeof f.path !== "string" || f.path.trim() === "")
5512
+ return `files[${i}] is missing a non-empty "path"`;
5513
+ if (typeof f.content !== "string")
5514
+ return `files[${i}] ("${f.path}") is missing a string "content"`;
5515
+ return null;
5516
+ }).filter((m) => m !== null);
5517
+ if (malformed.length > 0) {
5518
+ return {
5519
+ error: `Malformed files array \u2014 nothing was written. Every item needs both "path" and "content" as strings: ${malformed.join("; ")}`,
5520
+ malformed
5521
+ };
5522
+ }
5509
5523
  const normalizedPaths = filesArg.map((f) => normalizePath(f.path));
5510
5524
  const existsInStorage = await Promise.all(
5511
5525
  normalizedPaths.map((p) => storage.getFile(conversationId, p))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anuma/sdk",
3
- "version": "3.11.0",
3
+ "version": "3.11.2",
4
4
  "description": "",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",