@earendil-works/pi-ai 0.84.4 → 0.85.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 (94) hide show
  1. package/README.md +36 -3
  2. package/dist/api/anthropic-messages.d.ts.map +1 -1
  3. package/dist/api/anthropic-messages.js +123 -37
  4. package/dist/api/anthropic-messages.js.map +1 -1
  5. package/dist/api/cloudflare-ai-binding.d.ts +77 -0
  6. package/dist/api/cloudflare-ai-binding.d.ts.map +1 -0
  7. package/dist/api/cloudflare-ai-binding.js +72 -0
  8. package/dist/api/cloudflare-ai-binding.js.map +1 -0
  9. package/dist/api/openai-codex-responses.d.ts.map +1 -1
  10. package/dist/api/openai-codex-responses.js +6 -3
  11. package/dist/api/openai-codex-responses.js.map +1 -1
  12. package/dist/api/openai-completions.d.ts +2 -1
  13. package/dist/api/openai-completions.d.ts.map +1 -1
  14. package/dist/api/openai-completions.js +4 -0
  15. package/dist/api/openai-completions.js.map +1 -1
  16. package/dist/api/openai-responses-shared.d.ts.map +1 -1
  17. package/dist/api/openai-responses-shared.js +4 -1
  18. package/dist/api/openai-responses-shared.js.map +1 -1
  19. package/dist/api/openai-responses.d.ts.map +1 -1
  20. package/dist/api/openai-responses.js +15 -4
  21. package/dist/api/openai-responses.js.map +1 -1
  22. package/dist/api/pi-messages.d.ts +2 -0
  23. package/dist/api/pi-messages.d.ts.map +1 -1
  24. package/dist/api/pi-messages.js +6 -0
  25. package/dist/api/pi-messages.js.map +1 -1
  26. package/dist/image-models.generated.d.ts +30 -0
  27. package/dist/image-models.generated.d.ts.map +1 -1
  28. package/dist/image-models.generated.js +30 -0
  29. package/dist/image-models.generated.js.map +1 -1
  30. package/dist/index.d.ts +1 -0
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +1 -0
  33. package/dist/index.js.map +1 -1
  34. package/dist/models.d.ts +1 -0
  35. package/dist/models.d.ts.map +1 -1
  36. package/dist/models.js +5 -2
  37. package/dist/models.js.map +1 -1
  38. package/dist/providers/cloudflare-ai-gateway.d.ts.map +1 -1
  39. package/dist/providers/cloudflare-ai-gateway.js +4 -0
  40. package/dist/providers/cloudflare-ai-gateway.js.map +1 -1
  41. package/dist/providers/data/.manifest.json +1 -1
  42. package/dist/providers/data/amazon-bedrock.json +1 -1
  43. package/dist/providers/data/anthropic.json +1 -1
  44. package/dist/providers/data/azure-openai-responses.json +1 -1
  45. package/dist/providers/data/baseten.json +1 -1
  46. package/dist/providers/data/cloudflare-ai-gateway.json +1 -1
  47. package/dist/providers/data/cloudflare-workers-ai.json +1 -1
  48. package/dist/providers/data/fireworks.json +1 -1
  49. package/dist/providers/data/github-copilot.json +1 -1
  50. package/dist/providers/data/google-vertex.json +1 -1
  51. package/dist/providers/data/google.json +1 -1
  52. package/dist/providers/data/groq.json +1 -1
  53. package/dist/providers/data/huggingface.json +1 -1
  54. package/dist/providers/data/nvidia.json +1 -1
  55. package/dist/providers/data/openai-codex.json +1 -1
  56. package/dist/providers/data/openai.json +1 -1
  57. package/dist/providers/data/opencode-go.json +1 -1
  58. package/dist/providers/data/opencode.json +1 -1
  59. package/dist/providers/data/openrouter.json +1 -1
  60. package/dist/providers/data/qwen-token-plan-cn.json +1 -1
  61. package/dist/providers/data/qwen-token-plan-individual.json +1 -1
  62. package/dist/providers/data/qwen-token-plan.json +1 -1
  63. package/dist/providers/data/together.json +1 -1
  64. package/dist/providers/data/vercel-ai-gateway.json +1 -1
  65. package/dist/providers/data/xai.json +1 -1
  66. package/dist/providers/faux.d.ts.map +1 -1
  67. package/dist/providers/faux.js +3 -3
  68. package/dist/providers/faux.js.map +1 -1
  69. package/dist/providers/openrouter.d.ts +1 -1
  70. package/dist/providers/openrouter.d.ts.map +1 -1
  71. package/dist/providers/openrouter.js +5 -1
  72. package/dist/providers/openrouter.js.map +1 -1
  73. package/dist/types.d.ts +28 -7
  74. package/dist/types.d.ts.map +1 -1
  75. package/dist/types.js.map +1 -1
  76. package/dist/utils/assistant-message-frame.d.ts +77 -0
  77. package/dist/utils/assistant-message-frame.d.ts.map +1 -0
  78. package/dist/utils/assistant-message-frame.js +425 -0
  79. package/dist/utils/assistant-message-frame.js.map +1 -0
  80. package/dist/utils/node-http-proxy.d.ts.map +1 -1
  81. package/dist/utils/node-http-proxy.js +53 -12
  82. package/dist/utils/node-http-proxy.js.map +1 -1
  83. package/dist/utils/retry.d.ts.map +1 -1
  84. package/dist/utils/retry.js +2 -1
  85. package/dist/utils/retry.js.map +1 -1
  86. package/dist/utils/uuid.d.ts +2 -2
  87. package/dist/utils/uuid.d.ts.map +1 -1
  88. package/dist/utils/uuid.js +35 -39
  89. package/dist/utils/uuid.js.map +1 -1
  90. package/package.json +7 -3
  91. package/dist/api/cloudflare-gateway-binding.d.ts +0 -69
  92. package/dist/api/cloudflare-gateway-binding.d.ts.map +0 -1
  93. package/dist/api/cloudflare-gateway-binding.js +0 -159
  94. package/dist/api/cloudflare-gateway-binding.js.map +0 -1
@@ -1,6 +1,7 @@
1
1
  import Anthropic from "@anthropic-ai/sdk";
2
2
  import { calculateCost } from "../models.js";
3
3
  import { splitDeferredTools } from "../utils/deferred-tools.js";
4
+ import { appendAssistantMessageDiagnostic } from "../utils/diagnostics.js";
4
5
  import { AssistantMessageEventStream } from "../utils/event-stream.js";
5
6
  import { headersToRecord } from "../utils/headers.js";
6
7
  import { parseJsonWithRepair, parseStreamingJson } from "../utils/json-parse.js";
@@ -37,7 +38,7 @@ function getCacheControl(model, cacheRetention, env) {
37
38
  };
38
39
  }
39
40
  // Stealth mode: Mimic Claude Code's tool naming exactly
40
- const claudeCodeVersion = "2.1.75";
41
+ const claudeCodeVersion = "2.1.251";
41
42
  // Claude Code 2.x tool names (canonical casing)
42
43
  // Source: https://cchistory.mariozechner.at/data/prompts-2.1.11.md
43
44
  // To update: https://github.com/badlogic/cchistory
@@ -111,6 +112,8 @@ function convertContentBlocks(content) {
111
112
  const FINE_GRAINED_TOOL_STREAMING_BETA = "fine-grained-tool-streaming-2025-05-14";
112
113
  const INTERLEAVED_THINKING_BETA = "interleaved-thinking-2025-05-14";
113
114
  const SERVER_SIDE_FALLBACK_BETA = "server-side-fallback-2026-07-01";
115
+ const MID_CONVERSATION_OUTPUT_CONFIG_BETA = "mid-conversation-output-config-2026-07-01";
116
+ const THINKING_BINDING_CONTROLS_BETA = "thinking-binding-controls-2026-08-01";
114
117
  function shouldUseServerSideFallbackBeta(model) {
115
118
  return (model.compat?.allowedFallbackModels?.length ?? 0) > 0;
116
119
  }
@@ -327,12 +330,14 @@ async function* iterateAnthropicEvents(response, signal) {
327
330
  export const stream = (model, context, options) => {
328
331
  const stream = new AssistantMessageEventStream();
329
332
  (async () => {
333
+ const providerThinkingLevel = model.compat?.supportsMidConvoEffort ? (options?.effort ?? "high") : undefined;
330
334
  const output = {
331
335
  role: "assistant",
332
336
  content: [],
333
337
  api: model.api,
334
338
  provider: model.provider,
335
339
  model: model.id,
340
+ ...(providerThinkingLevel === undefined ? {} : { providerThinkingLevel }),
336
341
  usage: {
337
342
  input: 0,
338
343
  output: 0,
@@ -348,6 +353,7 @@ export const stream = (model, context, options) => {
348
353
  let client;
349
354
  let isOAuth;
350
355
  let usageModel = model;
356
+ let inputTransformations;
351
357
  if (options?.client) {
352
358
  client = options.client;
353
359
  isOAuth = false;
@@ -365,21 +371,21 @@ export const stream = (model, context, options) => {
365
371
  }
366
372
  const cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env);
367
373
  const cacheSessionId = cacheRetention === "none" ? undefined : options?.sessionId;
368
- const created = createClient(model, apiKey, options?.interleavedThinking ?? true, shouldUseFineGrainedToolStreamingBeta(model, context), shouldUseServerSideFallbackBeta(model), options?.headers, options?.fetch, copilotDynamicHeaders, cacheSessionId);
374
+ const created = createClient(model, apiKey, options?.headers, options?.fetch, copilotDynamicHeaders, cacheSessionId);
369
375
  client = created.client;
370
376
  isOAuth = created.isOAuthToken;
371
377
  }
372
378
  let params = buildParams(model, context, isOAuth, options);
373
379
  const nextParams = await options?.onPayload?.(params, model);
374
380
  if (nextParams !== undefined) {
375
- params = nextParams;
381
+ params = { ...nextParams, stream: true };
376
382
  }
377
383
  const requestOptions = {
378
384
  ...(options?.signal ? { signal: options.signal } : {}),
379
385
  ...(options?.timeoutMs !== undefined ? { timeout: options.timeoutMs } : {}),
380
386
  maxRetries: 0,
381
387
  };
382
- const response = await retryProviderRequest(() => client.messages.create({ ...params, stream: true }, requestOptions).asResponse(), {
388
+ const response = await retryProviderRequest(() => client.beta.messages.create(params, requestOptions).asResponse(), {
383
389
  maxRetries: options?.maxRetries,
384
390
  maxRetryDelayMs: options?.maxRetryDelayMs,
385
391
  signal: options?.signal,
@@ -390,6 +396,9 @@ export const stream = (model, context, options) => {
390
396
  for await (const event of iterateAnthropicEvents(response, options?.signal)) {
391
397
  if (event.type === "message_start") {
392
398
  output.responseId = event.message.id;
399
+ const transformations = event.message.input_transformations;
400
+ if (Array.isArray(transformations))
401
+ inputTransformations = transformations;
393
402
  output.model = event.message.model;
394
403
  const fallbackCost = output.model === model.id
395
404
  ? undefined
@@ -408,6 +417,12 @@ export const stream = (model, context, options) => {
408
417
  calculateCost(usageModel, output.usage);
409
418
  }
410
419
  else if (event.type === "content_block_start") {
420
+ if (event.content_block.type === "fallback") {
421
+ if (output.content.length > 0) {
422
+ throw new Error("Anthropic performed an unsupported mid-output model fallback");
423
+ }
424
+ continue;
425
+ }
411
426
  if (event.content_block.type === "text") {
412
427
  const block = {
413
428
  type: "text",
@@ -539,6 +554,9 @@ export const stream = (model, context, options) => {
539
554
  }
540
555
  }
541
556
  else if (event.type === "message_delta") {
557
+ const transformations = event.input_transformations;
558
+ if (Array.isArray(transformations))
559
+ inputTransformations = transformations;
542
560
  if (event.delta.stop_reason) {
543
561
  output.rawStopReason = event.delta.stop_reason;
544
562
  const stopReasonResult = mapStopReason(event.delta.stop_reason, event.delta.stop_details);
@@ -562,11 +580,8 @@ export const stream = (model, context, options) => {
562
580
  if (event.usage.cache_creation_input_tokens != null) {
563
581
  output.usage.cacheWrite = event.usage.cache_creation_input_tokens;
564
582
  }
565
- // Anthropic reports reasoning tokens in `output_tokens_details.thinking_tokens` on the
566
- // final message_delta usage (a subset of output_tokens). SDK 0.91.1 omits the field from
567
- // its Usage type, so read it through a narrow cast. Verified against the live API.
568
- const thinkingTokens = event.usage
569
- .output_tokens_details?.thinking_tokens;
583
+ // Anthropic reports reasoning tokens as a subset of output tokens.
584
+ const thinkingTokens = event.usage.output_tokens_details?.thinking_tokens;
570
585
  if (thinkingTokens != null) {
571
586
  output.usage.reasoning = thinkingTokens;
572
587
  }
@@ -586,6 +601,19 @@ export const stream = (model, context, options) => {
586
601
  if (output.stopReason === "aborted" || output.stopReason === "error") {
587
602
  throw new Error(output.errorMessage || "An unknown error occurred");
588
603
  }
604
+ if (inputTransformations && inputTransformations.length > 0) {
605
+ appendAssistantMessageDiagnostic(output, {
606
+ type: "anthropic_input_transformations",
607
+ timestamp: Date.now(),
608
+ details: {
609
+ transformations: inputTransformations.map((transformation) => ({
610
+ type: transformation.type ?? undefined,
611
+ path: transformation.path ?? undefined,
612
+ reason: transformation.reason ?? undefined,
613
+ })),
614
+ },
615
+ });
616
+ }
589
617
  stream.push({ type: "done", reason: output.stopReason, message: output });
590
618
  stream.end();
591
619
  }
@@ -660,20 +688,8 @@ export const streamSimple = (model, context, options) => {
660
688
  function isOAuthToken(apiKey) {
661
689
  return apiKey.includes("sk-ant-oat");
662
690
  }
663
- function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStreamingBeta, useServerSideFallbackBeta, optionsHeaders, fetch, dynamicHeaders, sessionId) {
664
- // Adaptive thinking models have interleaved thinking built in, so skip the beta header.
665
- const needsInterleavedBeta = interleavedThinking && model.compat?.forceAdaptiveThinking !== true;
666
- const betaFeatures = [];
667
- if (useFineGrainedToolStreamingBeta) {
668
- betaFeatures.push(FINE_GRAINED_TOOL_STREAMING_BETA);
669
- }
670
- if (needsInterleavedBeta) {
671
- betaFeatures.push(INTERLEAVED_THINKING_BETA);
672
- }
673
- if (useServerSideFallbackBeta) {
674
- betaFeatures.push(SERVER_SIDE_FALLBACK_BETA);
675
- }
676
- // Copilot: Bearer auth, selective betas.
691
+ function createClient(model, apiKey, optionsHeaders, fetch, dynamicHeaders, sessionId) {
692
+ // Copilot: Bearer auth.
677
693
  if (model.provider === "github-copilot") {
678
694
  const client = new Anthropic({
679
695
  apiKey: null,
@@ -684,7 +700,6 @@ function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStre
684
700
  defaultHeaders: mergeClientHeaders({
685
701
  accept: "application/json",
686
702
  "anthropic-dangerous-direct-browser-access": "true",
687
- ...(betaFeatures.length > 0 ? { "anthropic-beta": betaFeatures.join(",") } : {}),
688
703
  }, model.headers, dynamicHeaders, optionsHeaders),
689
704
  });
690
705
  return { client, isOAuthToken: false };
@@ -700,7 +715,6 @@ function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStre
700
715
  defaultHeaders: mergeClientHeaders({
701
716
  accept: "application/json",
702
717
  "anthropic-dangerous-direct-browser-access": "true",
703
- "anthropic-beta": ["claude-code-20250219", "oauth-2025-04-20", ...betaFeatures].join(","),
704
718
  "user-agent": `claude-cli/${claudeCodeVersion}`,
705
719
  "x-app": "cli",
706
720
  }, model.headers, optionsHeaders),
@@ -712,7 +726,6 @@ function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStre
712
726
  const defaultHeaders = mergeClientHeaders({
713
727
  accept: "application/json",
714
728
  "anthropic-dangerous-direct-browser-access": "true",
715
- ...(betaFeatures.length > 0 ? { "anthropic-beta": betaFeatures.join(",") } : {}),
716
729
  }, sessionAffinityHeaders, model.headers, optionsHeaders);
717
730
  const client = new Anthropic({
718
731
  apiKey: apiKey ?? null,
@@ -724,6 +737,42 @@ function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStre
724
737
  });
725
738
  return { client, isOAuthToken: false };
726
739
  }
740
+ function getBetaFeatures(model, context, isOAuthToken, options) {
741
+ let configuredFeatures;
742
+ for (const headers of [model.headers, options?.headers]) {
743
+ for (const [name, value] of Object.entries(headers ?? {})) {
744
+ if (name.toLowerCase() === "anthropic-beta")
745
+ configuredFeatures = value;
746
+ }
747
+ }
748
+ if (configuredFeatures === null)
749
+ return [];
750
+ if (configuredFeatures !== undefined) {
751
+ return [
752
+ ...new Set(configuredFeatures
753
+ .split(",")
754
+ .map((feature) => feature.trim())
755
+ .filter((feature) => feature.length > 0)),
756
+ ];
757
+ }
758
+ const features = [];
759
+ if (isOAuthToken)
760
+ features.push("claude-code-20250219", "oauth-2025-04-20");
761
+ if (shouldUseFineGrainedToolStreamingBeta(model, context))
762
+ features.push(FINE_GRAINED_TOOL_STREAMING_BETA);
763
+ if (model.reasoning &&
764
+ options?.thinkingEnabled === true &&
765
+ (options.interleavedThinking ?? true) &&
766
+ model.compat?.forceAdaptiveThinking !== true) {
767
+ features.push(INTERLEAVED_THINKING_BETA);
768
+ }
769
+ if (shouldUseServerSideFallbackBeta(model))
770
+ features.push(SERVER_SIDE_FALLBACK_BETA);
771
+ if (model.compat?.supportsMidConvoEffort === true) {
772
+ features.push(MID_CONVERSATION_OUTPUT_CONFIG_BETA, THINKING_BINDING_CONTROLS_BETA);
773
+ }
774
+ return [...new Set(features)];
775
+ }
727
776
  function buildParams(model, context, isOAuthToken, options) {
728
777
  const { cacheControl } = getCacheControl(model, options?.cacheRetention, options?.env);
729
778
  const compat = getAnthropicCompat(model);
@@ -737,11 +786,17 @@ function buildParams(model, context, isOAuthToken, options) {
737
786
  deferredTools = [];
738
787
  }
739
788
  const deferredToolNames = new Set(deferredTools.map((tool) => normalizeToolName(tool.name)));
789
+ const converted = convertMessages(transformedMessages, isOAuthToken, cacheControl, compat.allowEmptySignature, deferredToolNames, normalizeToolName, model.compat?.supportsMidConvoEffort === true ? model.provider : undefined);
790
+ const activeEffort = options?.effort ?? "high";
791
+ const betaFeatures = getBetaFeatures(model, context, isOAuthToken, options);
740
792
  const params = {
741
793
  model: model.id,
742
- messages: convertMessages(transformedMessages, isOAuthToken, cacheControl, compat.allowEmptySignature, deferredToolNames, normalizeToolName),
794
+ messages: model.compat?.supportsMidConvoEffort === true
795
+ ? insertThinkingLevelMessages(converted, activeEffort)
796
+ : converted.messages,
743
797
  max_tokens: options?.maxTokens ?? model.maxTokens,
744
798
  stream: true,
799
+ ...(betaFeatures.length > 0 ? { betas: betaFeatures } : {}),
745
800
  };
746
801
  // For OAuth tokens, we MUST include Claude Code identity
747
802
  if (isOAuthToken) {
@@ -771,7 +826,10 @@ function buildParams(model, context, isOAuthToken, options) {
771
826
  ];
772
827
  }
773
828
  // Temperature is incompatible with extended thinking and unsupported on Claude Opus 4.7+.
774
- if (options?.temperature !== undefined && !options?.thinkingEnabled && compat.supportsTemperature) {
829
+ if (options?.temperature !== undefined &&
830
+ !options?.thinkingEnabled &&
831
+ model.compat?.supportsMidConvoEffort !== true &&
832
+ compat.supportsTemperature) {
775
833
  params.temperature = options.temperature;
776
834
  }
777
835
  if (immediateTools.length > 0 || deferredTools.length > 0) {
@@ -780,8 +838,17 @@ function buildParams(model, context, isOAuthToken, options) {
780
838
  ...convertTools(deferredTools, isOAuthToken, compat.supportsEagerToolInputStreaming, compat.supportsStrictTools, undefined, true),
781
839
  ];
782
840
  }
783
- // Configure thinking mode: adaptive, budget-based, or explicitly disabled.
784
- if (model.reasoning) {
841
+ // Managed effort models always use adaptive thinking so prefix mismatches can
842
+ // be dropped instead of surfacing as persistent 400 responses.
843
+ if (model.compat?.supportsMidConvoEffort === true) {
844
+ params.thinking = {
845
+ type: "adaptive",
846
+ display: options?.thinkingDisplay ?? "summarized",
847
+ block_binding: { prefix_mismatch_behavior: "drop_block" },
848
+ };
849
+ params.output_config = { effort: "high" };
850
+ }
851
+ else if (model.reasoning) {
785
852
  if (options?.thinkingEnabled) {
786
853
  // Default to "summarized" so Opus 4.7 and Mythos Preview behave like
787
854
  // older Claude 4 models (whose API default is also "summarized").
@@ -790,11 +857,7 @@ function buildParams(model, context, isOAuthToken, options) {
790
857
  // Adaptive thinking: Claude decides when and how much to think.
791
858
  params.thinking = { type: "adaptive", display };
792
859
  if (options.effort) {
793
- // The Anthropic SDK types can lag newly supported effort values such as "xhigh".
794
- params.output_config =
795
- options.effort === "xhigh"
796
- ? { effort: options.effort }
797
- : { effort: options.effort };
860
+ params.output_config = { effort: options.effort };
798
861
  }
799
862
  }
800
863
  else {
@@ -862,8 +925,9 @@ function convertToolResult(msg, isOAuthToken, deferredToolNames, loadedToolNames
862
925
  : convertedContent,
863
926
  };
864
927
  }
865
- function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowEmptySignature = false, deferredToolNames = new Set(), normalizeToolName = (name) => name) {
928
+ function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowEmptySignature = false, deferredToolNames = new Set(), normalizeToolName = (name) => name, managedProvider) {
866
929
  const params = [];
930
+ const assistantLevels = new Map();
867
931
  const loadedToolNames = new Set();
868
932
  for (let i = 0; i < transformedMessages.length; i++) {
869
933
  const msg = transformedMessages[i];
@@ -967,10 +1031,17 @@ function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowE
967
1031
  }
968
1032
  if (blocks.length === 0)
969
1033
  continue;
1034
+ const messageIndex = params.length;
970
1035
  params.push({
971
1036
  role: "assistant",
972
1037
  content: blocks,
973
1038
  });
1039
+ if (managedProvider !== undefined &&
1040
+ msg.api === "anthropic-messages" &&
1041
+ msg.provider === managedProvider &&
1042
+ isAnthropicEffort(msg.providerThinkingLevel)) {
1043
+ assistantLevels.set(messageIndex, msg.providerThinkingLevel);
1044
+ }
974
1045
  }
975
1046
  else if (msg.role === "toolResult") {
976
1047
  // Collect all consecutive toolResult messages, needed for z.ai Anthropic endpoint.
@@ -1014,7 +1085,22 @@ function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowE
1014
1085
  }
1015
1086
  }
1016
1087
  }
1017
- return params;
1088
+ return { messages: params, assistantLevels };
1089
+ }
1090
+ function isAnthropicEffort(value) {
1091
+ return value === "low" || value === "medium" || value === "high" || value === "xhigh" || value === "max";
1092
+ }
1093
+ function insertThinkingLevelMessages(converted, activeEffort) {
1094
+ const messages = [];
1095
+ for (let index = 0; index < converted.messages.length; index++) {
1096
+ const historicalEffort = converted.assistantLevels.get(index);
1097
+ if (historicalEffort !== undefined) {
1098
+ messages.push({ role: "system", content: [], output_config: { effort: historicalEffort } });
1099
+ }
1100
+ messages.push(converted.messages[index]);
1101
+ }
1102
+ messages.push({ role: "system", content: [], output_config: { effort: activeEffort } });
1103
+ return messages;
1018
1104
  }
1019
1105
  function shouldUseFineGrainedToolStreamingBeta(model, context) {
1020
1106
  return !!context.tools?.length && !getAnthropicCompat(model).supportsEagerToolInputStreaming;