graphlit-client 1.0.20250921001 → 1.0.20250924001
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/dist/client.js +1 -1
- package/dist/generated/graphql-documents.js +4 -0
- package/dist/generated/graphql-types.d.ts +39 -4
- package/dist/generated/graphql-types.js +12 -4
- package/dist/streaming/llm-formatters.js +38 -37
- package/dist/streaming/providers.js +45 -21
- package/dist/streaming/ui-event-adapter.d.ts +5 -0
- package/dist/streaming/ui-event-adapter.js +39 -7
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -2486,7 +2486,7 @@ class Graphlit {
|
|
|
2486
2486
|
// Mistral API requires that we don't pass tools when sending tool results
|
|
2487
2487
|
const shouldPassTools = toolResponseCount === 0 ? tools : undefined;
|
|
2488
2488
|
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
2489
|
-
console.log(`🔍 [Mistral] Passing tools: ${shouldPassTools ?
|
|
2489
|
+
console.log(`🔍 [Mistral] Passing tools: ${shouldPassTools ? "YES" : "NO"} (tool responses in messages: ${toolResponseCount})`);
|
|
2490
2490
|
}
|
|
2491
2491
|
await this.streamWithMistral(specification, mistralMessages, shouldPassTools, uiAdapter, (message, calls, usage) => {
|
|
2492
2492
|
roundMessage = message;
|
|
@@ -6696,6 +6696,7 @@ export const GetFeed = gql `
|
|
|
6696
6696
|
enableMeetingRecording
|
|
6697
6697
|
meetingBotName
|
|
6698
6698
|
google {
|
|
6699
|
+
type
|
|
6699
6700
|
calendarId
|
|
6700
6701
|
beforeDate
|
|
6701
6702
|
afterDate
|
|
@@ -6706,6 +6707,7 @@ export const GetFeed = gql `
|
|
|
6706
6707
|
authorizationId
|
|
6707
6708
|
}
|
|
6708
6709
|
microsoft {
|
|
6710
|
+
type
|
|
6709
6711
|
calendarId
|
|
6710
6712
|
beforeDate
|
|
6711
6713
|
afterDate
|
|
@@ -7039,6 +7041,7 @@ export const QueryFeeds = gql `
|
|
|
7039
7041
|
enableMeetingRecording
|
|
7040
7042
|
meetingBotName
|
|
7041
7043
|
google {
|
|
7044
|
+
type
|
|
7042
7045
|
calendarId
|
|
7043
7046
|
beforeDate
|
|
7044
7047
|
afterDate
|
|
@@ -7049,6 +7052,7 @@ export const QueryFeeds = gql `
|
|
|
7049
7052
|
authorizationId
|
|
7050
7053
|
}
|
|
7051
7054
|
microsoft {
|
|
7055
|
+
type
|
|
7052
7056
|
calendarId
|
|
7053
7057
|
beforeDate
|
|
7054
7058
|
afterDate
|
|
@@ -369,11 +369,11 @@ export type AnthropicModelPropertiesUpdateInput = {
|
|
|
369
369
|
};
|
|
370
370
|
/** Anthropic model type */
|
|
371
371
|
export declare enum AnthropicModels {
|
|
372
|
-
/** @deprecated Use Claude
|
|
372
|
+
/** @deprecated Use Claude 4.x instead. */
|
|
373
373
|
Claude_2 = "CLAUDE_2",
|
|
374
|
-
/** @deprecated Use Claude
|
|
374
|
+
/** @deprecated Use Claude 4.x instead. */
|
|
375
375
|
Claude_2_0 = "CLAUDE_2_0",
|
|
376
|
-
/** @deprecated Use Claude
|
|
376
|
+
/** @deprecated Use Claude 4.x instead. */
|
|
377
377
|
Claude_2_1 = "CLAUDE_2_1",
|
|
378
378
|
/** Claude 3.5 Haiku (Latest) */
|
|
379
379
|
Claude_3_5Haiku = "CLAUDE_3_5_HAIKU",
|
|
@@ -381,7 +381,7 @@ export declare enum AnthropicModels {
|
|
|
381
381
|
Claude_3_5Haiku_20241022 = "CLAUDE_3_5_HAIKU_20241022",
|
|
382
382
|
/** Claude 3.5 Sonnet (Latest) */
|
|
383
383
|
Claude_3_5Sonnet = "CLAUDE_3_5_SONNET",
|
|
384
|
-
/** Claude
|
|
384
|
+
/** @deprecated Use Claude 4.x instead. */
|
|
385
385
|
Claude_3_5Sonnet_20240620 = "CLAUDE_3_5_SONNET_20240620",
|
|
386
386
|
/** Claude 3.5 Sonnet (10-22-2024 version) */
|
|
387
387
|
Claude_3_5Sonnet_20241022 = "CLAUDE_3_5_SONNET_20241022",
|
|
@@ -1278,6 +1278,13 @@ export type CalendarFeedPropertiesUpdateInput = {
|
|
|
1278
1278
|
/** The limit of items to be read from feed, defaults to 100. */
|
|
1279
1279
|
readLimit?: InputMaybe<Scalars['Int']['input']>;
|
|
1280
1280
|
};
|
|
1281
|
+
/** Calendar list type */
|
|
1282
|
+
export declare enum CalendarListingTypes {
|
|
1283
|
+
/** Read new calendar events */
|
|
1284
|
+
New = "NEW",
|
|
1285
|
+
/** Read past calendar events */
|
|
1286
|
+
Past = "PAST"
|
|
1287
|
+
}
|
|
1281
1288
|
/** Represents a calendar event recurrence. */
|
|
1282
1289
|
export type CalendarRecurrence = {
|
|
1283
1290
|
__typename?: 'CalendarRecurrence';
|
|
@@ -4862,6 +4869,8 @@ export type GoogleCalendarFeedProperties = {
|
|
|
4862
4869
|
clientSecret?: Maybe<Scalars['String']['output']>;
|
|
4863
4870
|
/** Google OAuth2 refresh token. */
|
|
4864
4871
|
refreshToken?: Maybe<Scalars['String']['output']>;
|
|
4872
|
+
/** Calendar listing type, i.e. past or new events. */
|
|
4873
|
+
type?: Maybe<CalendarListingTypes>;
|
|
4865
4874
|
};
|
|
4866
4875
|
/** Represents Google Calendar properties. */
|
|
4867
4876
|
export type GoogleCalendarFeedPropertiesInput = {
|
|
@@ -4881,19 +4890,29 @@ export type GoogleCalendarFeedPropertiesInput = {
|
|
|
4881
4890
|
clientSecret?: InputMaybe<Scalars['String']['input']>;
|
|
4882
4891
|
/** Google OAuth2 refresh token, requires User authentication type. */
|
|
4883
4892
|
refreshToken?: InputMaybe<Scalars['String']['input']>;
|
|
4893
|
+
/** Calendar listing type, i.e. past or new events. */
|
|
4894
|
+
type?: InputMaybe<CalendarListingTypes>;
|
|
4884
4895
|
};
|
|
4885
4896
|
/** Represents Google Calendar properties. */
|
|
4886
4897
|
export type GoogleCalendarFeedPropertiesUpdateInput = {
|
|
4898
|
+
/** Read calendar events after this date (inclusive), optional. */
|
|
4899
|
+
afterDate?: InputMaybe<Scalars['DateTime']['input']>;
|
|
4887
4900
|
/** Google Calendar authentication type, defaults to User. */
|
|
4888
4901
|
authenticationType?: InputMaybe<GoogleCalendarAuthenticationTypes>;
|
|
4889
4902
|
/** Authentication identifier, for Connector authentication type. */
|
|
4890
4903
|
authorizationId?: InputMaybe<Scalars['String']['input']>;
|
|
4904
|
+
/** Read calendar events before this date (inclusive), optional. */
|
|
4905
|
+
beforeDate?: InputMaybe<Scalars['DateTime']['input']>;
|
|
4906
|
+
/** Google Email calendar identifier, optional. */
|
|
4907
|
+
calendarId?: InputMaybe<Scalars['String']['input']>;
|
|
4891
4908
|
/** Google OAuth2 client identifier, requires User authentication type. */
|
|
4892
4909
|
clientId?: InputMaybe<Scalars['String']['input']>;
|
|
4893
4910
|
/** Google OAuth2 client secret, requires User authentication type. */
|
|
4894
4911
|
clientSecret?: InputMaybe<Scalars['String']['input']>;
|
|
4895
4912
|
/** Google OAuth2 refresh token, requires User authentication type. */
|
|
4896
4913
|
refreshToken?: InputMaybe<Scalars['String']['input']>;
|
|
4914
|
+
/** Calendar listing type, i.e. past or new events. */
|
|
4915
|
+
type?: InputMaybe<CalendarListingTypes>;
|
|
4897
4916
|
};
|
|
4898
4917
|
/** Represents Google Calendar properties. */
|
|
4899
4918
|
export type GoogleCalendarsInput = {
|
|
@@ -8097,6 +8116,8 @@ export type MicrosoftCalendarFeedProperties = {
|
|
|
8097
8116
|
clientSecret?: Maybe<Scalars['String']['output']>;
|
|
8098
8117
|
/** Microsoft Entra ID refresh token. */
|
|
8099
8118
|
refreshToken?: Maybe<Scalars['String']['output']>;
|
|
8119
|
+
/** Calendar listing type, i.e. past or new events. */
|
|
8120
|
+
type?: Maybe<CalendarListingTypes>;
|
|
8100
8121
|
};
|
|
8101
8122
|
/** Represents Microsoft Calendar properties. */
|
|
8102
8123
|
export type MicrosoftCalendarFeedPropertiesInput = {
|
|
@@ -8116,19 +8137,29 @@ export type MicrosoftCalendarFeedPropertiesInput = {
|
|
|
8116
8137
|
clientSecret?: InputMaybe<Scalars['String']['input']>;
|
|
8117
8138
|
/** Microsoft Entra ID refresh token, requires User authentication type. */
|
|
8118
8139
|
refreshToken?: InputMaybe<Scalars['String']['input']>;
|
|
8140
|
+
/** Calendar listing type, i.e. past or new events. */
|
|
8141
|
+
type?: InputMaybe<CalendarListingTypes>;
|
|
8119
8142
|
};
|
|
8120
8143
|
/** Represents Microsoft Calendar properties. */
|
|
8121
8144
|
export type MicrosoftCalendarFeedPropertiesUpdateInput = {
|
|
8145
|
+
/** Read calendar events after this date (inclusive), optional. */
|
|
8146
|
+
afterDate?: InputMaybe<Scalars['DateTime']['input']>;
|
|
8122
8147
|
/** Microsoft Calendar authentication type, defaults to User. */
|
|
8123
8148
|
authenticationType?: InputMaybe<MicrosoftCalendarAuthenticationTypes>;
|
|
8124
8149
|
/** Authentication identifier, for Connector authentication type. */
|
|
8125
8150
|
authorizationId?: InputMaybe<Scalars['String']['input']>;
|
|
8151
|
+
/** Read calendar events before this date (inclusive), optional. */
|
|
8152
|
+
beforeDate?: InputMaybe<Scalars['DateTime']['input']>;
|
|
8153
|
+
/** Microsoft Email calendar identifier, optional. */
|
|
8154
|
+
calendarId?: InputMaybe<Scalars['String']['input']>;
|
|
8126
8155
|
/** Microsoft Entra ID client identifier, requires User authentication type. */
|
|
8127
8156
|
clientId?: InputMaybe<Scalars['String']['input']>;
|
|
8128
8157
|
/** Microsoft Entra ID client secret, requires User authentication type. */
|
|
8129
8158
|
clientSecret?: InputMaybe<Scalars['String']['input']>;
|
|
8130
8159
|
/** Microsoft Entra ID refresh token, requires User authentication type. */
|
|
8131
8160
|
refreshToken?: InputMaybe<Scalars['String']['input']>;
|
|
8161
|
+
/** Calendar listing type, i.e. past or new events. */
|
|
8162
|
+
type?: InputMaybe<CalendarListingTypes>;
|
|
8132
8163
|
};
|
|
8133
8164
|
/** Represents Microsoft Calendar properties. */
|
|
8134
8165
|
export type MicrosoftCalendarsInput = {
|
|
@@ -22910,6 +22941,7 @@ export type GetFeedQuery = {
|
|
|
22910
22941
|
readLimit?: number | null;
|
|
22911
22942
|
google?: {
|
|
22912
22943
|
__typename?: 'GoogleCalendarFeedProperties';
|
|
22944
|
+
type?: CalendarListingTypes | null;
|
|
22913
22945
|
calendarId?: string | null;
|
|
22914
22946
|
beforeDate?: any | null;
|
|
22915
22947
|
afterDate?: any | null;
|
|
@@ -22921,6 +22953,7 @@ export type GetFeedQuery = {
|
|
|
22921
22953
|
} | null;
|
|
22922
22954
|
microsoft?: {
|
|
22923
22955
|
__typename?: 'MicrosoftCalendarFeedProperties';
|
|
22956
|
+
type?: CalendarListingTypes | null;
|
|
22924
22957
|
calendarId?: string | null;
|
|
22925
22958
|
beforeDate?: any | null;
|
|
22926
22959
|
afterDate?: any | null;
|
|
@@ -23321,6 +23354,7 @@ export type QueryFeedsQuery = {
|
|
|
23321
23354
|
readLimit?: number | null;
|
|
23322
23355
|
google?: {
|
|
23323
23356
|
__typename?: 'GoogleCalendarFeedProperties';
|
|
23357
|
+
type?: CalendarListingTypes | null;
|
|
23324
23358
|
calendarId?: string | null;
|
|
23325
23359
|
beforeDate?: any | null;
|
|
23326
23360
|
afterDate?: any | null;
|
|
@@ -23332,6 +23366,7 @@ export type QueryFeedsQuery = {
|
|
|
23332
23366
|
} | null;
|
|
23333
23367
|
microsoft?: {
|
|
23334
23368
|
__typename?: 'MicrosoftCalendarFeedProperties';
|
|
23369
|
+
type?: CalendarListingTypes | null;
|
|
23335
23370
|
calendarId?: string | null;
|
|
23336
23371
|
beforeDate?: any | null;
|
|
23337
23372
|
afterDate?: any | null;
|
|
@@ -7,11 +7,11 @@ export var AlertTypes;
|
|
|
7
7
|
/** Anthropic model type */
|
|
8
8
|
export var AnthropicModels;
|
|
9
9
|
(function (AnthropicModels) {
|
|
10
|
-
/** @deprecated Use Claude
|
|
10
|
+
/** @deprecated Use Claude 4.x instead. */
|
|
11
11
|
AnthropicModels["Claude_2"] = "CLAUDE_2";
|
|
12
|
-
/** @deprecated Use Claude
|
|
12
|
+
/** @deprecated Use Claude 4.x instead. */
|
|
13
13
|
AnthropicModels["Claude_2_0"] = "CLAUDE_2_0";
|
|
14
|
-
/** @deprecated Use Claude
|
|
14
|
+
/** @deprecated Use Claude 4.x instead. */
|
|
15
15
|
AnthropicModels["Claude_2_1"] = "CLAUDE_2_1";
|
|
16
16
|
/** Claude 3.5 Haiku (Latest) */
|
|
17
17
|
AnthropicModels["Claude_3_5Haiku"] = "CLAUDE_3_5_HAIKU";
|
|
@@ -19,7 +19,7 @@ export var AnthropicModels;
|
|
|
19
19
|
AnthropicModels["Claude_3_5Haiku_20241022"] = "CLAUDE_3_5_HAIKU_20241022";
|
|
20
20
|
/** Claude 3.5 Sonnet (Latest) */
|
|
21
21
|
AnthropicModels["Claude_3_5Sonnet"] = "CLAUDE_3_5_SONNET";
|
|
22
|
-
/** Claude
|
|
22
|
+
/** @deprecated Use Claude 4.x instead. */
|
|
23
23
|
AnthropicModels["Claude_3_5Sonnet_20240620"] = "CLAUDE_3_5_SONNET_20240620";
|
|
24
24
|
/** Claude 3.5 Sonnet (10-22-2024 version) */
|
|
25
25
|
AnthropicModels["Claude_3_5Sonnet_20241022"] = "CLAUDE_3_5_SONNET_20241022";
|
|
@@ -247,6 +247,14 @@ export var CalendarEventVisibility;
|
|
|
247
247
|
/** Public event */
|
|
248
248
|
CalendarEventVisibility["Public"] = "PUBLIC";
|
|
249
249
|
})(CalendarEventVisibility || (CalendarEventVisibility = {}));
|
|
250
|
+
/** Calendar list type */
|
|
251
|
+
export var CalendarListingTypes;
|
|
252
|
+
(function (CalendarListingTypes) {
|
|
253
|
+
/** Read new calendar events */
|
|
254
|
+
CalendarListingTypes["New"] = "NEW";
|
|
255
|
+
/** Read past calendar events */
|
|
256
|
+
CalendarListingTypes["Past"] = "PAST";
|
|
257
|
+
})(CalendarListingTypes || (CalendarListingTypes = {}));
|
|
250
258
|
/** Calendar recurrence pattern */
|
|
251
259
|
export var CalendarRecurrencePattern;
|
|
252
260
|
(function (CalendarRecurrencePattern) {
|
|
@@ -108,56 +108,57 @@ export function formatMessagesForAnthropic(messages) {
|
|
|
108
108
|
systemPrompt = trimmedMessage;
|
|
109
109
|
break;
|
|
110
110
|
case ConversationRoleTypes.Assistant:
|
|
111
|
-
const content = [];
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
//
|
|
136
|
-
|
|
137
|
-
.
|
|
138
|
-
.trim();
|
|
139
|
-
if (textWithoutThinking) {
|
|
140
|
-
content.push({
|
|
141
|
-
type: "text",
|
|
142
|
-
text: textWithoutThinking,
|
|
143
|
-
});
|
|
111
|
+
const content = [];
|
|
112
|
+
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
113
|
+
console.log(`🔍 [formatMessagesForAnthropic] Processing assistant message: "${trimmedMessage.substring(0, 200)}..."`);
|
|
114
|
+
console.log(`🔍 [formatMessagesForAnthropic] Has tool calls: ${message.toolCalls?.length || 0}`);
|
|
115
|
+
}
|
|
116
|
+
// Check if message contains thinking content (for Anthropic compatibility)
|
|
117
|
+
const hasThinking = trimmedMessage.includes('<thinking');
|
|
118
|
+
if (hasThinking) {
|
|
119
|
+
// Parse thinking and text content separately for proper Anthropic format
|
|
120
|
+
const thinkingMatch = trimmedMessage.match(/<thinking(?:\s+signature="([^"]*)")?\s*>(.*?)<\/thinking>/s);
|
|
121
|
+
const thinkingSignature = thinkingMatch ? thinkingMatch[1] : '';
|
|
122
|
+
const thinkingContent = thinkingMatch ? thinkingMatch[2].trim() : '';
|
|
123
|
+
const textContent = trimmedMessage.replace(/<thinking(?:\s+signature="[^"]*")?\s*>.*?<\/thinking>/s, '').trim();
|
|
124
|
+
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
125
|
+
console.log(`🔍 [formatMessagesForAnthropic] Found thinking content: ${thinkingContent.length} chars`);
|
|
126
|
+
console.log(`🔍 [formatMessagesForAnthropic] Text content after thinking: "${textContent}"`);
|
|
127
|
+
console.log(`🔍 [formatMessagesForAnthropic] Signature: "${thinkingSignature}"`);
|
|
128
|
+
}
|
|
129
|
+
// CRITICAL: When thinking is enabled, thinking block must come first
|
|
130
|
+
if (thinkingContent) {
|
|
131
|
+
const thinkingBlock = {
|
|
132
|
+
type: "thinking",
|
|
133
|
+
thinking: thinkingContent,
|
|
134
|
+
};
|
|
135
|
+
// Include signature if present
|
|
136
|
+
if (thinkingSignature) {
|
|
137
|
+
thinkingBlock.signature = thinkingSignature;
|
|
144
138
|
}
|
|
139
|
+
content.push(thinkingBlock);
|
|
145
140
|
}
|
|
146
|
-
|
|
147
|
-
|
|
141
|
+
// Add text content after thinking block
|
|
142
|
+
if (textContent) {
|
|
148
143
|
content.push({
|
|
149
144
|
type: "text",
|
|
150
|
-
text:
|
|
145
|
+
text: textContent,
|
|
151
146
|
});
|
|
152
147
|
}
|
|
153
148
|
}
|
|
154
149
|
else if (trimmedMessage) {
|
|
155
|
-
//
|
|
150
|
+
// Regular text content
|
|
151
|
+
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
152
|
+
console.log(`🔍 [formatMessagesForAnthropic] No thinking found, adding text content`);
|
|
153
|
+
}
|
|
156
154
|
content.push({
|
|
157
155
|
type: "text",
|
|
158
156
|
text: trimmedMessage,
|
|
159
157
|
});
|
|
160
158
|
}
|
|
159
|
+
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
160
|
+
console.log(`🔍 [formatMessagesForAnthropic] Content array: ${content.map(c => c.type).join(', ')}`);
|
|
161
|
+
}
|
|
161
162
|
// Add tool uses if present
|
|
162
163
|
if (message.toolCalls && message.toolCalls.length > 0) {
|
|
163
164
|
for (const toolCall of message.toolCalls) {
|
|
@@ -421,15 +421,17 @@ onEvent, onComplete, abortSignal, thinkingConfig) {
|
|
|
421
421
|
if (!modelName) {
|
|
422
422
|
throw new Error(`No model name found for Anthropic specification: ${specification.name}`);
|
|
423
423
|
}
|
|
424
|
+
// Calculate smart default for max_tokens based on thinking mode
|
|
425
|
+
const defaultMaxTokens = thinkingConfig ? 32768 : 8192;
|
|
424
426
|
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
425
|
-
console.log(`🤖 [Anthropic] Model Config: Service=Anthropic | Model=${modelName} | Temperature=${specification.anthropic?.temperature} | MaxTokens=${specification.anthropic?.completionTokenLimit ||
|
|
427
|
+
console.log(`🤖 [Anthropic] Model Config: Service=Anthropic | Model=${modelName} | Temperature=${specification.anthropic?.temperature} | MaxTokens=${specification.anthropic?.completionTokenLimit || defaultMaxTokens} | SystemPrompt=${systemPrompt ? "Yes" : "No"} | Tools=${tools?.length || 0} | Thinking=${!!thinkingConfig} | Spec="${specification.name}"`);
|
|
426
428
|
}
|
|
427
429
|
// Use proper Anthropic SDK types for the config
|
|
428
430
|
const streamConfig = {
|
|
429
431
|
model: modelName,
|
|
430
432
|
messages,
|
|
431
433
|
stream: true,
|
|
432
|
-
max_tokens: specification.anthropic?.completionTokenLimit ||
|
|
434
|
+
max_tokens: specification.anthropic?.completionTokenLimit || defaultMaxTokens,
|
|
433
435
|
};
|
|
434
436
|
// Handle temperature based on thinking configuration
|
|
435
437
|
if (thinkingConfig) {
|
|
@@ -496,14 +498,17 @@ onEvent, onComplete, abortSignal, thinkingConfig) {
|
|
|
496
498
|
console.log(`[Anthropic] Usage data captured from message_start.message:`, usageData);
|
|
497
499
|
}
|
|
498
500
|
}
|
|
499
|
-
else if (chunk.type === "message_delta" &&
|
|
501
|
+
else if (chunk.type === "message_delta" &&
|
|
502
|
+
chunk.usage &&
|
|
503
|
+
!usageData?.input_tokens) {
|
|
500
504
|
// Only use message_delta if we don't have input_tokens yet
|
|
501
505
|
usageData = chunk.usage;
|
|
502
506
|
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
503
507
|
console.log(`[Anthropic] Usage data captured from ${chunk.type}:`, usageData);
|
|
504
508
|
}
|
|
505
509
|
}
|
|
506
|
-
else if ((chunk.type === "message_delta" || chunk.type === "message_start") &&
|
|
510
|
+
else if ((chunk.type === "message_delta" || chunk.type === "message_start") &&
|
|
511
|
+
chunk.usage) {
|
|
507
512
|
// Merge usage data if we have partial data
|
|
508
513
|
if (usageData) {
|
|
509
514
|
usageData = { ...usageData, ...chunk.usage };
|
|
@@ -746,14 +751,24 @@ onEvent, onComplete, abortSignal, thinkingConfig) {
|
|
|
746
751
|
}
|
|
747
752
|
}
|
|
748
753
|
}
|
|
749
|
-
// Final check:
|
|
750
|
-
const validToolCalls = toolCalls
|
|
754
|
+
// Final check: normalize and validate tool calls
|
|
755
|
+
const validToolCalls = toolCalls
|
|
756
|
+
.map((tc, idx) => {
|
|
757
|
+
// For tools with no parameters, Anthropic doesn't send input_json_delta
|
|
758
|
+
// So we need to convert empty arguments to valid JSON
|
|
759
|
+
if (tc.arguments === "") {
|
|
760
|
+
tc.arguments = "{}";
|
|
761
|
+
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
762
|
+
console.log(`[Anthropic] Normalized empty arguments to "{}" for tool ${tc.name}`);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
751
765
|
if (!isValidJSON(tc.arguments)) {
|
|
752
766
|
console.warn(`[Anthropic] Filtering out incomplete tool call ${idx} (${tc.name}) with INVALID JSON (${tc.arguments.length} chars)`);
|
|
753
|
-
return
|
|
767
|
+
return null;
|
|
754
768
|
}
|
|
755
|
-
return
|
|
756
|
-
})
|
|
769
|
+
return tc;
|
|
770
|
+
})
|
|
771
|
+
.filter((tc) => tc !== null);
|
|
757
772
|
if (toolCalls.length !== validToolCalls.length) {
|
|
758
773
|
console.log(`[Anthropic] Filtered out ${toolCalls.length - validToolCalls.length} incomplete tool calls`);
|
|
759
774
|
console.log(`[Anthropic] Successfully processed ${validToolCalls.length} valid tool calls`);
|
|
@@ -825,19 +840,26 @@ onEvent, onComplete, abortSignal, thinkingConfig) {
|
|
|
825
840
|
}
|
|
826
841
|
console.log(`✅ [Anthropic] Final message (${fullMessage.length} chars): "${fullMessage}"`);
|
|
827
842
|
}
|
|
828
|
-
// Include thinking content in
|
|
829
|
-
let
|
|
830
|
-
if (
|
|
831
|
-
|
|
832
|
-
|
|
843
|
+
// Include thinking content in message when there are tool calls (required by Anthropic API)
|
|
844
|
+
let messageWithThinking = fullMessage;
|
|
845
|
+
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
846
|
+
console.log(`🧠 [Anthropic] Debug - validToolCalls: ${validToolCalls.length}, thinking content: ${completeThinkingContent.length} chars, fullMessage: ${fullMessage.length} chars`);
|
|
847
|
+
}
|
|
848
|
+
if (validToolCalls.length > 0 && completeThinkingContent.trim()) {
|
|
849
|
+
// Include thinking content with signature for API compatibility
|
|
850
|
+
const thinkingXml = completeThinkingSignature
|
|
833
851
|
? `<thinking signature="${completeThinkingSignature}">${completeThinkingContent}</thinking>`
|
|
834
852
|
: `<thinking>${completeThinkingContent}</thinking>`;
|
|
835
|
-
|
|
853
|
+
messageWithThinking = `${thinkingXml}\n${fullMessage}`.trim();
|
|
836
854
|
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
837
|
-
console.log(`🧠 [Anthropic] Including thinking content (${completeThinkingContent.length} chars
|
|
855
|
+
console.log(`🧠 [Anthropic] Including thinking content with message due to tool calls (${completeThinkingContent.length} chars, signature: ${completeThinkingSignature?.length || 0})`);
|
|
856
|
+
console.log(`🧠 [Anthropic] Final stored message: "${messageWithThinking}"`);
|
|
838
857
|
}
|
|
839
858
|
}
|
|
840
|
-
|
|
859
|
+
else if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING && completeThinkingContent.trim()) {
|
|
860
|
+
console.log(`🧠 [Anthropic] Thinking content captured (${completeThinkingContent.length} chars) - not including (no tool calls)`);
|
|
861
|
+
}
|
|
862
|
+
onComplete(messageWithThinking, validToolCalls, usageData);
|
|
841
863
|
}
|
|
842
864
|
catch (error) {
|
|
843
865
|
// Handle Anthropic-specific errors
|
|
@@ -1095,7 +1117,8 @@ onEvent, onComplete, abortSignal) {
|
|
|
1095
1117
|
continue;
|
|
1096
1118
|
}
|
|
1097
1119
|
// Only add if it's not already included in fullMessage
|
|
1098
|
-
if (!fullMessage.includes(finalText) &&
|
|
1120
|
+
if (!fullMessage.includes(finalText) &&
|
|
1121
|
+
!fullMessage.endsWith(finalText)) {
|
|
1099
1122
|
fullMessage += finalText;
|
|
1100
1123
|
onEvent({
|
|
1101
1124
|
type: "token",
|
|
@@ -1526,7 +1549,8 @@ onEvent, onComplete, abortSignal) {
|
|
|
1526
1549
|
}
|
|
1527
1550
|
}
|
|
1528
1551
|
// Check for finish reason
|
|
1529
|
-
if (chunk.choices[0].finish_reason === "tool_calls" &&
|
|
1552
|
+
if (chunk.choices[0].finish_reason === "tool_calls" &&
|
|
1553
|
+
toolCalls.length > 0) {
|
|
1530
1554
|
// Emit tool_call_parsed events for completed tool calls
|
|
1531
1555
|
for (const toolCall of toolCalls) {
|
|
1532
1556
|
onEvent({
|
|
@@ -2227,7 +2251,7 @@ onEvent, onComplete, abortSignal) {
|
|
|
2227
2251
|
}));
|
|
2228
2252
|
}
|
|
2229
2253
|
else {
|
|
2230
|
-
console.log(`[Mistral] No tools provided - tools parameter is ${tools === undefined ?
|
|
2254
|
+
console.log(`[Mistral] No tools provided - tools parameter is ${tools === undefined ? "undefined" : "empty array"}`);
|
|
2231
2255
|
}
|
|
2232
2256
|
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
2233
2257
|
console.log(`[Mistral] Stream config:`, JSON.stringify({
|
|
@@ -2274,7 +2298,7 @@ onEvent, onComplete, abortSignal) {
|
|
|
2274
2298
|
console.log(`[Mistral] Attempting to create stream with retry configuration`);
|
|
2275
2299
|
}
|
|
2276
2300
|
// Log final config being sent
|
|
2277
|
-
console.log(`[Mistral] Sending request with tools: ${streamConfig.tools ?
|
|
2301
|
+
console.log(`[Mistral] Sending request with tools: ${streamConfig.tools ? "YES" : "NO"}`);
|
|
2278
2302
|
stream = await mistralClient.chat.stream(streamConfig, {
|
|
2279
2303
|
retries: {
|
|
2280
2304
|
strategy: "backoff",
|
|
@@ -26,6 +26,7 @@ export declare class UIEventAdapter {
|
|
|
26
26
|
private chunkQueue;
|
|
27
27
|
private contextWindowUsage?;
|
|
28
28
|
private finalMetrics?;
|
|
29
|
+
private roundThinkingContent?;
|
|
29
30
|
private reasoningContent;
|
|
30
31
|
private reasoningFormat?;
|
|
31
32
|
private reasoningSignature?;
|
|
@@ -82,4 +83,8 @@ export declare class UIEventAdapter {
|
|
|
82
83
|
* Set usage data from native provider
|
|
83
84
|
*/
|
|
84
85
|
setUsageData(usage: any): void;
|
|
86
|
+
/**
|
|
87
|
+
* Set thinking content for this round (for conversation history formatting)
|
|
88
|
+
*/
|
|
89
|
+
setRoundThinkingContent(thinkingContent: string): void;
|
|
85
90
|
}
|
|
@@ -25,6 +25,7 @@ export class UIEventAdapter {
|
|
|
25
25
|
chunkQueue = []; // Queue of chunks waiting to be emitted
|
|
26
26
|
contextWindowUsage;
|
|
27
27
|
finalMetrics;
|
|
28
|
+
roundThinkingContent; // Store thinking content for conversation history
|
|
28
29
|
reasoningContent = "";
|
|
29
30
|
reasoningFormat;
|
|
30
31
|
reasoningSignature;
|
|
@@ -130,14 +131,16 @@ export class UIEventAdapter {
|
|
|
130
131
|
this.lastTokenTime = now;
|
|
131
132
|
this.tokenCount++;
|
|
132
133
|
// Check if we're resuming after tool calls and need to add newlines
|
|
133
|
-
if (this.hadToolCallsBeforeResume &&
|
|
134
|
+
if (this.hadToolCallsBeforeResume &&
|
|
135
|
+
this.hasToolCallsInProgress === false) {
|
|
134
136
|
// We had tool calls before and now we're receiving content again
|
|
135
137
|
// Add double newline to separate the content from tool results
|
|
136
|
-
if (this.currentMessage.length > 0 &&
|
|
138
|
+
if (this.currentMessage.length > 0 &&
|
|
139
|
+
!this.currentMessage.endsWith("\n\n")) {
|
|
137
140
|
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
138
141
|
console.log(`📝 [UIEventAdapter] Adding newlines after tool calls before resuming content`);
|
|
139
142
|
}
|
|
140
|
-
this.currentMessage +=
|
|
143
|
+
this.currentMessage += "\n\n";
|
|
141
144
|
}
|
|
142
145
|
// Reset the flag now that we've added the newlines
|
|
143
146
|
this.hadToolCallsBeforeResume = false;
|
|
@@ -383,6 +386,17 @@ export class UIEventAdapter {
|
|
|
383
386
|
}
|
|
384
387
|
// Store final metrics for later retrieval
|
|
385
388
|
this.finalMetrics = finalMetrics;
|
|
389
|
+
// Check if there are tool calls that haven't been executed yet
|
|
390
|
+
const hasPendingToolCalls = Array.from(this.activeToolCalls.values()).some((toolData) => toolData.status === "ready" ||
|
|
391
|
+
toolData.status === "preparing" ||
|
|
392
|
+
toolData.status === "executing");
|
|
393
|
+
if (hasPendingToolCalls) {
|
|
394
|
+
// Don't emit conversation_completed yet - tool execution will continue
|
|
395
|
+
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
396
|
+
console.log(`🔄 [UIEventAdapter] Skipping conversation_completed - ${this.activeToolCalls.size} tool calls pending execution`);
|
|
397
|
+
}
|
|
398
|
+
return; // Exit without emitting conversation_completed
|
|
399
|
+
}
|
|
386
400
|
// Include context window usage if available
|
|
387
401
|
const event = {
|
|
388
402
|
type: "conversation_completed",
|
|
@@ -395,10 +409,19 @@ export class UIEventAdapter {
|
|
|
395
409
|
// Add native provider usage data if available
|
|
396
410
|
if (this.usageData) {
|
|
397
411
|
event.usage = {
|
|
398
|
-
promptTokens: this.usageData.prompt_tokens ||
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
412
|
+
promptTokens: this.usageData.prompt_tokens ||
|
|
413
|
+
this.usageData.promptTokens ||
|
|
414
|
+
this.usageData.input_tokens ||
|
|
415
|
+
0,
|
|
416
|
+
completionTokens: this.usageData.completion_tokens ||
|
|
417
|
+
this.usageData.completionTokens ||
|
|
418
|
+
this.usageData.output_tokens ||
|
|
419
|
+
0,
|
|
420
|
+
totalTokens: this.usageData.total_tokens ||
|
|
421
|
+
this.usageData.totalTokens ||
|
|
422
|
+
(this.usageData.input_tokens || 0) +
|
|
423
|
+
(this.usageData.output_tokens || 0) ||
|
|
424
|
+
0,
|
|
402
425
|
model: this.model,
|
|
403
426
|
provider: this.modelService,
|
|
404
427
|
};
|
|
@@ -635,4 +658,13 @@ export class UIEventAdapter {
|
|
|
635
658
|
console.log(`📊 [UIEventAdapter] Usage data set:`, usage);
|
|
636
659
|
}
|
|
637
660
|
}
|
|
661
|
+
/**
|
|
662
|
+
* Set thinking content for this round (for conversation history formatting)
|
|
663
|
+
*/
|
|
664
|
+
setRoundThinkingContent(thinkingContent) {
|
|
665
|
+
this.roundThinkingContent = thinkingContent;
|
|
666
|
+
if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
|
|
667
|
+
console.log(`🧠 [UIEventAdapter] Thinking content set for conversation history (${thinkingContent.length} chars)`);
|
|
668
|
+
}
|
|
669
|
+
}
|
|
638
670
|
}
|