graphlit-client 1.0.20260408010 → 1.0.20260408012

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.
package/README.md CHANGED
@@ -16,6 +16,15 @@ Graphlit is a cloud platform that handles the complex parts of building AI appli
16
16
 
17
17
  ## What's New
18
18
 
19
+ ### OpenAI Responses API Support
20
+
21
+ - **Automatic Responses API Routing** - GPT-5.4 and eligible OpenAI models are automatically routed through the [OpenAI Responses API](https://platform.openai.com/docs/api-reference/responses) for improved intelligence, fewer reasoning tokens, higher cache hit rates, and lower latency. Disable with `useResponsesApi: false` in `StreamAgentOptions`.
22
+ - **Reasoning Effort** - Reasoning effort (e.g. `medium`, `high`) is read from the specification's `openAI.reasoningEffort` field and passed through to the Responses API.
23
+ - **GPT-5.4 Temperature Handling** - Temperature is only sent when reasoning effort is `none` (the GPT-5.4 default). Other reasoning levels don't support temperature per the OpenAI docs.
24
+ - **`phase` on Assistant Messages** - Conversation history replayed to the Responses API includes `phase: "commentary"` on assistant messages that preceded tool calls, and `phase: "final_answer"` on terminal messages, per GPT-5.4 best practices.
25
+ - **Tool Call ID Remapping** - Tool call IDs are automatically remapped between `call_` (Chat Completions) and `fc_` (Responses API) formats, enabling mid-conversation model switches without errors.
26
+ - **First-Round Tool Engagement** - When tools are provided, the SDK sends `tool_choice: "required"` on the first API request to ensure the model engages with available tools, then reverts to `auto` for subsequent rounds. This addresses GPT-5.4's tendency to skip tool use under the default `auto` setting. This behavior is internal to the Responses API path and not exposed as a caller option.
27
+
19
28
  ### Streaming Provider Resilience
20
29
 
21
30
  - **Automatic Retry for Provider Errors** - `streamAgent` and `runAgent` now retry transient LLM provider errors (HTTP 500, 503, 429, network failures) with exponential backoff (up to 3 retries)
@@ -77,6 +86,7 @@ Graphlit is a cloud platform that handles the complex parts of building AI appli
77
86
  - [Quick Start](#quick-start)
78
87
  - [Installation](#installation)
79
88
  - [Setting Up](#setting-up)
89
+ - [OpenAI Responses API Support](#openai-responses-api-support)
80
90
  - [Migrating from @google/generative-ai](#migrating-from-google-generative-ai) šŸ”„
81
91
  - [Reasoning Support (New!)](#reasoning-support-new) 🧠
82
92
  - [Stream Cancellation (New!)](#stream-cancellation-new) šŸ›‘
@@ -546,7 +556,7 @@ The Graphlit SDK supports real-time streaming responses from 9 different LLM pro
546
556
 
547
557
  | Provider | Models | SDK Required | API Key |
548
558
  | --------------- | --------------------------------------------- | --------------------------------- | ------------------- |
549
- | **OpenAI** | GPT-4, GPT-4o, GPT-4.1, O1, O3, O4 | `openai` | `OPENAI_API_KEY` |
559
+ | **OpenAI** | GPT-5.4, GPT-4.1, GPT-4o, O1, O3, O4 | `openai` | `OPENAI_API_KEY` |
550
560
  | **Anthropic** | Claude 3, Claude 3.5, Claude 3.7, Claude 4 | `@anthropic-ai/sdk` | `ANTHROPIC_API_KEY` |
551
561
  | **Google** | Gemini 1.5, Gemini 2.0, Gemini 2.5 | `@google/genai` | `GOOGLE_API_KEY` |
552
562
  | **Groq** | Llama 4, Llama 3.3, Mixtral, Deepseek R1 | `groq-sdk` | `GROQ_API_KEY` |
@@ -597,7 +607,8 @@ const spec = await client.createSpecification({
597
607
 
598
608
  ### Provider-Specific Notes
599
609
 
600
- - **OpenAI-Compatible**: Groq, Cerebras, and Deepseek use OpenAI-compatible APIs
610
+ - **OpenAI GPT-5.4**: Automatically uses the Responses API for chain-of-thought passback, 1M context, and improved tool calling. The SDK sends `tool_choice: "required"` on the first round when tools are provided, then `auto` on subsequent rounds. Set `useResponsesApi: false` in options to force legacy Chat Completions.
611
+ - **OpenAI-Compatible**: Groq, Cerebras, Deepseek, and xAI use OpenAI-compatible APIs
601
612
  - **AWS Bedrock**: Requires AWS credentials and uses the Converse API for streaming
602
613
  - **Cohere**: Supports both chat and tool calling with Command models
603
614
  - **Google**: Includes advanced multimodal capabilities with Gemini models
package/dist/client.js CHANGED
@@ -5654,7 +5654,7 @@ class Graphlit {
5654
5654
  });
5655
5655
  // Start the streaming conversation
5656
5656
  // fullSpec is guaranteed non-null here — the !fullSpec check above returns early
5657
- await this.executeStreamingAgent(prompt, actualConversationId, fullSpec, tools, toolHandlers, uiAdapter, maxRounds, abortSignal, mimeType, data, correlationId, persona, options?.contextStrategy, options?.useResponsesApi, options?.toolChoice, options?.toolStrict, options?.instructions, options?.scratchpad, options?.skills);
5657
+ await this.executeStreamingAgent(prompt, actualConversationId, fullSpec, tools, toolHandlers, uiAdapter, maxRounds, abortSignal, mimeType, data, correlationId, persona, options?.contextStrategy, options?.useResponsesApi, options?.instructions, options?.scratchpad, options?.skills);
5658
5658
  }, abortSignal);
5659
5659
  }
5660
5660
  catch (error) {
@@ -5700,7 +5700,7 @@ class Graphlit {
5700
5700
  /**
5701
5701
  * Execute the streaming agent workflow with tool calling loop
5702
5702
  */
5703
- async executeStreamingAgent(prompt, conversationId, specification, tools, toolHandlers, uiAdapter, maxRounds, abortSignal, mimeType, data, correlationId, persona, contextStrategy, useResponsesApi, toolChoice, toolStrict, instructions, scratchpad, skills) {
5703
+ async executeStreamingAgent(prompt, conversationId, specification, tools, toolHandlers, uiAdapter, maxRounds, abortSignal, mimeType, data, correlationId, persona, contextStrategy, useResponsesApi, instructions, scratchpad, skills) {
5704
5704
  // Collects artifact content IDs from tool handlers (e.g. code_execution).
5705
5705
  // Handlers register async ingestion promises; we await all of them before
5706
5706
  // completeConversation so the IDs are available without blocking the LLM.
@@ -5873,8 +5873,6 @@ class Graphlit {
5873
5873
  maxRounds,
5874
5874
  abortSignal,
5875
5875
  useResponsesApi,
5876
- toolChoice,
5877
- toolStrict,
5878
5876
  correlationId,
5879
5877
  persona,
5880
5878
  mimeType,
@@ -5935,7 +5933,7 @@ class Graphlit {
5935
5933
  * Shared between streamAgent (single turn) and runAgent (multi-turn harness).
5936
5934
  */
5937
5935
  async executeStreamingLoop(config) {
5938
- const { conversationId, specification, tools, toolHandlers, uiAdapter, budgetTracker, contextStrategy: { toolResultTokenLimit, toolRoundLimit, rebudgetThreshold }, maxRounds, abortSignal, useResponsesApi, toolChoice, toolStrict, mimeType, data, correlationId, persona, } = config;
5936
+ const { conversationId, specification, tools, toolHandlers, uiAdapter, budgetTracker, contextStrategy: { toolResultTokenLimit, toolRoundLimit, rebudgetThreshold }, maxRounds, abortSignal, useResponsesApi, mimeType, data, correlationId, persona, } = config;
5939
5937
  let messages = config.messages;
5940
5938
  let currentRound = 0;
5941
5939
  let fullMessage = "";
@@ -6048,7 +6046,7 @@ class Graphlit {
6048
6046
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING_MESSAGES) {
6049
6047
  console.log(`šŸ” [OpenAI Responses] Sending ${openAIResponsesState.initialInput.length} initial items and ${openAIResponsesState.continuationItems.length} continuation items`);
6050
6048
  }
6051
- const responsesResult = await this.streamWithOpenAIResponses(specification, messages, openAIResponsesPendingToolMessages, tools, uiAdapter, abortSignal, openAIResponsesState, toolChoice, toolStrict);
6049
+ const responsesResult = await this.streamWithOpenAIResponses(specification, messages, openAIResponsesPendingToolMessages, tools, uiAdapter, abortSignal, openAIResponsesState, (currentRound === 0 && tools?.length) ? "required" : undefined);
6052
6050
  roundMessage = responsesResult.message;
6053
6051
  toolCalls = responsesResult.toolCalls;
6054
6052
  openAIResponsesState = responsesResult.state;
@@ -6069,7 +6067,7 @@ class Graphlit {
6069
6067
  if (usage) {
6070
6068
  uiAdapter.setUsageData(usage);
6071
6069
  }
6072
- }, abortSignal, toolChoice, toolStrict);
6070
+ }, abortSignal);
6073
6071
  }
6074
6072
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
6075
6073
  console.log(`\nšŸ [Streaming] OpenAI ${useOpenAIResponses ? "Responses" : "native"} streaming completed (Round ${currentRound})`);
@@ -6091,7 +6089,7 @@ class Graphlit {
6091
6089
  if (usage) {
6092
6090
  uiAdapter.setUsageData(usage);
6093
6091
  }
6094
- }, abortSignal, toolChoice);
6092
+ }, abortSignal);
6095
6093
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
6096
6094
  console.log(`\nšŸ [Streaming] Anthropic native streaming completed (Round ${currentRound})`);
6097
6095
  }
@@ -6112,7 +6110,7 @@ class Graphlit {
6112
6110
  if (usage) {
6113
6111
  uiAdapter.setUsageData(usage);
6114
6112
  }
6115
- }, abortSignal, toolChoice);
6113
+ }, abortSignal);
6116
6114
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
6117
6115
  console.log(`\nšŸ [Streaming] Google native streaming completed (Round ${currentRound})`);
6118
6116
  }
@@ -6133,7 +6131,7 @@ class Graphlit {
6133
6131
  if (usage) {
6134
6132
  uiAdapter.setUsageData(usage);
6135
6133
  }
6136
- }, abortSignal, toolChoice);
6134
+ }, abortSignal);
6137
6135
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
6138
6136
  console.log(`\nšŸ [Streaming] Groq native streaming completed (Round ${currentRound})`);
6139
6137
  }
@@ -6154,7 +6152,7 @@ class Graphlit {
6154
6152
  if (usage) {
6155
6153
  uiAdapter.setUsageData(usage);
6156
6154
  }
6157
- }, abortSignal, toolChoice);
6155
+ }, abortSignal);
6158
6156
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
6159
6157
  console.log(`\nšŸ [Streaming] Cerebras native streaming completed (Round ${currentRound})`);
6160
6158
  }
@@ -6174,7 +6172,7 @@ class Graphlit {
6174
6172
  if (usage) {
6175
6173
  uiAdapter.setUsageData(usage);
6176
6174
  }
6177
- }, abortSignal, toolChoice);
6175
+ }, abortSignal);
6178
6176
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
6179
6177
  console.log(`\nšŸ [Streaming] Cohere native streaming completed (Round ${currentRound})`);
6180
6178
  }
@@ -6216,7 +6214,7 @@ class Graphlit {
6216
6214
  if (usage) {
6217
6215
  uiAdapter.setUsageData(usage);
6218
6216
  }
6219
- }, abortSignal, toolChoice);
6217
+ }, abortSignal);
6220
6218
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
6221
6219
  console.log(`\nšŸ [Streaming] Mistral native streaming completed (Round ${currentRound})`);
6222
6220
  }
@@ -6237,7 +6235,7 @@ class Graphlit {
6237
6235
  if (usage) {
6238
6236
  uiAdapter.setUsageData(usage);
6239
6237
  }
6240
- }, abortSignal, toolChoice);
6238
+ }, abortSignal);
6241
6239
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
6242
6240
  console.log(`\nšŸ [Streaming] Bedrock native streaming completed (Round ${currentRound})`);
6243
6241
  }
@@ -6258,7 +6256,7 @@ class Graphlit {
6258
6256
  if (usage) {
6259
6257
  uiAdapter.setUsageData(usage);
6260
6258
  }
6261
- }, abortSignal, toolChoice);
6259
+ }, abortSignal);
6262
6260
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
6263
6261
  console.log(`\nšŸ [Streaming] Deepseek native streaming completed (Round ${currentRound})`);
6264
6262
  }
@@ -6279,7 +6277,7 @@ class Graphlit {
6279
6277
  if (usage) {
6280
6278
  uiAdapter.setUsageData(usage);
6281
6279
  }
6282
- }, abortSignal, toolChoice);
6280
+ }, abortSignal);
6283
6281
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
6284
6282
  console.log(`\nšŸ [Streaming] xAI native streaming completed (Round ${currentRound})`);
6285
6283
  }
@@ -7119,8 +7117,6 @@ class Graphlit {
7119
7117
  maxRounds: DEFAULT_MAX_TOOL_ROUNDS,
7120
7118
  abortSignal,
7121
7119
  useResponsesApi: options?.useResponsesApi,
7122
- toolChoice: options?.toolChoice,
7123
- toolStrict: options?.toolStrict,
7124
7120
  correlationId: options?.correlationId,
7125
7121
  persona: options?.persona,
7126
7122
  });
@@ -7608,7 +7604,7 @@ class Graphlit {
7608
7604
  /**
7609
7605
  * Stream with OpenAI client
7610
7606
  */
7611
- async streamWithOpenAIResponses(specification, messages, toolMessages, tools, uiAdapter, abortSignal, state, toolChoice, toolStrict) {
7607
+ async streamWithOpenAIResponses(specification, messages, toolMessages, tools, uiAdapter, abortSignal, state, toolChoice) {
7612
7608
  if (!OpenAI && !this.openaiClient) {
7613
7609
  throw new Error("OpenAI client not available");
7614
7610
  }
@@ -7623,7 +7619,7 @@ class Graphlit {
7623
7619
  throw new Error("OpenAI module not available");
7624
7620
  })());
7625
7621
  const reasoningEffort = specification.openAI?.reasoningEffort || undefined;
7626
- const toolDefinitions = formatToolsForOpenAIResponses(tools, toolStrict);
7622
+ const toolDefinitions = formatToolsForOpenAIResponses(tools);
7627
7623
  const baseState = state || {
7628
7624
  instructions: extractInstructionsForOpenAIResponses(messages),
7629
7625
  initialInput: formatMessagesForOpenAIResponsesInitialRound(messages),
@@ -7654,7 +7650,7 @@ class Graphlit {
7654
7650
  /**
7655
7651
  * Stream with OpenAI client
7656
7652
  */
7657
- async streamWithOpenAI(specification, messages, tools, uiAdapter, onComplete, abortSignal, toolChoice, toolStrict) {
7653
+ async streamWithOpenAI(specification, messages, tools, uiAdapter, onComplete, abortSignal) {
7658
7654
  // Check if we have either the OpenAI module or a provided client
7659
7655
  if (!OpenAI && !this.openaiClient) {
7660
7656
  throw new Error("OpenAI client not available");
@@ -7678,12 +7674,12 @@ class Graphlit {
7678
7674
  if (reasoningEffort && process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
7679
7675
  console.log(`🧠 [Graphlit SDK] OpenAI reasoning effort: ${reasoningEffort}`);
7680
7676
  }
7681
- await streamWithOpenAI(specification, messages, tools, openaiClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal, reasoningEffort, toolChoice, toolStrict);
7677
+ await streamWithOpenAI(specification, messages, tools, openaiClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal, reasoningEffort);
7682
7678
  }
7683
7679
  /**
7684
7680
  * Stream with Anthropic client
7685
7681
  */
7686
- async streamWithAnthropic(specification, messages, systemPrompt, tools, uiAdapter, onComplete, abortSignal, toolChoice) {
7682
+ async streamWithAnthropic(specification, messages, systemPrompt, tools, uiAdapter, onComplete, abortSignal) {
7687
7683
  // Check if we have either the Anthropic module or a provided client
7688
7684
  if (!Anthropic && !this.anthropicClient) {
7689
7685
  throw new Error("Anthropic client not available");
@@ -7707,7 +7703,7 @@ class Graphlit {
7707
7703
  if (thinkingConfig && process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
7708
7704
  console.log(`🧠 [Graphlit SDK] Anthropic thinking enabled | Budget: ${thinkingConfig.budget_tokens} tokens`);
7709
7705
  }
7710
- await streamWithAnthropic(specification, messages, systemPrompt, tools, anthropicClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal, thinkingConfig, toolChoice);
7706
+ await streamWithAnthropic(specification, messages, systemPrompt, tools, anthropicClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal, thinkingConfig);
7711
7707
  }
7712
7708
  /**
7713
7709
  * Extract thinking configuration from specification
@@ -7738,7 +7734,7 @@ class Graphlit {
7738
7734
  /**
7739
7735
  * Stream with Google client
7740
7736
  */
7741
- async streamWithGoogle(specification, messages, systemPrompt, tools, uiAdapter, onComplete, abortSignal, toolChoice) {
7737
+ async streamWithGoogle(specification, messages, systemPrompt, tools, uiAdapter, onComplete, abortSignal) {
7742
7738
  // Check if we have either the Google module or a provided client
7743
7739
  if (!GoogleGenAI && !this.googleClient) {
7744
7740
  throw new Error("Google GenerativeAI client not available");
@@ -7758,12 +7754,12 @@ class Graphlit {
7758
7754
  if (thinkingConfig && process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
7759
7755
  console.log(`🧠 [Graphlit SDK] Google thinking enabled | Budget: ${thinkingConfig.budget_tokens} tokens`);
7760
7756
  }
7761
- await streamWithGoogle(specification, messages, systemPrompt, tools, googleClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal, thinkingConfig, toolChoice);
7757
+ await streamWithGoogle(specification, messages, systemPrompt, tools, googleClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal, thinkingConfig);
7762
7758
  }
7763
7759
  /**
7764
7760
  * Stream with Groq client (OpenAI-compatible)
7765
7761
  */
7766
- async streamWithGroq(specification, messages, tools, uiAdapter, onComplete, abortSignal, toolChoice) {
7762
+ async streamWithGroq(specification, messages, tools, uiAdapter, onComplete, abortSignal) {
7767
7763
  // Check if we have either the Groq module or a provided client
7768
7764
  if (!Groq && !this.groqClient) {
7769
7765
  throw new Error("Groq client not available");
@@ -7778,12 +7774,12 @@ class Graphlit {
7778
7774
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
7779
7775
  console.log(`šŸš€ [Graphlit SDK] Routing to Groq streaming provider | Spec: ${specification.name} (${specification.id}) | Messages: ${messages.length} | Tools: ${tools?.length || 0}`);
7780
7776
  }
7781
- await streamWithGroq(specification, messages, tools, groqClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal, toolChoice);
7777
+ await streamWithGroq(specification, messages, tools, groqClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal);
7782
7778
  }
7783
7779
  /**
7784
7780
  * Stream with Cerebras client (native SDK)
7785
7781
  */
7786
- async streamWithCerebras(specification, messages, tools, uiAdapter, onComplete, abortSignal, toolChoice) {
7782
+ async streamWithCerebras(specification, messages, tools, uiAdapter, onComplete, abortSignal) {
7787
7783
  // Check if we have either the Cerebras module or a provided client
7788
7784
  if (!Cerebras && !this.cerebrasClient) {
7789
7785
  throw new Error("Cerebras client not available");
@@ -7802,12 +7798,12 @@ class Graphlit {
7802
7798
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
7803
7799
  console.log(`šŸš€ [Graphlit SDK] Routing to Cerebras streaming provider | Spec: ${specification.name} (${specification.id}) | Messages: ${messages.length} | Tools: ${tools?.length || 0}`);
7804
7800
  }
7805
- await streamWithCerebras(specification, messages, tools, cerebrasClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal, toolChoice);
7801
+ await streamWithCerebras(specification, messages, tools, cerebrasClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal);
7806
7802
  }
7807
7803
  /**
7808
7804
  * Stream with Cohere client
7809
7805
  */
7810
- async streamWithCohere(specification, messages, tools, uiAdapter, onComplete, abortSignal, toolChoice) {
7806
+ async streamWithCohere(specification, messages, tools, uiAdapter, onComplete, abortSignal) {
7811
7807
  // Check if we have either the Cohere module or a provided client
7812
7808
  if (!CohereClient && !CohereClientV2 && !this.cohereClient) {
7813
7809
  throw new Error("Cohere client not available");
@@ -7824,12 +7820,12 @@ class Graphlit {
7824
7820
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
7825
7821
  console.log(`šŸš€ [Graphlit SDK] Routing to Cohere streaming provider | Spec: ${specification.name} (${specification.id}) | Messages: ${messages.length} | Tools: ${tools?.length || 0}`);
7826
7822
  }
7827
- await streamWithCohere(specification, messages, tools, cohereClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal, toolChoice);
7823
+ await streamWithCohere(specification, messages, tools, cohereClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal);
7828
7824
  }
7829
7825
  /**
7830
7826
  * Stream with Mistral client
7831
7827
  */
7832
- async streamWithMistral(specification, messages, tools, uiAdapter, onComplete, abortSignal, toolChoice) {
7828
+ async streamWithMistral(specification, messages, tools, uiAdapter, onComplete, abortSignal) {
7833
7829
  // Check if we have either the Mistral module or a provided client
7834
7830
  if (!Mistral && !this.mistralClient) {
7835
7831
  throw new Error("Mistral client not available");
@@ -7862,12 +7858,12 @@ class Graphlit {
7862
7858
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
7863
7859
  console.log(`šŸš€ [Graphlit SDK] Routing to Mistral streaming provider | Spec: ${specification.name} (${specification.id}) | Messages: ${messages.length} | Tools: ${tools?.length || 0}`);
7864
7860
  }
7865
- await streamWithMistral(specification, messages, tools, mistralClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal, toolChoice);
7861
+ await streamWithMistral(specification, messages, tools, mistralClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal);
7866
7862
  }
7867
7863
  /**
7868
7864
  * Stream with Bedrock client
7869
7865
  */
7870
- async streamWithBedrock(specification, messages, systemPrompt, tools, uiAdapter, onComplete, abortSignal, toolChoice) {
7866
+ async streamWithBedrock(specification, messages, systemPrompt, tools, uiAdapter, onComplete, abortSignal) {
7871
7867
  // Check if we have either the Bedrock module or a provided client
7872
7868
  if (!BedrockRuntimeClient && !this.bedrockClient) {
7873
7869
  throw new Error("Bedrock client not available");
@@ -7884,12 +7880,12 @@ class Graphlit {
7884
7880
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
7885
7881
  console.log(`šŸš€ [Graphlit SDK] Routing to Bedrock streaming provider | Spec: ${specification.name} (${specification.id}) | Messages: ${messages.length} | Tools: ${tools?.length || 0} | SystemPrompt: ${systemPrompt ? "Yes" : "No"}`);
7886
7882
  }
7887
- await streamWithBedrock(specification, messages, systemPrompt, tools, bedrockClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal, toolChoice);
7883
+ await streamWithBedrock(specification, messages, systemPrompt, tools, bedrockClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal);
7888
7884
  }
7889
7885
  /**
7890
7886
  * Stream with Deepseek client
7891
7887
  */
7892
- async streamWithDeepseek(specification, messages, tools, uiAdapter, onComplete, abortSignal, toolChoice) {
7888
+ async streamWithDeepseek(specification, messages, tools, uiAdapter, onComplete, abortSignal) {
7893
7889
  // Check if we have either the OpenAI module or a provided Deepseek client
7894
7890
  if (!OpenAI && !this.deepseekClient) {
7895
7891
  throw new Error("Deepseek client not available (requires OpenAI SDK)");
@@ -7910,9 +7906,9 @@ class Graphlit {
7910
7906
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
7911
7907
  console.log(`šŸš€ [Graphlit SDK] Routing to Deepseek streaming provider | Spec: ${specification.name} (${specification.id}) | Messages: ${messages.length} | Tools: ${tools?.length || 0}`);
7912
7908
  }
7913
- await streamWithDeepseek(specification, messages, tools, deepseekClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal, toolChoice);
7909
+ await streamWithDeepseek(specification, messages, tools, deepseekClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal);
7914
7910
  }
7915
- async streamWithXai(specification, messages, tools, uiAdapter, onComplete, abortSignal, toolChoice) {
7911
+ async streamWithXai(specification, messages, tools, uiAdapter, onComplete, abortSignal) {
7916
7912
  // Check if we have either the OpenAI module or a provided xAI client
7917
7913
  if (!OpenAI && !this.xaiClient) {
7918
7914
  throw new Error("xAI client not available (requires OpenAI SDK)");
@@ -7933,7 +7929,7 @@ class Graphlit {
7933
7929
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
7934
7930
  console.log(`šŸš€ [Graphlit SDK] Routing to xAI streaming provider | Spec: ${specification.name} (${specification.id}) | Messages: ${messages.length} | Tools: ${tools?.length || 0}`);
7935
7931
  }
7936
- await streamWithXai(specification, messages, tools, xaiClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal, toolChoice);
7932
+ await streamWithXai(specification, messages, tools, xaiClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal);
7937
7933
  }
7938
7934
  // Helper method to execute tools for promptAgent
7939
7935
  async executeToolsForPromptAgent(toolCalls, toolHandlers, allToolCalls, signal, toolResultTokenLimit = DEFAULT_CONTEXT_STRATEGY.toolResultTokenLimit) {
@@ -56,7 +56,7 @@ export interface OpenAIResponsesToolDefinition {
56
56
  name: string;
57
57
  description?: string;
58
58
  parameters: Record<string, unknown>;
59
- strict: boolean;
59
+ strict: false;
60
60
  }
61
61
  /**
62
62
  * Anthropic message format
@@ -119,7 +119,7 @@ export declare function formatToolsForOpenAIResponses(tools: Array<{
119
119
  name: string;
120
120
  description?: string | null;
121
121
  schema?: string | null;
122
- }> | undefined, strict?: boolean): OpenAIResponsesToolDefinition[] | undefined;
122
+ }> | undefined): OpenAIResponsesToolDefinition[] | undefined;
123
123
  /**
124
124
  * Format GraphQL conversation messages for Anthropic SDK
125
125
  */
@@ -137,7 +137,7 @@ export function formatMessagesForOpenAI(messages) {
137
137
  assistantMessage.tool_calls = message.toolCalls
138
138
  .filter((tc) => tc !== null)
139
139
  .map((toolCall) => ({
140
- id: toolCall.id,
140
+ id: toChatCompletionsCallId(toolCall.id),
141
141
  type: "function",
142
142
  function: {
143
143
  name: toolCall.name,
@@ -151,7 +151,7 @@ export function formatMessagesForOpenAI(messages) {
151
151
  formattedMessages.push({
152
152
  role: "tool",
153
153
  content: stripImagesToText(trimmedMessage),
154
- tool_call_id: message.toolCallId || "",
154
+ tool_call_id: toChatCompletionsCallId(message.toolCallId || ""),
155
155
  });
156
156
  break;
157
157
  default: // User messages
@@ -199,6 +199,22 @@ export function extractInstructionsForOpenAIResponses(messages) {
199
199
  ? systemMessages.join("\n\n")
200
200
  : undefined;
201
201
  }
202
+ // Remap tool call IDs to Responses API format (must start with 'fc_')
203
+ function toResponsesCallId(id) {
204
+ if (id.startsWith("fc_"))
205
+ return id;
206
+ if (id.startsWith("call_"))
207
+ return "fc_" + id.slice(5);
208
+ return "fc_" + id;
209
+ }
210
+ // Remap tool call IDs to Chat Completions format (must start with 'call_')
211
+ function toChatCompletionsCallId(id) {
212
+ if (id.startsWith("call_"))
213
+ return id;
214
+ if (id.startsWith("fc_"))
215
+ return "call_" + id.slice(3);
216
+ return "call_" + id;
217
+ }
202
218
  export function formatMessagesForOpenAIResponsesInitialRound(messages) {
203
219
  const formattedMessages = [];
204
220
  for (const message of messages) {
@@ -228,10 +244,11 @@ export function formatMessagesForOpenAIResponsesInitialRound(messages) {
228
244
  if (!toolCall) {
229
245
  continue;
230
246
  }
247
+ const callId = toResponsesCallId(toolCall.id);
231
248
  formattedMessages.push({
232
249
  type: "function_call",
233
- id: toolCall.id,
234
- call_id: toolCall.id,
250
+ id: callId,
251
+ call_id: callId,
235
252
  name: toolCall.name,
236
253
  arguments: toolCall.arguments,
237
254
  });
@@ -245,7 +262,7 @@ export function formatMessagesForOpenAIResponsesInitialRound(messages) {
245
262
  }
246
263
  formattedMessages.push({
247
264
  type: "function_call_output",
248
- call_id: message.toolCallId,
265
+ call_id: toResponsesCallId(message.toolCallId),
249
266
  output: stripImagesToText(trimmedMessage),
250
267
  });
251
268
  break;
@@ -290,12 +307,12 @@ export function buildResponsesFunctionCallOutputItems(toolMessages) {
290
307
  message.toolCallId.length > 0)
291
308
  .map((message) => ({
292
309
  type: "function_call_output",
293
- call_id: message.toolCallId,
310
+ call_id: toResponsesCallId(message.toolCallId),
294
311
  output: stripImagesToText(message.message?.trim() || ""),
295
312
  }));
296
313
  }
297
314
  export const buildOpenAIResponsesFunctionCallOutputItems = buildResponsesFunctionCallOutputItems;
298
- export function formatToolsForOpenAIResponses(tools, strict) {
315
+ export function formatToolsForOpenAIResponses(tools) {
299
316
  if (!tools?.length) {
300
317
  return undefined;
301
318
  }
@@ -314,7 +331,7 @@ export function formatToolsForOpenAIResponses(tools, strict) {
314
331
  name: tool.name,
315
332
  description: tool.description || undefined,
316
333
  parameters,
317
- strict: strict ?? false,
334
+ strict: false,
318
335
  };
319
336
  });
320
337
  }
@@ -6,7 +6,7 @@ function isFunctionCallOutputItem(item) {
6
6
  item.type === "function_call");
7
7
  }
8
8
  function toToolCallId(item, outputIndex) {
9
- return item.call_id || item.id || `tool_${Date.now()}_${outputIndex}`;
9
+ return item.call_id || item.id || `fc_${Date.now()}_${outputIndex}`;
10
10
  }
11
11
  export async function streamWithOpenAIResponses(specification, instructions, input, tools, openaiClient, onEvent, abortSignal, reasoningEffort, toolChoice) {
12
12
  let fullMessage = "";
@@ -6,8 +6,7 @@ import { ReasoningMetadata } from "../types/ui-events.js";
6
6
  * Stream with OpenAI SDK
7
7
  */
8
8
  export declare function streamWithOpenAI(specification: Specification, messages: OpenAIMessage[], tools: ToolDefinitionInput[] | undefined, openaiClient: any, // OpenAI client instance
9
- onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[], usage?: any, reasoning?: ReasoningMetadata) => void, abortSignal?: AbortSignal, reasoningEffort?: string, // OpenAI reasoning effort level (low, medium, high)
10
- toolChoice?: "auto" | "required" | "none", toolStrict?: boolean): Promise<void>;
9
+ onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[], usage?: any, reasoning?: ReasoningMetadata) => void, abortSignal?: AbortSignal, reasoningEffort?: string): Promise<void>;
11
10
  /**
12
11
  * Stream with Anthropic SDK
13
12
  */
@@ -16,7 +15,7 @@ export declare function streamWithAnthropic(specification: Specification, messag
16
15
  onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[], usage?: any, reasoning?: ReasoningMetadata) => void, abortSignal?: AbortSignal, thinkingConfig?: {
17
16
  type: "enabled";
18
17
  budget_tokens: number;
19
- }, toolChoice?: "auto" | "required" | "none"): Promise<void>;
18
+ }): Promise<void>;
20
19
  /**
21
20
  * Stream with Google SDK
22
21
  */
@@ -24,37 +23,37 @@ export declare function streamWithGoogle(specification: Specification, messages:
24
23
  onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[], usage?: any, reasoning?: ReasoningMetadata) => void, abortSignal?: AbortSignal, thinkingConfig?: {
25
24
  type: "enabled";
26
25
  budget_tokens: number;
27
- }, toolChoice?: "auto" | "required" | "none"): Promise<void>;
26
+ }): Promise<void>;
28
27
  /**
29
28
  * Stream with Groq SDK (OpenAI-compatible)
30
29
  */
31
30
  export declare function streamWithGroq(specification: Specification, messages: OpenAIMessage[], tools: ToolDefinitionInput[] | undefined, groqClient: any, // Groq client instance (OpenAI-compatible)
32
- onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[], usage?: any, reasoning?: ReasoningMetadata) => void, abortSignal?: AbortSignal, toolChoice?: "auto" | "required" | "none"): Promise<void>;
31
+ onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[], usage?: any, reasoning?: ReasoningMetadata) => void, abortSignal?: AbortSignal): Promise<void>;
33
32
  /**
34
33
  * Stream with Cerebras native SDK
35
34
  */
36
35
  export declare function streamWithCerebras(specification: Specification, messages: OpenAIMessage[], tools: ToolDefinitionInput[] | undefined, cerebrasClient: any, // Cerebras native client instance
37
- onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[], usage?: any, reasoning?: ReasoningMetadata) => void, abortSignal?: AbortSignal, toolChoice?: "auto" | "required" | "none"): Promise<void>;
36
+ onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[], usage?: any, reasoning?: ReasoningMetadata) => void, abortSignal?: AbortSignal): Promise<void>;
38
37
  /**
39
38
  * Stream with Deepseek SDK (OpenAI-compatible)
40
39
  */
41
40
  export declare function streamWithDeepseek(specification: Specification, messages: OpenAIMessage[], tools: ToolDefinitionInput[] | undefined, deepseekClient: any, // OpenAI client instance configured for Deepseek
42
- onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[], usage?: any, reasoning?: ReasoningMetadata) => void, abortSignal?: AbortSignal, toolChoice?: "auto" | "required" | "none"): Promise<void>;
41
+ onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[], usage?: any, reasoning?: ReasoningMetadata) => void, abortSignal?: AbortSignal): Promise<void>;
43
42
  /**
44
43
  * Stream with Cohere SDK
45
44
  */
46
45
  export declare function streamWithCohere(specification: Specification, messages: ConversationMessage[], tools: ToolDefinitionInput[] | undefined, cohereClient: any, // CohereClient instance
47
- onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[], usage?: any, reasoning?: ReasoningMetadata) => void, abortSignal?: AbortSignal, toolChoice?: "auto" | "required" | "none"): Promise<void>;
46
+ onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[], usage?: any, reasoning?: ReasoningMetadata) => void, abortSignal?: AbortSignal): Promise<void>;
48
47
  /**
49
48
  * Stream with Mistral SDK
50
49
  */
51
50
  export declare function streamWithMistral(specification: Specification, messages: MistralMessage[], tools: ToolDefinitionInput[] | undefined, mistralClient: any, // Mistral client instance
52
- onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[], usage?: any, reasoning?: ReasoningMetadata) => void, abortSignal?: AbortSignal, toolChoice?: "auto" | "required" | "none"): Promise<void>;
51
+ onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[], usage?: any, reasoning?: ReasoningMetadata) => void, abortSignal?: AbortSignal): Promise<void>;
53
52
  /**
54
53
  * Stream with Bedrock SDK (for Claude models)
55
54
  */
56
55
  export declare function streamWithBedrock(specification: Specification, messages: BedrockMessage[], systemPrompt: string | undefined, tools: ToolDefinitionInput[] | undefined, bedrockClient: any, // BedrockRuntimeClient instance
57
- onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[], usage?: any, reasoning?: ReasoningMetadata) => void, abortSignal?: AbortSignal, toolChoice?: "auto" | "required" | "none"): Promise<void>;
56
+ onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[], usage?: any, reasoning?: ReasoningMetadata) => void, abortSignal?: AbortSignal): Promise<void>;
58
57
  export declare function streamWithXai(specification: Specification, messages: OpenAIMessage[], tools: ToolDefinitionInput[] | undefined, xaiClient: any, // OpenAI client instance configured for xAI
59
- onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[], usage?: any, reasoning?: ReasoningMetadata) => void, abortSignal?: AbortSignal, toolChoice?: "auto" | "required" | "none"): Promise<void>;
58
+ onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[], usage?: any, reasoning?: ReasoningMetadata) => void, abortSignal?: AbortSignal): Promise<void>;
60
59
  export {};
@@ -77,8 +77,7 @@ function cleanSchemaForGoogle(schema) {
77
77
  * Stream with OpenAI SDK
78
78
  */
79
79
  export async function streamWithOpenAI(specification, messages, tools, openaiClient, // OpenAI client instance
80
- onEvent, onComplete, abortSignal, reasoningEffort, // OpenAI reasoning effort level (low, medium, high)
81
- toolChoice, toolStrict) {
80
+ onEvent, onComplete, abortSignal, reasoningEffort) {
82
81
  let fullMessage = "";
83
82
  let toolCalls = [];
84
83
  let usageData = null;
@@ -130,12 +129,8 @@ toolChoice, toolStrict) {
130
129
  name: tool.name,
131
130
  description: tool.description,
132
131
  parameters: tool.schema ? JSON.parse(tool.schema) : {},
133
- ...(toolStrict !== undefined && { strict: toolStrict }),
134
132
  },
135
133
  }));
136
- if (toolChoice) {
137
- streamConfig.tool_choice = toolChoice;
138
- }
139
134
  }
140
135
  // Add reasoning effort for o1 models
141
136
  if (reasoningEffort) {
@@ -427,7 +422,7 @@ toolChoice, toolStrict) {
427
422
  }
428
423
  }
429
424
  export async function streamWithAnthropic(specification, messages, systemPrompt, tools, anthropicClient, // Properly typed Anthropic client
430
- onEvent, onComplete, abortSignal, thinkingConfig, toolChoice) {
425
+ onEvent, onComplete, abortSignal, thinkingConfig) {
431
426
  let fullMessage = "";
432
427
  let toolCalls = [];
433
428
  let usageData = null;
@@ -493,17 +488,6 @@ onEvent, onComplete, abortSignal, thinkingConfig, toolChoice) {
493
488
  description: tool.description,
494
489
  input_schema: tool.schema ? JSON.parse(tool.schema) : {},
495
490
  }));
496
- if (toolChoice) {
497
- // Anthropic uses { type: "auto" }, { type: "any" } (for required), or { type: "none" } (tool_choice not supported for none - omit tools instead)
498
- const anthropicToolChoice = toolChoice === "required"
499
- ? { type: "any" }
500
- : toolChoice === "none"
501
- ? undefined // Anthropic doesn't support { type: "none" } - handled by not passing tools
502
- : { type: "auto" };
503
- if (anthropicToolChoice) {
504
- streamConfig.tool_choice = anthropicToolChoice;
505
- }
506
- }
507
491
  }
508
492
  // Check if this is a 1M context model (beta flag, same underlying model ID)
509
493
  const is1MContext = specification.anthropic?.model ===
@@ -973,7 +957,7 @@ onEvent, onComplete, abortSignal, thinkingConfig, toolChoice) {
973
957
  * Stream with Google SDK
974
958
  */
975
959
  export async function streamWithGoogle(specification, messages, systemPrompt, tools, googleClient, // Google GenerativeAI client instance
976
- onEvent, onComplete, abortSignal, thinkingConfig, toolChoice) {
960
+ onEvent, onComplete, abortSignal, thinkingConfig) {
977
961
  let fullMessage = "";
978
962
  let toolCalls = [];
979
963
  let usageData = null;
@@ -1096,19 +1080,6 @@ onEvent, onComplete, abortSignal, thinkingConfig, toolChoice) {
1096
1080
  // Add tools to config if provided
1097
1081
  if (googleTools) {
1098
1082
  config.tools = googleTools;
1099
- if (toolChoice) {
1100
- // Google uses functionCallingConfig.mode with values AUTO, ANY (for required), NONE
1101
- const googleMode = toolChoice === "required"
1102
- ? "ANY"
1103
- : toolChoice === "none"
1104
- ? "NONE"
1105
- : "AUTO";
1106
- config.toolConfig = {
1107
- functionCallingConfig: {
1108
- mode: googleMode,
1109
- },
1110
- };
1111
- }
1112
1083
  }
1113
1084
  // Call generateContentStream with conversation history
1114
1085
  const streamResponse = await googleClient.models.generateContentStream({
@@ -1439,7 +1410,7 @@ onEvent, onComplete, abortSignal, thinkingConfig, toolChoice) {
1439
1410
  * Stream with Groq SDK (OpenAI-compatible)
1440
1411
  */
1441
1412
  export async function streamWithGroq(specification, messages, tools, groqClient, // Groq client instance (OpenAI-compatible)
1442
- onEvent, onComplete, abortSignal, toolChoice) {
1413
+ onEvent, onComplete, abortSignal) {
1443
1414
  try {
1444
1415
  const modelName = getModelName(specification);
1445
1416
  // Filter or simplify tools for Groq models that have issues
@@ -1480,8 +1451,7 @@ onEvent, onComplete, abortSignal, toolChoice) {
1480
1451
  }
1481
1452
  }
1482
1453
  // Groq uses the same API as OpenAI, so we can reuse the OpenAI streaming logic
1483
- return await streamWithOpenAI(specification, messages, groqTools, groqClient, onEvent, onComplete, abortSignal, undefined, // reasoningEffort
1484
- toolChoice);
1454
+ return await streamWithOpenAI(specification, messages, groqTools, groqClient, onEvent, onComplete, abortSignal, undefined);
1485
1455
  }
1486
1456
  catch (error) {
1487
1457
  // Normalize Groq errors into ProviderError
@@ -1531,7 +1501,7 @@ onEvent, onComplete, abortSignal, toolChoice) {
1531
1501
  * Stream with Cerebras native SDK
1532
1502
  */
1533
1503
  export async function streamWithCerebras(specification, messages, tools, cerebrasClient, // Cerebras native client instance
1534
- onEvent, onComplete, abortSignal, toolChoice) {
1504
+ onEvent, onComplete, abortSignal) {
1535
1505
  let fullMessage = "";
1536
1506
  let toolCalls = [];
1537
1507
  let usageData = null;
@@ -1638,9 +1608,6 @@ onEvent, onComplete, abortSignal, toolChoice) {
1638
1608
  // Add tools if available
1639
1609
  if (cerebrasTools) {
1640
1610
  streamConfig.tools = cerebrasTools;
1641
- if (toolChoice) {
1642
- streamConfig.tool_choice = toolChoice;
1643
- }
1644
1611
  }
1645
1612
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
1646
1613
  console.log(`ā±ļø [Cerebras] Starting LLM call at: ${new Date().toISOString()}`);
@@ -1823,7 +1790,7 @@ onEvent, onComplete, abortSignal, toolChoice) {
1823
1790
  * Stream with Deepseek SDK (OpenAI-compatible)
1824
1791
  */
1825
1792
  export async function streamWithDeepseek(specification, messages, tools, deepseekClient, // OpenAI client instance configured for Deepseek
1826
- onEvent, onComplete, abortSignal, toolChoice) {
1793
+ onEvent, onComplete, abortSignal) {
1827
1794
  let fullMessage = "";
1828
1795
  let toolCalls = [];
1829
1796
  let usageData = null;
@@ -1903,9 +1870,6 @@ onEvent, onComplete, abortSignal, toolChoice) {
1903
1870
  parameters: tool.schema ? JSON.parse(tool.schema) : {},
1904
1871
  },
1905
1872
  }));
1906
- if (toolChoice) {
1907
- streamConfig.tool_choice = toolChoice;
1908
- }
1909
1873
  }
1910
1874
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
1911
1875
  console.log(`ā±ļø [Deepseek] Starting LLM call at: ${new Date().toISOString()}`);
@@ -2170,7 +2134,7 @@ onEvent, onComplete, abortSignal, toolChoice) {
2170
2134
  * Stream with Cohere SDK
2171
2135
  */
2172
2136
  export async function streamWithCohere(specification, messages, tools, cohereClient, // CohereClient instance
2173
- onEvent, onComplete, abortSignal, toolChoice) {
2137
+ onEvent, onComplete, abortSignal) {
2174
2138
  let fullMessage = "";
2175
2139
  let toolCalls = [];
2176
2140
  let usageData = null;
@@ -2273,9 +2237,6 @@ onEvent, onComplete, abortSignal, toolChoice) {
2273
2237
  parameters: tool.schema ? JSON.parse(tool.schema) : {},
2274
2238
  },
2275
2239
  }));
2276
- if (toolChoice) {
2277
- streamConfig.tool_choice = toolChoice;
2278
- }
2279
2240
  }
2280
2241
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2281
2242
  console.log(`šŸ” [Cohere] Final stream config:`, JSON.stringify(streamConfig, null, 2));
@@ -2494,7 +2455,7 @@ onEvent, onComplete, abortSignal, toolChoice) {
2494
2455
  * Stream with Mistral SDK
2495
2456
  */
2496
2457
  export async function streamWithMistral(specification, messages, tools, mistralClient, // Mistral client instance
2497
- onEvent, onComplete, abortSignal, toolChoice) {
2458
+ onEvent, onComplete, abortSignal) {
2498
2459
  let fullMessage = "";
2499
2460
  let toolCalls = [];
2500
2461
  let usageData = null;
@@ -2539,11 +2500,6 @@ onEvent, onComplete, abortSignal, toolChoice) {
2539
2500
  parameters: tool.schema ? JSON.parse(tool.schema) : {},
2540
2501
  },
2541
2502
  }));
2542
- if (toolChoice) {
2543
- // Mistral uses tool_choice with values "auto", "any" (for required), "none"
2544
- const mistralToolChoice = toolChoice === "required" ? "any" : toolChoice;
2545
- streamConfig.tool_choice = mistralToolChoice;
2546
- }
2547
2503
  }
2548
2504
  else {
2549
2505
  console.log(`[Mistral] No tools provided - tools parameter is ${tools === undefined ? "undefined" : "empty array"}`);
@@ -2801,7 +2757,7 @@ onEvent, onComplete, abortSignal, toolChoice) {
2801
2757
  * Stream with Bedrock SDK (for Claude models)
2802
2758
  */
2803
2759
  export async function streamWithBedrock(specification, messages, systemPrompt, tools, bedrockClient, // BedrockRuntimeClient instance
2804
- onEvent, onComplete, abortSignal, toolChoice) {
2760
+ onEvent, onComplete, abortSignal) {
2805
2761
  let fullMessage = "";
2806
2762
  let toolCalls = [];
2807
2763
  let usageData = null;
@@ -2881,17 +2837,6 @@ onEvent, onComplete, abortSignal, toolChoice) {
2881
2837
  },
2882
2838
  })),
2883
2839
  };
2884
- if (toolChoice) {
2885
- // Bedrock uses toolChoice with format { auto: {} }, { any: {} }, or { none: {} } (not supported - omit)
2886
- const bedrockToolChoice = toolChoice === "required"
2887
- ? { any: {} }
2888
- : toolChoice === "auto"
2889
- ? { auto: {} }
2890
- : undefined; // Bedrock doesn't support "none" for toolChoice
2891
- if (bedrockToolChoice) {
2892
- request.toolConfig.toolChoice = bedrockToolChoice;
2893
- }
2894
- }
2895
2840
  }
2896
2841
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2897
2842
  console.log(`šŸ” [Bedrock] Converse request:`, JSON.stringify(request, null, 2));
@@ -3125,14 +3070,13 @@ onEvent, onComplete, abortSignal, toolChoice) {
3125
3070
  }
3126
3071
  }
3127
3072
  export async function streamWithXai(specification, messages, tools, xaiClient, // OpenAI client instance configured for xAI
3128
- onEvent, onComplete, abortSignal, toolChoice) {
3073
+ onEvent, onComplete, abortSignal) {
3129
3074
  try {
3130
3075
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
3131
3076
  console.log(`šŸš€ [xAI] Starting stream | Model: ${getModelName(specification)} | Messages: ${messages.length} | Tools: ${tools?.length || 0}`);
3132
3077
  }
3133
3078
  // xAI uses the same API as OpenAI, so we can reuse the OpenAI streaming logic
3134
- return await streamWithOpenAI(specification, messages, tools, xaiClient, onEvent, onComplete, abortSignal, undefined, // reasoningEffort
3135
- toolChoice);
3079
+ return await streamWithOpenAI(specification, messages, tools, xaiClient, onEvent, onComplete, abortSignal, undefined);
3136
3080
  }
3137
3081
  catch (error) {
3138
3082
  // Normalize xAI errors into ProviderError
@@ -21,10 +21,6 @@ export interface AgentOptions {
21
21
  maxToolRounds?: number;
22
22
  timeout?: number;
23
23
  contextStrategy?: ContextStrategy;
24
- /** Controls whether the model must call a tool. Default: "auto". */
25
- toolChoice?: "auto" | "required" | "none";
26
- /** Enforce strict schema adherence for tool call arguments (OpenAI only). Default: false. */
27
- toolStrict?: boolean;
28
24
  }
29
25
  export interface AgentMetrics {
30
26
  totalTime: number;
@@ -72,10 +68,6 @@ export interface StreamAgentOptions {
72
68
  contextStrategy?: ContextStrategy;
73
69
  /** Default eligible OpenAI GPT-5.4+ models to Responses; false forces legacy Chat Completions. */
74
70
  useResponsesApi?: boolean;
75
- /** Controls whether the model must call a tool. Default: "auto". */
76
- toolChoice?: "auto" | "required" | "none";
77
- /** Enforce strict schema adherence for tool call arguments (OpenAI only). Default: false. */
78
- toolStrict?: boolean;
79
71
  /** Harness-injected instructions appended to the formatted conversation (e.g. wind-down, stuck intervention). */
80
72
  instructions?: string;
81
73
  /** Harness-injected scratchpad text, merged with conversation scratchpad. Placed right before user-prompt. */
@@ -168,10 +160,6 @@ export interface RunAgentOptions {
168
160
  chunkingStrategy?: "character" | "word" | "sentence";
169
161
  smoothingDelay?: number;
170
162
  useResponsesApi?: boolean;
171
- /** Controls whether the model must call a tool. Default: "auto". */
172
- toolChoice?: "auto" | "required" | "none";
173
- /** Enforce strict schema adherence for tool call arguments (OpenAI only). Default: false. */
174
- toolStrict?: boolean;
175
163
  /** Skill references to inject into the agent's context window. Retrieved via querySkills, passed by reference. */
176
164
  skills?: EntityReferenceInput[];
177
165
  }
@@ -221,8 +209,6 @@ export interface StreamingLoopConfig {
221
209
  maxRounds: number;
222
210
  abortSignal: AbortSignal | undefined;
223
211
  useResponsesApi?: boolean;
224
- toolChoice?: "auto" | "required" | "none";
225
- toolStrict?: boolean;
226
212
  correlationId?: string;
227
213
  persona?: EntityReferenceInput;
228
214
  mimeType?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphlit-client",
3
- "version": "1.0.20260408010",
3
+ "version": "1.0.20260408012",
4
4
  "description": "Graphlit API Client for TypeScript",
5
5
  "type": "module",
6
6
  "main": "./dist/client.js",