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 +13 -2
- package/dist/client.js +36 -40
- package/dist/streaming/llm-formatters.d.ts +2 -2
- package/dist/streaming/llm-formatters.js +25 -8
- package/dist/streaming/openai-responses.js +1 -1
- package/dist/streaming/providers.d.ts +10 -11
- package/dist/streaming/providers.js +12 -68
- package/dist/types/agent.d.ts +0 -14
- package/package.json +1 -1
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-
|
|
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-
|
|
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?.
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
7909
|
+
await streamWithDeepseek(specification, messages, tools, deepseekClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal);
|
|
7914
7910
|
}
|
|
7915
|
-
async streamWithXai(specification, messages, tools, uiAdapter, onComplete, abortSignal
|
|
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
|
|
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:
|
|
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
|
|
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:
|
|
234
|
-
call_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
|
|
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:
|
|
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 || `
|
|
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
|
|
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
|
-
}
|
|
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
|
-
}
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
package/dist/types/agent.d.ts
CHANGED
|
@@ -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;
|