graphlit-client 1.0.20250704001 → 1.0.20250710001

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.d.ts CHANGED
@@ -48,6 +48,7 @@ declare class Graphlit {
48
48
  private mistralClient?;
49
49
  private bedrockClient?;
50
50
  private deepseekClient?;
51
+ private xaiClient?;
51
52
  constructor(organizationIdOrOptions?: string | GraphlitClientOptions, environmentId?: string, jwtSecret?: string, ownerId?: string, userId?: string, apiUri?: string);
52
53
  refreshClient(): void;
53
54
  /**
@@ -95,6 +96,11 @@ declare class Graphlit {
95
96
  * @param client - OpenAI client instance configured for Deepseek (e.g., new OpenAI({ baseURL: "https://api.deepseek.com", apiKey: "..." }))
96
97
  */
97
98
  setDeepseekClient(client: any): void;
99
+ /**
100
+ * Set a custom xAI client instance for streaming
101
+ * @param client - OpenAI client instance configured for xAI (e.g., new OpenAI({ baseURL: "https://api.x.ai/v1", apiKey: "..." }))
102
+ */
103
+ setXaiClient(client: any): void;
98
104
  /**
99
105
  * Update retry configuration and refresh the Apollo client
100
106
  * @param retryConfig - New retry configuration
@@ -505,6 +511,7 @@ declare class Graphlit {
505
511
  * Stream with Deepseek client
506
512
  */
507
513
  private streamWithDeepseek;
514
+ private streamWithXai;
508
515
  private executeToolsForPromptAgent;
509
516
  private prettyPrintGraphQLError;
510
517
  private mutateAndCheckError;
package/dist/client.js CHANGED
@@ -9,7 +9,7 @@ import * as dotenv from "dotenv";
9
9
  import { getServiceType, getModelName } from "./model-mapping.js";
10
10
  import { UIEventAdapter } from "./streaming/ui-event-adapter.js";
11
11
  import { formatMessagesForOpenAI, formatMessagesForAnthropic, formatMessagesForGoogle, formatMessagesForMistral, formatMessagesForBedrock, } from "./streaming/llm-formatters.js";
12
- import { streamWithOpenAI, streamWithAnthropic, streamWithGoogle, streamWithGroq, streamWithCerebras, streamWithCohere, streamWithMistral, streamWithBedrock, streamWithDeepseek, } from "./streaming/providers.js";
12
+ import { streamWithOpenAI, streamWithAnthropic, streamWithGoogle, streamWithGroq, streamWithCerebras, streamWithCohere, streamWithMistral, streamWithBedrock, streamWithDeepseek, streamWithXai, } from "./streaming/providers.js";
13
13
  // Optional imports for streaming LLM clients
14
14
  // These are peer dependencies and may not be installed
15
15
  // We need to use createRequire for optional dependencies to avoid build errors
@@ -132,6 +132,7 @@ class Graphlit {
132
132
  mistralClient;
133
133
  bedrockClient;
134
134
  deepseekClient;
135
+ xaiClient;
135
136
  constructor(organizationIdOrOptions, environmentId, jwtSecret, ownerId, userId, apiUri) {
136
137
  // Handle both old constructor signature and new options object
137
138
  let options;
@@ -331,6 +332,13 @@ class Graphlit {
331
332
  setDeepseekClient(client) {
332
333
  this.deepseekClient = client;
333
334
  }
335
+ /**
336
+ * Set a custom xAI client instance for streaming
337
+ * @param client - OpenAI client instance configured for xAI (e.g., new OpenAI({ baseURL: "https://api.x.ai/v1", apiKey: "..." }))
338
+ */
339
+ setXaiClient(client) {
340
+ this.xaiClient = client;
341
+ }
334
342
  /**
335
343
  * Update retry configuration and refresh the Apollo client
336
344
  * @param retryConfig - New retry configuration
@@ -1823,6 +1831,8 @@ class Graphlit {
1823
1831
  return hasBedrockClient;
1824
1832
  case Types.ModelServiceTypes.Deepseek:
1825
1833
  return OpenAI !== undefined || this.deepseekClient !== undefined;
1834
+ case Types.ModelServiceTypes.Xai:
1835
+ return OpenAI !== undefined || this.xaiClient !== undefined;
1826
1836
  default:
1827
1837
  return false;
1828
1838
  }
@@ -1839,6 +1849,8 @@ class Graphlit {
1839
1849
  this.cohereClient !== undefined;
1840
1850
  const hasMistral = Mistral !== undefined || this.mistralClient !== undefined;
1841
1851
  const hasBedrock = BedrockRuntimeClient !== undefined || this.bedrockClient !== undefined;
1852
+ const hasDeepseek = OpenAI !== undefined || this.deepseekClient !== undefined;
1853
+ const hasXai = OpenAI !== undefined || this.xaiClient !== undefined;
1842
1854
  return (hasOpenAI ||
1843
1855
  hasAnthropic ||
1844
1856
  hasGoogle ||
@@ -1846,7 +1858,9 @@ class Graphlit {
1846
1858
  hasCerebras ||
1847
1859
  hasCohere ||
1848
1860
  hasMistral ||
1849
- hasBedrock);
1861
+ hasBedrock ||
1862
+ hasDeepseek ||
1863
+ hasXai);
1850
1864
  }
1851
1865
  /**
1852
1866
  * Execute an agent with non-streaming response
@@ -2294,9 +2308,12 @@ class Graphlit {
2294
2308
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING_MESSAGES) {
2295
2309
  console.log(`šŸ” [OpenAI] Sending ${openaiMessages.length} messages to LLM: ${JSON.stringify(openaiMessages)}`);
2296
2310
  }
2297
- await this.streamWithOpenAI(specification, openaiMessages, tools, uiAdapter, (message, calls) => {
2311
+ await this.streamWithOpenAI(specification, openaiMessages, tools, uiAdapter, (message, calls, usage) => {
2298
2312
  roundMessage = message;
2299
2313
  toolCalls = calls;
2314
+ if (usage) {
2315
+ uiAdapter.setUsageData(usage);
2316
+ }
2300
2317
  }, abortSignal);
2301
2318
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2302
2319
  console.log(`\nšŸ [Streaming] OpenAI native streaming completed (Round ${currentRound})`);
@@ -2311,9 +2328,12 @@ class Graphlit {
2311
2328
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING_MESSAGES) {
2312
2329
  console.log(`šŸ” [Anthropic] Sending ${anthropicMessages.length} messages to LLM (system: ${system ? "yes" : "no"}): ${JSON.stringify(anthropicMessages)}`);
2313
2330
  }
2314
- await this.streamWithAnthropic(specification, anthropicMessages, system, tools, uiAdapter, (message, calls) => {
2331
+ await this.streamWithAnthropic(specification, anthropicMessages, system, tools, uiAdapter, (message, calls, usage) => {
2315
2332
  roundMessage = message;
2316
2333
  toolCalls = calls;
2334
+ if (usage) {
2335
+ uiAdapter.setUsageData(usage);
2336
+ }
2317
2337
  }, abortSignal);
2318
2338
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2319
2339
  console.log(`\nšŸ [Streaming] Anthropic native streaming completed (Round ${currentRound})`);
@@ -2330,9 +2350,12 @@ class Graphlit {
2330
2350
  }
2331
2351
  // Google doesn't use system prompts separately, they're incorporated into messages
2332
2352
  await this.streamWithGoogle(specification, googleMessages, undefined, // systemPrompt - Google handles this differently
2333
- tools, uiAdapter, (message, calls) => {
2353
+ tools, uiAdapter, (message, calls, usage) => {
2334
2354
  roundMessage = message;
2335
2355
  toolCalls = calls;
2356
+ if (usage) {
2357
+ uiAdapter.setUsageData(usage);
2358
+ }
2336
2359
  }, abortSignal);
2337
2360
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2338
2361
  console.log(`\nšŸ [Streaming] Google native streaming completed (Round ${currentRound})`);
@@ -2347,9 +2370,12 @@ class Graphlit {
2347
2370
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING_MESSAGES) {
2348
2371
  console.log(`šŸ” [Groq] Sending ${groqMessages.length} messages to LLM: ${JSON.stringify(groqMessages)}`);
2349
2372
  }
2350
- await this.streamWithGroq(specification, groqMessages, tools, uiAdapter, (message, calls) => {
2373
+ await this.streamWithGroq(specification, groqMessages, tools, uiAdapter, (message, calls, usage) => {
2351
2374
  roundMessage = message;
2352
2375
  toolCalls = calls;
2376
+ if (usage) {
2377
+ uiAdapter.setUsageData(usage);
2378
+ }
2353
2379
  }, abortSignal);
2354
2380
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2355
2381
  console.log(`\nšŸ [Streaming] Groq native streaming completed (Round ${currentRound})`);
@@ -2364,9 +2390,12 @@ class Graphlit {
2364
2390
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING_MESSAGES) {
2365
2391
  console.log(`šŸ” [Cerebras] Sending ${cerebrasMessages.length} messages to LLM: ${JSON.stringify(cerebrasMessages)}`);
2366
2392
  }
2367
- await this.streamWithCerebras(specification, cerebrasMessages, tools, uiAdapter, (message, calls) => {
2393
+ await this.streamWithCerebras(specification, cerebrasMessages, tools, uiAdapter, (message, calls, usage) => {
2368
2394
  roundMessage = message;
2369
2395
  toolCalls = calls;
2396
+ if (usage) {
2397
+ uiAdapter.setUsageData(usage);
2398
+ }
2370
2399
  }, abortSignal);
2371
2400
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2372
2401
  console.log(`\nšŸ [Streaming] Cerebras native streaming completed (Round ${currentRound})`);
@@ -2381,9 +2410,12 @@ class Graphlit {
2381
2410
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING_MESSAGES) {
2382
2411
  console.log(`šŸ” [Cohere] Sending ${messages.length} messages to LLM`);
2383
2412
  }
2384
- await this.streamWithCohere(specification, messages, tools, uiAdapter, (message, calls) => {
2413
+ await this.streamWithCohere(specification, messages, tools, uiAdapter, (message, calls, usage) => {
2385
2414
  roundMessage = message;
2386
2415
  toolCalls = calls;
2416
+ if (usage) {
2417
+ uiAdapter.setUsageData(usage);
2418
+ }
2387
2419
  }, abortSignal);
2388
2420
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2389
2421
  console.log(`\nšŸ [Streaming] Cohere native streaming completed (Round ${currentRound})`);
@@ -2411,9 +2443,12 @@ class Graphlit {
2411
2443
  console.log(`šŸ” [Mistral] IMPORTANT: We have tool responses, should we still pass tools?`);
2412
2444
  }
2413
2445
  }
2414
- await this.streamWithMistral(specification, mistralMessages, tools, uiAdapter, (message, calls) => {
2446
+ await this.streamWithMistral(specification, mistralMessages, tools, uiAdapter, (message, calls, usage) => {
2415
2447
  roundMessage = message;
2416
2448
  toolCalls = calls;
2449
+ if (usage) {
2450
+ uiAdapter.setUsageData(usage);
2451
+ }
2417
2452
  }, abortSignal);
2418
2453
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2419
2454
  console.log(`\nšŸ [Streaming] Mistral native streaming completed (Round ${currentRound})`);
@@ -2428,9 +2463,12 @@ class Graphlit {
2428
2463
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING_MESSAGES) {
2429
2464
  console.log(`šŸ” [Bedrock] Sending ${bedrockMessages.length} messages to LLM (system: ${system ? "yes" : "no"}): ${JSON.stringify(bedrockMessages)}`);
2430
2465
  }
2431
- await this.streamWithBedrock(specification, bedrockMessages, system, tools, uiAdapter, (message, calls) => {
2466
+ await this.streamWithBedrock(specification, bedrockMessages, system, tools, uiAdapter, (message, calls, usage) => {
2432
2467
  roundMessage = message;
2433
2468
  toolCalls = calls;
2469
+ if (usage) {
2470
+ uiAdapter.setUsageData(usage);
2471
+ }
2434
2472
  }, abortSignal);
2435
2473
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2436
2474
  console.log(`\nšŸ [Streaming] Bedrock native streaming completed (Round ${currentRound})`);
@@ -2445,14 +2483,37 @@ class Graphlit {
2445
2483
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING_MESSAGES) {
2446
2484
  console.log(`šŸ” [Deepseek] Sending ${deepseekMessages.length} messages to LLM: ${JSON.stringify(deepseekMessages)}`);
2447
2485
  }
2448
- await this.streamWithDeepseek(specification, deepseekMessages, tools, uiAdapter, (message, calls) => {
2486
+ await this.streamWithDeepseek(specification, deepseekMessages, tools, uiAdapter, (message, calls, usage) => {
2449
2487
  roundMessage = message;
2450
2488
  toolCalls = calls;
2489
+ if (usage) {
2490
+ uiAdapter.setUsageData(usage);
2491
+ }
2451
2492
  }, abortSignal);
2452
2493
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2453
2494
  console.log(`\nšŸ [Streaming] Deepseek native streaming completed (Round ${currentRound})`);
2454
2495
  }
2455
2496
  }
2497
+ else if (serviceType === Types.ModelServiceTypes.Xai &&
2498
+ (OpenAI || this.xaiClient)) {
2499
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2500
+ console.log(`\nāœ… [Streaming] Using xAI native streaming (Round ${currentRound})`);
2501
+ }
2502
+ const xaiMessages = formatMessagesForOpenAI(messages); // xAI uses OpenAI format
2503
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING_MESSAGES) {
2504
+ console.log(`šŸ” [xAI] Sending ${xaiMessages.length} messages to LLM: ${JSON.stringify(xaiMessages)}`);
2505
+ }
2506
+ await this.streamWithXai(specification, xaiMessages, tools, uiAdapter, (message, calls, usage) => {
2507
+ roundMessage = message;
2508
+ toolCalls = calls;
2509
+ if (usage) {
2510
+ uiAdapter.setUsageData(usage);
2511
+ }
2512
+ }, abortSignal);
2513
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2514
+ console.log(`\nšŸ [Streaming] xAI native streaming completed (Round ${currentRound})`);
2515
+ }
2516
+ }
2456
2517
  else {
2457
2518
  // Fallback to non-streaming
2458
2519
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
@@ -2994,6 +3055,27 @@ class Graphlit {
2994
3055
  }
2995
3056
  await streamWithDeepseek(specification, messages, tools, deepseekClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal);
2996
3057
  }
3058
+ async streamWithXai(specification, messages, tools, uiAdapter, onComplete, abortSignal) {
3059
+ // Check if we have either the OpenAI module or a provided xAI client
3060
+ if (!OpenAI && !this.xaiClient) {
3061
+ throw new Error("xAI client not available (requires OpenAI SDK)");
3062
+ }
3063
+ // Use provided client or create a new one with xAI base URL
3064
+ const xaiClient = this.xaiClient ||
3065
+ (OpenAI
3066
+ ? new OpenAI({
3067
+ baseURL: "https://api.x.ai/v1",
3068
+ apiKey: process.env.XAI_API_KEY || "",
3069
+ })
3070
+ : null);
3071
+ if (!xaiClient) {
3072
+ throw new Error("Failed to create xAI client");
3073
+ }
3074
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
3075
+ console.log(`šŸš€ [Graphlit SDK] Routing to xAI streaming provider | Spec: ${specification.name} (${specification.id}) | Messages: ${messages.length} | Tools: ${tools?.length || 0}`);
3076
+ }
3077
+ await streamWithXai(specification, messages, tools, xaiClient, (event) => uiAdapter.handleEvent(event), onComplete, abortSignal);
3078
+ }
2997
3079
  // Helper method to execute tools for promptAgent
2998
3080
  async executeToolsForPromptAgent(toolCalls, toolHandlers, allToolCalls, signal) {
2999
3081
  const responses = [];
@@ -9223,6 +9223,16 @@ export const GetSpecification = gql `
9223
9223
  temperature
9224
9224
  probability
9225
9225
  }
9226
+ xai {
9227
+ tokenLimit
9228
+ completionTokenLimit
9229
+ model
9230
+ key
9231
+ modelName
9232
+ endpoint
9233
+ temperature
9234
+ probability
9235
+ }
9226
9236
  groq {
9227
9237
  tokenLimit
9228
9238
  completionTokenLimit
@@ -9583,6 +9593,16 @@ export const QuerySpecifications = gql `
9583
9593
  temperature
9584
9594
  probability
9585
9595
  }
9596
+ xai {
9597
+ tokenLimit
9598
+ completionTokenLimit
9599
+ model
9600
+ key
9601
+ modelName
9602
+ endpoint
9603
+ temperature
9604
+ probability
9605
+ }
9586
9606
  groq {
9587
9607
  tokenLimit
9588
9608
  completionTokenLimit
@@ -399,13 +399,13 @@ export declare enum AnthropicModels {
399
399
  Claude_3Haiku = "CLAUDE_3_HAIKU",
400
400
  /** Claude 3 Haiku (03-07-2024 version) */
401
401
  Claude_3Haiku_20240307 = "CLAUDE_3_HAIKU_20240307",
402
- /** Claude 3 Opus (Latest) */
402
+ /** @deprecated Use Claude 4 Opus instead. */
403
403
  Claude_3Opus = "CLAUDE_3_OPUS",
404
404
  /** Claude 3 Opus (02-29-2024 version) */
405
405
  Claude_3Opus_20240229 = "CLAUDE_3_OPUS_20240229",
406
- /** Claude 3 Sonnet (Latest) */
406
+ /** @deprecated Use Claude 4 Sonnet instead. */
407
407
  Claude_3Sonnet = "CLAUDE_3_SONNET",
408
- /** Claude 3 Sonnet (02-29-2024 version) */
408
+ /** @deprecated Use Claude 4 Sonnet instead. */
409
409
  Claude_3Sonnet_20240229 = "CLAUDE_3_SONNET_20240229",
410
410
  /** Claude 4 Opus (Latest) */
411
411
  Claude_4Opus = "CLAUDE_4_OPUS",
@@ -8460,7 +8460,9 @@ export declare enum ModelServiceTypes {
8460
8460
  /** Replicate */
8461
8461
  Replicate = "REPLICATE",
8462
8462
  /** Voyage */
8463
- Voyage = "VOYAGE"
8463
+ Voyage = "VOYAGE",
8464
+ /** xAI */
8465
+ Xai = "XAI"
8464
8466
  }
8465
8467
  /** Represents an LLM text entity extraction connector. */
8466
8468
  export type ModelTextExtractionProperties = {
@@ -13803,6 +13805,8 @@ export type Specification = {
13803
13805
  type?: Maybe<SpecificationTypes>;
13804
13806
  /** The Voyage model properties. */
13805
13807
  voyage?: Maybe<VoyageModelProperties>;
13808
+ /** The xAI model properties. */
13809
+ xai?: Maybe<XaiModelProperties>;
13806
13810
  };
13807
13811
  /** Represents a filter for LLM specifications. */
13808
13812
  export type SpecificationFilter = {
@@ -13889,6 +13893,8 @@ export type SpecificationInput = {
13889
13893
  type?: InputMaybe<SpecificationTypes>;
13890
13894
  /** The Voyage model properties. */
13891
13895
  voyage?: InputMaybe<VoyageModelPropertiesInput>;
13896
+ /** The XAI model properties. */
13897
+ xai?: InputMaybe<XaiModelPropertiesInput>;
13892
13898
  };
13893
13899
  /** Represents LLM specification query results. */
13894
13900
  export type SpecificationResults = {
@@ -13973,6 +13979,8 @@ export type SpecificationUpdateInput = {
13973
13979
  type?: InputMaybe<SpecificationTypes>;
13974
13980
  /** The Voyage model properties. */
13975
13981
  voyage?: InputMaybe<VoyageModelPropertiesUpdateInput>;
13982
+ /** The XAI model properties. */
13983
+ xai?: InputMaybe<XaiModelPropertiesUpdateInput>;
13976
13984
  };
13977
13985
  /** Represents the storage policy. */
13978
13986
  export type StoragePolicy = {
@@ -14894,6 +14902,75 @@ export type WorkflowUpdateInput = {
14894
14902
  /** The storage stage of the content workflow. */
14895
14903
  storage?: InputMaybe<StorageWorkflowStageInput>;
14896
14904
  };
14905
+ /** Represents xAI model properties. */
14906
+ export type XaiModelProperties = {
14907
+ __typename?: 'XAIModelProperties';
14908
+ /** The limit of tokens generated by prompt completion. */
14909
+ completionTokenLimit?: Maybe<Scalars['Int']['output']>;
14910
+ /** The xAI API endpoint, if using developer's own account. */
14911
+ endpoint?: Maybe<Scalars['URL']['output']>;
14912
+ /** The xAI API key, if using developer's own account. */
14913
+ key?: Maybe<Scalars['String']['output']>;
14914
+ /** The xAI model, or custom, when using developer's own account. */
14915
+ model: XaiModels;
14916
+ /** The xAI model name, if using developer's own account. */
14917
+ modelName?: Maybe<Scalars['String']['output']>;
14918
+ /** The model token probability. */
14919
+ probability?: Maybe<Scalars['Float']['output']>;
14920
+ /** The model temperature. */
14921
+ temperature?: Maybe<Scalars['Float']['output']>;
14922
+ /** The number of tokens which can provided to the xAI model, if using developer's own account. */
14923
+ tokenLimit?: Maybe<Scalars['Int']['output']>;
14924
+ };
14925
+ /** Represents xAI model properties. */
14926
+ export type XaiModelPropertiesInput = {
14927
+ /** The limit of tokens generated by prompt completion. */
14928
+ completionTokenLimit?: InputMaybe<Scalars['Int']['input']>;
14929
+ /** The xAI API endpoint, if using developer's own account. */
14930
+ endpoint?: InputMaybe<Scalars['URL']['input']>;
14931
+ /** The xAI API key, if using developer's own account. */
14932
+ key?: InputMaybe<Scalars['String']['input']>;
14933
+ /** The xAI model, or custom, when using developer's own account. */
14934
+ model: XaiModels;
14935
+ /** The xAI model name, if using developer's own account. */
14936
+ modelName?: InputMaybe<Scalars['String']['input']>;
14937
+ /** The model token probability. */
14938
+ probability?: InputMaybe<Scalars['Float']['input']>;
14939
+ /** The model temperature. */
14940
+ temperature?: InputMaybe<Scalars['Float']['input']>;
14941
+ /** The number of tokens which can provided to the xAI model, if using developer's own account. */
14942
+ tokenLimit?: InputMaybe<Scalars['Int']['input']>;
14943
+ };
14944
+ /** Represents xAI model properties. */
14945
+ export type XaiModelPropertiesUpdateInput = {
14946
+ /** The limit of tokens generated by prompt completion. */
14947
+ completionTokenLimit?: InputMaybe<Scalars['Int']['input']>;
14948
+ /** The xAI API endpoint, if using developer's own account. */
14949
+ endpoint?: InputMaybe<Scalars['URL']['input']>;
14950
+ /** The xAI API key, if using developer's own account. */
14951
+ key?: InputMaybe<Scalars['String']['input']>;
14952
+ /** The xAI model, or custom, when using developer's own account. */
14953
+ model?: InputMaybe<XaiModels>;
14954
+ /** The xAI model name, if using developer's own account. */
14955
+ modelName?: InputMaybe<Scalars['String']['input']>;
14956
+ /** The model token probability. */
14957
+ probability?: InputMaybe<Scalars['Float']['input']>;
14958
+ /** The model temperature. */
14959
+ temperature?: InputMaybe<Scalars['Float']['input']>;
14960
+ /** The number of tokens which can provided to the xAI model, if using developer's own account. */
14961
+ tokenLimit?: InputMaybe<Scalars['Int']['input']>;
14962
+ };
14963
+ /** xAI model type */
14964
+ export declare enum XaiModels {
14965
+ /** Developer-specified model */
14966
+ Custom = "CUSTOM",
14967
+ /** Grok 3 (Latest) */
14968
+ Grok_3 = "GROK_3",
14969
+ /** Grok 3 Mini (Latest) */
14970
+ Grok_3Mini = "GROK_3_MINI",
14971
+ /** Grok 4 (Latest) */
14972
+ Grok_4 = "GROK_4"
14973
+ }
14897
14974
  /** Represents YouTube feed properties. */
14898
14975
  export type YouTubeFeedProperties = {
14899
14976
  __typename?: 'YouTubeFeedProperties';
@@ -25878,6 +25955,17 @@ export type GetSpecificationQuery = {
25878
25955
  temperature?: number | null;
25879
25956
  probability?: number | null;
25880
25957
  } | null;
25958
+ xai?: {
25959
+ __typename?: 'XAIModelProperties';
25960
+ tokenLimit?: number | null;
25961
+ completionTokenLimit?: number | null;
25962
+ model: XaiModels;
25963
+ key?: string | null;
25964
+ modelName?: string | null;
25965
+ endpoint?: any | null;
25966
+ temperature?: number | null;
25967
+ probability?: number | null;
25968
+ } | null;
25881
25969
  groq?: {
25882
25970
  __typename?: 'GroqModelProperties';
25883
25971
  tokenLimit?: number | null;
@@ -26283,6 +26371,17 @@ export type QuerySpecificationsQuery = {
26283
26371
  temperature?: number | null;
26284
26372
  probability?: number | null;
26285
26373
  } | null;
26374
+ xai?: {
26375
+ __typename?: 'XAIModelProperties';
26376
+ tokenLimit?: number | null;
26377
+ completionTokenLimit?: number | null;
26378
+ model: XaiModels;
26379
+ key?: string | null;
26380
+ modelName?: string | null;
26381
+ endpoint?: any | null;
26382
+ temperature?: number | null;
26383
+ probability?: number | null;
26384
+ } | null;
26286
26385
  groq?: {
26287
26386
  __typename?: 'GroqModelProperties';
26288
26387
  tokenLimit?: number | null;
@@ -31,13 +31,13 @@ export var AnthropicModels;
31
31
  AnthropicModels["Claude_3Haiku"] = "CLAUDE_3_HAIKU";
32
32
  /** Claude 3 Haiku (03-07-2024 version) */
33
33
  AnthropicModels["Claude_3Haiku_20240307"] = "CLAUDE_3_HAIKU_20240307";
34
- /** Claude 3 Opus (Latest) */
34
+ /** @deprecated Use Claude 4 Opus instead. */
35
35
  AnthropicModels["Claude_3Opus"] = "CLAUDE_3_OPUS";
36
36
  /** Claude 3 Opus (02-29-2024 version) */
37
37
  AnthropicModels["Claude_3Opus_20240229"] = "CLAUDE_3_OPUS_20240229";
38
- /** Claude 3 Sonnet (Latest) */
38
+ /** @deprecated Use Claude 4 Sonnet instead. */
39
39
  AnthropicModels["Claude_3Sonnet"] = "CLAUDE_3_SONNET";
40
- /** Claude 3 Sonnet (02-29-2024 version) */
40
+ /** @deprecated Use Claude 4 Sonnet instead. */
41
41
  AnthropicModels["Claude_3Sonnet_20240229"] = "CLAUDE_3_SONNET_20240229";
42
42
  /** Claude 4 Opus (Latest) */
43
43
  AnthropicModels["Claude_4Opus"] = "CLAUDE_4_OPUS";
@@ -1469,6 +1469,8 @@ export var ModelServiceTypes;
1469
1469
  ModelServiceTypes["Replicate"] = "REPLICATE";
1470
1470
  /** Voyage */
1471
1471
  ModelServiceTypes["Voyage"] = "VOYAGE";
1472
+ /** xAI */
1473
+ ModelServiceTypes["Xai"] = "XAI";
1472
1474
  })(ModelServiceTypes || (ModelServiceTypes = {}));
1473
1475
  /** Model type */
1474
1476
  export var ModelTypes;
@@ -2246,6 +2248,18 @@ export var VoyageModels;
2246
2248
  /** Voyage Multilingual 2.0 */
2247
2249
  VoyageModels["VoyageMultilingual_2_0"] = "VOYAGE_MULTILINGUAL_2_0";
2248
2250
  })(VoyageModels || (VoyageModels = {}));
2251
+ /** xAI model type */
2252
+ export var XaiModels;
2253
+ (function (XaiModels) {
2254
+ /** Developer-specified model */
2255
+ XaiModels["Custom"] = "CUSTOM";
2256
+ /** Grok 3 (Latest) */
2257
+ XaiModels["Grok_3"] = "GROK_3";
2258
+ /** Grok 3 Mini (Latest) */
2259
+ XaiModels["Grok_3Mini"] = "GROK_3_MINI";
2260
+ /** Grok 4 (Latest) */
2261
+ XaiModels["Grok_4"] = "GROK_4";
2262
+ })(XaiModels || (XaiModels = {}));
2249
2263
  export var YouTubeTypes;
2250
2264
  (function (YouTubeTypes) {
2251
2265
  /** YouTube Channel */
@@ -136,6 +136,12 @@ const DEEPSEEK_MODEL_MAP = {
136
136
  [Types.DeepseekModels.Chat]: "deepseek-chat",
137
137
  [Types.DeepseekModels.Reasoner]: "deepseek-reasoner",
138
138
  };
139
+ // xAI model mappings
140
+ const XAI_MODEL_MAP = {
141
+ [Types.XaiModels.Grok_4]: "grok-4",
142
+ [Types.XaiModels.Grok_3]: "grok-3",
143
+ [Types.XaiModels.Grok_3Mini]: "grok-3-mini",
144
+ };
139
145
  /**
140
146
  * Get the actual model name for a given specification
141
147
  * @param specification - The Graphlit specification object
@@ -171,6 +177,9 @@ export function getModelName(specification) {
171
177
  if (specification?.deepseek?.modelName) {
172
178
  return specification.deepseek.modelName;
173
179
  }
180
+ if (specification?.xai?.modelName) {
181
+ return specification.xai.modelName;
182
+ }
174
183
  // Map based on service type and model enum
175
184
  switch (serviceType) {
176
185
  case Types.ModelServiceTypes.OpenAi:
@@ -201,6 +210,9 @@ export function getModelName(specification) {
201
210
  case Types.ModelServiceTypes.Deepseek:
202
211
  const deepseekModel = specification?.deepseek?.model;
203
212
  return deepseekModel ? DEEPSEEK_MODEL_MAP[deepseekModel] : undefined;
213
+ case Types.ModelServiceTypes.Xai:
214
+ const xaiModel = specification?.xai?.model;
215
+ return xaiModel ? XAI_MODEL_MAP[xaiModel] : undefined;
204
216
  default:
205
217
  return undefined;
206
218
  }
@@ -221,6 +233,7 @@ export function isStreamingSupported(serviceType) {
221
233
  Types.ModelServiceTypes.Mistral,
222
234
  Types.ModelServiceTypes.Bedrock,
223
235
  Types.ModelServiceTypes.Deepseek,
236
+ Types.ModelServiceTypes.Xai,
224
237
  ];
225
238
  return streamingServices.includes(serviceType);
226
239
  }
@@ -5,13 +5,13 @@ import { StreamEvent } from "../types/internal.js";
5
5
  * Stream with OpenAI SDK
6
6
  */
7
7
  export declare function streamWithOpenAI(specification: Specification, messages: OpenAIMessage[], tools: ToolDefinitionInput[] | undefined, openaiClient: any, // OpenAI client instance
8
- onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[]) => void, abortSignal?: AbortSignal): Promise<void>;
8
+ onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[], usage?: any) => void, abortSignal?: AbortSignal): Promise<void>;
9
9
  /**
10
10
  * Stream with Anthropic SDK
11
11
  */
12
12
  type AnthropicClient = import("@anthropic-ai/sdk").default;
13
13
  export declare function streamWithAnthropic(specification: Specification, messages: AnthropicMessage[], systemPrompt: string | undefined, tools: ToolDefinitionInput[] | undefined, anthropicClient: AnthropicClient, // Properly typed Anthropic client
14
- onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[]) => void, abortSignal?: AbortSignal, thinkingConfig?: {
14
+ onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[], usage?: any) => void, abortSignal?: AbortSignal, thinkingConfig?: {
15
15
  type: "enabled";
16
16
  budget_tokens: number;
17
17
  }): Promise<void>;
@@ -19,35 +19,37 @@ onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls:
19
19
  * Stream with Google SDK
20
20
  */
21
21
  export declare function streamWithGoogle(specification: Specification, messages: GoogleMessage[], systemPrompt: string | undefined, tools: ToolDefinitionInput[] | undefined, googleClient: any, // Google GenerativeAI client instance
22
- onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[]) => void, abortSignal?: AbortSignal): Promise<void>;
22
+ onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[], usage?: any) => void, abortSignal?: AbortSignal): Promise<void>;
23
23
  /**
24
24
  * Stream with Groq SDK (OpenAI-compatible)
25
25
  */
26
26
  export declare function streamWithGroq(specification: Specification, messages: OpenAIMessage[], tools: ToolDefinitionInput[] | undefined, groqClient: any, // Groq client instance (OpenAI-compatible)
27
- onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[]) => void, abortSignal?: AbortSignal): Promise<void>;
27
+ onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[], usage?: any) => void, abortSignal?: AbortSignal): Promise<void>;
28
28
  /**
29
29
  * Stream with Cerebras SDK (OpenAI-compatible)
30
30
  */
31
31
  export declare function streamWithCerebras(specification: Specification, messages: OpenAIMessage[], tools: ToolDefinitionInput[] | undefined, cerebrasClient: any, // OpenAI client instance configured for Cerebras
32
- onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[]) => void, abortSignal?: AbortSignal): Promise<void>;
32
+ onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[], usage?: any) => void, abortSignal?: AbortSignal): Promise<void>;
33
33
  /**
34
34
  * Stream with Deepseek SDK (OpenAI-compatible)
35
35
  */
36
36
  export declare function streamWithDeepseek(specification: Specification, messages: OpenAIMessage[], tools: ToolDefinitionInput[] | undefined, deepseekClient: any, // OpenAI client instance configured for Deepseek
37
- onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[]) => void, abortSignal?: AbortSignal): Promise<void>;
37
+ onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[], usage?: any) => void, abortSignal?: AbortSignal): Promise<void>;
38
38
  /**
39
39
  * Stream with Cohere SDK
40
40
  */
41
41
  export declare function streamWithCohere(specification: Specification, messages: ConversationMessage[], tools: ToolDefinitionInput[] | undefined, cohereClient: any, // CohereClient instance
42
- onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[]) => void, abortSignal?: AbortSignal): Promise<void>;
42
+ onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[], usage?: any) => void, abortSignal?: AbortSignal): Promise<void>;
43
43
  /**
44
44
  * Stream with Mistral SDK
45
45
  */
46
46
  export declare function streamWithMistral(specification: Specification, messages: MistralMessage[], tools: ToolDefinitionInput[] | undefined, mistralClient: any, // Mistral client instance
47
- onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[]) => void, abortSignal?: AbortSignal): Promise<void>;
47
+ onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[], usage?: any) => void, abortSignal?: AbortSignal): Promise<void>;
48
48
  /**
49
49
  * Stream with Bedrock SDK (for Claude models)
50
50
  */
51
51
  export declare function streamWithBedrock(specification: Specification, messages: BedrockMessage[], systemPrompt: string | undefined, tools: ToolDefinitionInput[] | undefined, bedrockClient: any, // BedrockRuntimeClient instance
52
- onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[]) => void, abortSignal?: AbortSignal): Promise<void>;
52
+ onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[], usage?: any) => void, abortSignal?: AbortSignal): Promise<void>;
53
+ export declare function streamWithXai(specification: Specification, messages: OpenAIMessage[], tools: ToolDefinitionInput[] | undefined, xaiClient: any, // OpenAI client instance configured for xAI
54
+ onEvent: (event: StreamEvent) => void, onComplete: (message: string, toolCalls: ConversationToolCall[], usage?: any) => void, abortSignal?: AbortSignal): Promise<void>;
53
55
  export {};
@@ -79,6 +79,7 @@ export async function streamWithOpenAI(specification, messages, tools, openaiCli
79
79
  onEvent, onComplete, abortSignal) {
80
80
  let fullMessage = "";
81
81
  let toolCalls = [];
82
+ let usageData = null;
82
83
  // Performance metrics
83
84
  const startTime = Date.now();
84
85
  let firstTokenTime = 0;
@@ -110,6 +111,7 @@ onEvent, onComplete, abortSignal) {
110
111
  model: modelName,
111
112
  messages,
112
113
  stream: true,
114
+ stream_options: { include_usage: true },
113
115
  temperature: specification.openAI?.temperature,
114
116
  //top_p: specification.openAI?.probability,
115
117
  };
@@ -137,6 +139,13 @@ onEvent, onComplete, abortSignal) {
137
139
  });
138
140
  for await (const chunk of stream) {
139
141
  const delta = chunk.choices[0]?.delta;
142
+ // Capture usage data from final chunk
143
+ if (chunk.usage || chunk.x_groq?.usage) {
144
+ usageData = chunk.usage || chunk.x_groq?.usage;
145
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
146
+ console.log(`[OpenAI] Usage data captured:`, usageData);
147
+ }
148
+ }
140
149
  // Debug log chunk details
141
150
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
142
151
  console.log(`[OpenAI] Chunk:`, JSON.stringify(chunk, null, 2));
@@ -351,7 +360,8 @@ onEvent, onComplete, abortSignal) {
351
360
  }
352
361
  console.log(`āœ… [OpenAI] Final message (${fullMessage.length} chars): "${fullMessage}"`);
353
362
  }
354
- onComplete(fullMessage, toolCalls);
363
+ // Pass usage data if available
364
+ onComplete(fullMessage, toolCalls, usageData);
355
365
  }
356
366
  catch (error) {
357
367
  // Handle OpenAI-specific errors
@@ -386,6 +396,7 @@ export async function streamWithAnthropic(specification, messages, systemPrompt,
386
396
  onEvent, onComplete, abortSignal, thinkingConfig) {
387
397
  let fullMessage = "";
388
398
  let toolCalls = [];
399
+ let usageData = null;
389
400
  // Performance metrics
390
401
  const startTime = Date.now();
391
402
  let firstTokenTime = 0;
@@ -477,6 +488,33 @@ onEvent, onComplete, abortSignal, thinkingConfig) {
477
488
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
478
489
  console.log(`[Anthropic] Received chunk type: ${chunk.type}`);
479
490
  }
491
+ // Capture usage data from various message events
492
+ // Prioritize message_start.message usage data as it's more complete
493
+ if (chunk.type === "message_start" && chunk.message?.usage) {
494
+ usageData = chunk.message.usage;
495
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
496
+ console.log(`[Anthropic] Usage data captured from message_start.message:`, usageData);
497
+ }
498
+ }
499
+ else if (chunk.type === "message_delta" && chunk.usage && !usageData?.input_tokens) {
500
+ // Only use message_delta if we don't have input_tokens yet
501
+ usageData = chunk.usage;
502
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
503
+ console.log(`[Anthropic] Usage data captured from ${chunk.type}:`, usageData);
504
+ }
505
+ }
506
+ else if ((chunk.type === "message_delta" || chunk.type === "message_start") && chunk.usage) {
507
+ // Merge usage data if we have partial data
508
+ if (usageData) {
509
+ usageData = { ...usageData, ...chunk.usage };
510
+ }
511
+ else {
512
+ usageData = chunk.usage;
513
+ }
514
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
515
+ console.log(`[Anthropic] Usage data merged from ${chunk.type}:`, usageData);
516
+ }
517
+ }
480
518
  if (chunk.type === "content_block_start") {
481
519
  activeContentBlock = true;
482
520
  currentContentBlockIndex = chunk.index;
@@ -799,7 +837,7 @@ onEvent, onComplete, abortSignal, thinkingConfig) {
799
837
  console.log(`🧠 [Anthropic] Including thinking content (${completeThinkingContent.length} chars) and signature (${completeThinkingSignature.length} chars) in conversation history`);
800
838
  }
801
839
  }
802
- onComplete(finalMessage, validToolCalls);
840
+ onComplete(finalMessage, validToolCalls, usageData);
803
841
  }
804
842
  catch (error) {
805
843
  // Handle Anthropic-specific errors
@@ -837,6 +875,7 @@ export async function streamWithGoogle(specification, messages, systemPrompt, to
837
875
  onEvent, onComplete, abortSignal) {
838
876
  let fullMessage = "";
839
877
  let toolCalls = [];
878
+ let usageData = null;
840
879
  // Performance metrics
841
880
  const startTime = Date.now();
842
881
  let firstTokenTime = 0;
@@ -1176,7 +1215,24 @@ onEvent, onComplete, abortSignal) {
1176
1215
  }
1177
1216
  console.log(`āœ… [Google] Final message (${fullMessage.length} chars): "${fullMessage}"`);
1178
1217
  }
1179
- onComplete(fullMessage, toolCalls);
1218
+ // Try to capture usage data from final response
1219
+ try {
1220
+ const response = await result.response;
1221
+ if (response.usageMetadata) {
1222
+ usageData = {
1223
+ prompt_tokens: response.usageMetadata.promptTokenCount,
1224
+ completion_tokens: response.usageMetadata.candidatesTokenCount,
1225
+ total_tokens: response.usageMetadata.totalTokenCount,
1226
+ };
1227
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
1228
+ console.log(`[Google] Usage data captured:`, usageData);
1229
+ }
1230
+ }
1231
+ }
1232
+ catch (e) {
1233
+ // Ignore errors capturing usage data
1234
+ }
1235
+ onComplete(fullMessage, toolCalls, usageData);
1180
1236
  }
1181
1237
  catch (error) {
1182
1238
  // Don't emit error event here - let the client handle it to avoid duplicates
@@ -1317,6 +1373,7 @@ export async function streamWithDeepseek(specification, messages, tools, deepsee
1317
1373
  onEvent, onComplete, abortSignal) {
1318
1374
  let fullMessage = "";
1319
1375
  let toolCalls = [];
1376
+ let usageData = null;
1320
1377
  // Reasoning detection state
1321
1378
  let reasoningLines = [];
1322
1379
  let currentLine = "";
@@ -1405,6 +1462,13 @@ onEvent, onComplete, abortSignal) {
1405
1462
  const delta = chunk.choices[0]?.delta;
1406
1463
  if (!delta)
1407
1464
  continue;
1465
+ // Check for usage data in the chunk (OpenAI-compatible format)
1466
+ if (chunk.usage) {
1467
+ usageData = chunk.usage;
1468
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
1469
+ console.log(`[Deepseek] Usage data captured:`, usageData);
1470
+ }
1471
+ }
1408
1472
  const currentTime = Date.now();
1409
1473
  // Track first token time
1410
1474
  if (firstTokenTime === 0) {
@@ -1599,7 +1663,7 @@ onEvent, onComplete, abortSignal) {
1599
1663
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
1600
1664
  console.log(`āœ… [Deepseek] Stream completed: ${fullMessage.length} chars, ${validToolCalls.length} tools`);
1601
1665
  }
1602
- onComplete(fullMessage, validToolCalls);
1666
+ onComplete(fullMessage, validToolCalls, usageData);
1603
1667
  }
1604
1668
  catch (error) {
1605
1669
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
@@ -1619,6 +1683,7 @@ export async function streamWithCohere(specification, messages, tools, cohereCli
1619
1683
  onEvent, onComplete, abortSignal) {
1620
1684
  let fullMessage = "";
1621
1685
  let toolCalls = [];
1686
+ let usageData = null;
1622
1687
  // Performance metrics
1623
1688
  const startTime = Date.now();
1624
1689
  let firstTokenTime = 0;
@@ -1867,10 +1932,17 @@ onEvent, onComplete, abortSignal) {
1867
1932
  }
1868
1933
  }
1869
1934
  else if (chunk.type === "message-end") {
1870
- // Handle message end event
1935
+ // Handle message end event and capture usage data
1871
1936
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
1872
1937
  console.log(`[Cohere] Message end event received`, chunk);
1873
1938
  }
1939
+ // Capture usage data from message-end event
1940
+ if (chunk.delta?.usage || chunk.usage) {
1941
+ usageData = chunk.delta?.usage || chunk.usage;
1942
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
1943
+ console.log(`[Cohere] Usage data captured:`, usageData);
1944
+ }
1945
+ }
1874
1946
  }
1875
1947
  }
1876
1948
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
@@ -1881,7 +1953,7 @@ onEvent, onComplete, abortSignal) {
1881
1953
  type: "complete",
1882
1954
  tokens: tokenCount,
1883
1955
  });
1884
- onComplete(fullMessage, toolCalls);
1956
+ onComplete(fullMessage, toolCalls, usageData);
1885
1957
  }
1886
1958
  catch (error) {
1887
1959
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
@@ -1906,6 +1978,7 @@ export async function streamWithMistral(specification, messages, tools, mistralC
1906
1978
  onEvent, onComplete, abortSignal) {
1907
1979
  let fullMessage = "";
1908
1980
  let toolCalls = [];
1981
+ let usageData = null;
1909
1982
  // Performance metrics
1910
1983
  const startTime = Date.now();
1911
1984
  let firstTokenTime = 0;
@@ -2042,6 +2115,13 @@ onEvent, onComplete, abortSignal) {
2042
2115
  console.log(`[Mistral] Raw chunk:`, JSON.stringify(chunk, null, 2));
2043
2116
  }
2044
2117
  const delta = chunk.data.choices[0]?.delta;
2118
+ // Check for usage data in the chunk
2119
+ if (chunk.data.usage) {
2120
+ usageData = chunk.data.usage;
2121
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2122
+ console.log(`[Mistral] Usage data captured:`, usageData);
2123
+ }
2124
+ }
2045
2125
  if (delta?.content) {
2046
2126
  fullMessage += delta.content;
2047
2127
  tokenCount++;
@@ -2122,7 +2202,9 @@ onEvent, onComplete, abortSignal) {
2122
2202
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2123
2203
  console.log(`āœ… [Mistral] Complete. Chunks: ${chunkCount} | Tokens: ${tokenCount} | Message length: ${fullMessage.length} | Tool calls: ${toolCalls.length}`);
2124
2204
  }
2125
- onComplete(fullMessage, toolCalls);
2205
+ // Check if we captured usage data during streaming
2206
+ // Note: Mistral SDK may provide usage data differently than other providers
2207
+ onComplete(fullMessage, toolCalls, usageData);
2126
2208
  }
2127
2209
  catch (error) {
2128
2210
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
@@ -2150,6 +2232,7 @@ export async function streamWithBedrock(specification, messages, systemPrompt, t
2150
2232
  onEvent, onComplete, abortSignal) {
2151
2233
  let fullMessage = "";
2152
2234
  let toolCalls = [];
2235
+ let usageData = null;
2153
2236
  // Map contentBlockIndex to tool calls for proper correlation
2154
2237
  const toolCallsByIndex = new Map();
2155
2238
  // Performance metrics
@@ -2393,6 +2476,17 @@ onEvent, onComplete, abortSignal) {
2393
2476
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2394
2477
  console.log(`šŸ“Š [Bedrock] Metadata:`, event.metadata);
2395
2478
  }
2479
+ // Capture usage data from metadata
2480
+ if (event.metadata.usage) {
2481
+ usageData = {
2482
+ prompt_tokens: event.metadata.usage.inputTokens,
2483
+ completion_tokens: event.metadata.usage.outputTokens,
2484
+ total_tokens: event.metadata.usage.totalTokens,
2485
+ };
2486
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2487
+ console.log(`[Bedrock] Usage data captured:`, usageData);
2488
+ }
2489
+ }
2396
2490
  }
2397
2491
  }
2398
2492
  }
@@ -2403,7 +2497,7 @@ onEvent, onComplete, abortSignal) {
2403
2497
  type: "complete",
2404
2498
  tokens: tokenCount,
2405
2499
  });
2406
- onComplete(fullMessage, toolCalls);
2500
+ onComplete(fullMessage, toolCalls, usageData);
2407
2501
  }
2408
2502
  catch (error) {
2409
2503
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
@@ -2432,3 +2526,31 @@ onEvent, onComplete, abortSignal) {
2432
2526
  throw error;
2433
2527
  }
2434
2528
  }
2529
+ export async function streamWithXai(specification, messages, tools, xaiClient, // OpenAI client instance configured for xAI
2530
+ onEvent, onComplete, abortSignal) {
2531
+ try {
2532
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2533
+ console.log(`šŸš€ [xAI] Starting stream | Model: ${getModelName(specification)} | Messages: ${messages.length} | Tools: ${tools?.length || 0}`);
2534
+ }
2535
+ // xAI uses the same API as OpenAI, so we can reuse the OpenAI streaming logic
2536
+ return await streamWithOpenAI(specification, messages, tools, xaiClient, onEvent, onComplete, abortSignal);
2537
+ }
2538
+ catch (error) {
2539
+ // Handle xAI-specific errors if any
2540
+ const errorMessage = error.message || error.toString();
2541
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2542
+ console.log(`āš ļø [xAI] Error: ${errorMessage}`);
2543
+ }
2544
+ // Check for rate limit errors
2545
+ if (error.status === 429 || error.statusCode === 429) {
2546
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
2547
+ console.log(`āš ļø [xAI] Rate limit hit (429)`);
2548
+ }
2549
+ // Re-throw with proper status code for retry logic
2550
+ const rateLimitError = new Error("xAI rate limit exceeded");
2551
+ rateLimitError.statusCode = 429;
2552
+ throw rateLimitError;
2553
+ }
2554
+ throw error;
2555
+ }
2556
+ }
@@ -30,6 +30,7 @@ export declare class UIEventAdapter {
30
30
  private reasoningFormat?;
31
31
  private reasoningSignature?;
32
32
  private isInReasoning;
33
+ private usageData?;
33
34
  constructor(onEvent: (event: AgentStreamEvent) => void, conversationId: string, options?: {
34
35
  smoothingEnabled?: boolean;
35
36
  chunkingStrategy?: ChunkingStrategy;
@@ -75,4 +76,8 @@ export declare class UIEventAdapter {
75
76
  * Get the throughput in tokens per second
76
77
  */
77
78
  getThroughput(): number | undefined;
79
+ /**
80
+ * Set usage data from native provider
81
+ */
82
+ setUsageData(usage: any): void;
78
83
  }
@@ -29,6 +29,7 @@ export class UIEventAdapter {
29
29
  reasoningFormat;
30
30
  reasoningSignature;
31
31
  isInReasoning = false;
32
+ usageData;
32
33
  constructor(onEvent, conversationId, options = {}) {
33
34
  this.onEvent = onEvent;
34
35
  this.conversationId = conversationId;
@@ -352,6 +353,17 @@ export class UIEventAdapter {
352
353
  if (this.contextWindowUsage) {
353
354
  event.contextWindow = this.contextWindowUsage;
354
355
  }
356
+ // Add native provider usage data if available
357
+ if (this.usageData) {
358
+ event.usage = {
359
+ promptTokens: this.usageData.prompt_tokens || this.usageData.promptTokens || this.usageData.input_tokens || 0,
360
+ completionTokens: this.usageData.completion_tokens || this.usageData.completionTokens || this.usageData.output_tokens || 0,
361
+ totalTokens: this.usageData.total_tokens || this.usageData.totalTokens ||
362
+ ((this.usageData.input_tokens || 0) + (this.usageData.output_tokens || 0)) || 0,
363
+ model: this.model,
364
+ provider: this.modelService,
365
+ };
366
+ }
355
367
  this.emitUIEvent(event);
356
368
  }
357
369
  handleError(error) {
@@ -575,4 +587,13 @@ export class UIEventAdapter {
575
587
  getThroughput() {
576
588
  return this.finalMetrics?.streamingThroughput;
577
589
  }
590
+ /**
591
+ * Set usage data from native provider
592
+ */
593
+ setUsageData(usage) {
594
+ this.usageData = usage;
595
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
596
+ console.log(`šŸ“Š [UIEventAdapter] Usage data set:`, usage);
597
+ }
598
+ }
578
599
  }
@@ -46,6 +46,13 @@ export type StreamEvent = {
46
46
  messageId?: string;
47
47
  conversationId?: string;
48
48
  tokens?: number;
49
+ usage?: {
50
+ promptTokens: number;
51
+ completionTokens: number;
52
+ totalTokens: number;
53
+ model?: string;
54
+ provider?: string;
55
+ };
49
56
  } | {
50
57
  type: "error";
51
58
  error: string;
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Token usage information from streaming providers
3
+ */
4
+ export interface TokenUsage {
5
+ /** Number of tokens in the prompt/input */
6
+ promptTokens: number;
7
+ /** Number of tokens in the completion/output */
8
+ completionTokens: number;
9
+ /** Total tokens (prompt + completion) */
10
+ totalTokens: number;
11
+ /** Provider-specific model identifier */
12
+ model?: string;
13
+ /** Provider name (OpenAI, Anthropic, etc.) */
14
+ provider?: string;
15
+ /** Additional provider-specific usage data */
16
+ metadata?: Record<string, any>;
17
+ }
18
+ /**
19
+ * Extended token usage with timing information
20
+ */
21
+ export interface ExtendedTokenUsage extends TokenUsage {
22
+ /** Time to generate the completion (ms) */
23
+ completionTime?: number;
24
+ /** Time to process the prompt (ms) */
25
+ promptTime?: number;
26
+ /** Queue time before processing (ms) */
27
+ queueTime?: number;
28
+ /** Tokens per second throughput */
29
+ tokensPerSecond?: number;
30
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -71,6 +71,13 @@ export type AgentStreamEvent = {
71
71
  percentage: number;
72
72
  remainingTokens: number;
73
73
  };
74
+ usage?: {
75
+ promptTokens: number;
76
+ completionTokens: number;
77
+ totalTokens: number;
78
+ model?: string;
79
+ provider?: string;
80
+ };
74
81
  } | {
75
82
  type: "error";
76
83
  error: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphlit-client",
3
- "version": "1.0.20250704001",
3
+ "version": "1.0.20250710001",
4
4
  "description": "Graphlit API Client for TypeScript",
5
5
  "type": "module",
6
6
  "main": "./dist/client.js",