graphlit-client 1.0.20250615001 → 1.0.20250615003

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -16,16 +16,25 @@ Graphlit is a cloud platform that handles the complex parts of building AI appli
16
16
 
17
17
  ## ✨ What's New in v1.1.0
18
18
 
19
- - **Real-time streaming** - Watch AI responses appear word-by-word
19
+ - **Real-time streaming** - Watch AI responses appear word-by-word across 9 different providers
20
20
  - **Tool calling** - Let AI execute functions and retrieve data
21
- - **Better performance** - Native integration with OpenAI, Anthropic, and Google
21
+ - **Extended provider support** - Native streaming integration with OpenAI, Anthropic, Google, Groq, Cerebras, Cohere, Mistral, AWS Bedrock, and Deepseek
22
+ - **Better performance** - Optimized streaming with provider-specific SDKs
23
+ - **Network resilience** - Automatic retry logic for transient failures
22
24
 
23
25
  ## 📋 Table of Contents
24
26
 
25
27
  - [Quick Start](#quick-start)
28
+ - [Installation](#installation)
29
+ - [Setting Up](#setting-up)
30
+ - [Network Resilience](#network-resilience-new-in-v111)
31
+ - [Streaming Provider Support](#streaming-provider-support)
26
32
  - [Basic Examples](#basic-examples)
27
33
  - [Common Use Cases](#common-use-cases)
34
+ - [Advanced Agent Features](#advanced-agent-features)
35
+ - [Advanced Workflows](#advanced-workflows)
28
36
  - [API Reference](#api-reference)
37
+ - [Testing & Examples](#testing--examples)
29
38
  - [Support](#support)
30
39
 
31
40
  ## Quick Start
@@ -93,7 +102,7 @@ npm install @google/generative-ai
93
102
  # For Groq streaming (OpenAI-compatible)
94
103
  npm install groq-sdk
95
104
 
96
- # For Cerebras streaming (uses OpenAI SDK with custom base URL)
105
+ # For Cerebras streaming (OpenAI-compatible)
97
106
  npm install openai
98
107
 
99
108
  # For Cohere streaming
@@ -105,7 +114,7 @@ npm install @mistralai/mistralai
105
114
  # For AWS Bedrock streaming (Claude models)
106
115
  npm install @aws-sdk/client-bedrock-runtime
107
116
 
108
- # For Deepseek streaming (uses OpenAI SDK with custom base URL)
117
+ # For Deepseek streaming (OpenAI-compatible)
109
118
  npm install openai
110
119
  ```
111
120
 
@@ -118,22 +127,22 @@ GRAPHLIT_ORGANIZATION_ID=your_org_id
118
127
  GRAPHLIT_ENVIRONMENT_ID=your_env_id
119
128
  GRAPHLIT_JWT_SECRET=your_secret
120
129
 
121
- # Optional: For streaming
130
+ # Optional: For streaming with specific providers
122
131
  OPENAI_API_KEY=your_key
123
132
  ANTHROPIC_API_KEY=your_key
124
133
  GOOGLE_API_KEY=your_key
125
- GROQ_API_KEY=your_key
126
- CEREBRAS_API_KEY=your_key
127
- COHERE_API_KEY=your_key
128
- MISTRAL_API_KEY=your_key
129
134
 
130
- # For AWS Bedrock (requires AWS credentials)
135
+ # Additional streaming providers
136
+ GROQ_API_KEY=your_key # For Groq models (Llama, Mixtral)
137
+ CEREBRAS_API_KEY=your_key # For Cerebras models
138
+ COHERE_API_KEY=your_key # For Cohere Command models
139
+ MISTRAL_API_KEY=your_key # For Mistral models
140
+ DEEPSEEK_API_KEY=your_key # For Deepseek models
141
+
142
+ # For AWS Bedrock streaming (requires AWS credentials)
131
143
  AWS_REGION=us-east-2
132
144
  AWS_ACCESS_KEY_ID=your_key
133
145
  AWS_SECRET_ACCESS_KEY=your_secret
134
-
135
- # For Deepseek streaming
136
- DEEPSEEK_API_KEY=your_key
137
146
  ```
138
147
 
139
148
  ## Network Resilience (New in v1.1.1)
@@ -206,6 +215,69 @@ const client = new Graphlit({
206
215
  });
207
216
  ```
208
217
 
218
+ ## Streaming Provider Support
219
+
220
+ The Graphlit SDK supports real-time streaming responses from 9 different LLM providers. Each provider requires its specific SDK and API key:
221
+
222
+ ### Supported Providers
223
+
224
+ | Provider | Models | SDK Required | API Key |
225
+ |----------|--------|--------------|---------|
226
+ | **OpenAI** | GPT-4, GPT-4o, GPT-4.1, O1, O3, O4 | `openai` | `OPENAI_API_KEY` |
227
+ | **Anthropic** | Claude 3, Claude 3.5, Claude 3.7, Claude 4 | `@anthropic-ai/sdk` | `ANTHROPIC_API_KEY` |
228
+ | **Google** | Gemini 1.5, Gemini 2.0, Gemini 2.5 | `@google/generative-ai` | `GOOGLE_API_KEY` |
229
+ | **Groq** | Llama 4, Llama 3.3, Mixtral, Deepseek R1 | `groq-sdk` | `GROQ_API_KEY` |
230
+ | **Cerebras** | Llama 3.3, Llama 3.1 | `openai` | `CEREBRAS_API_KEY` |
231
+ | **Cohere** | Command R+, Command R, Command R7B, Command A | `cohere-ai` | `COHERE_API_KEY` |
232
+ | **Mistral** | Mistral Large, Medium, Small, Nemo, Pixtral | `@mistralai/mistralai` | `MISTRAL_API_KEY` |
233
+ | **AWS Bedrock** | Nova Premier/Pro, Claude 3.7, Llama 4 | `@aws-sdk/client-bedrock-runtime` | AWS credentials |
234
+ | **Deepseek** | Deepseek Chat, Deepseek Reasoner | `openai` | `DEEPSEEK_API_KEY` |
235
+
236
+ ### Setting Up Streaming
237
+
238
+ Each provider requires both the SDK installation and proper client setup:
239
+
240
+ ```typescript
241
+ import { Graphlit } from "graphlit-client";
242
+
243
+ const client = new Graphlit();
244
+
245
+ // Example: Set up multiple streaming providers
246
+ if (process.env.OPENAI_API_KEY) {
247
+ const { OpenAI } = await import("openai");
248
+ client.setOpenAIClient(new OpenAI());
249
+ }
250
+
251
+ if (process.env.COHERE_API_KEY) {
252
+ const { CohereClient } = await import("cohere-ai");
253
+ client.setCohereClient(new CohereClient({ token: process.env.COHERE_API_KEY }));
254
+ }
255
+
256
+ if (process.env.GROQ_API_KEY) {
257
+ const { Groq } = await import("groq-sdk");
258
+ client.setGroqClient(new Groq({ apiKey: process.env.GROQ_API_KEY }));
259
+ }
260
+
261
+ // Then create specifications for any provider
262
+ const spec = await client.createSpecification({
263
+ name: "Multi-Provider Assistant",
264
+ type: Types.SpecificationTypes.Completion,
265
+ serviceType: Types.ModelServiceTypes.Cohere, // or any supported provider
266
+ cohere: {
267
+ model: Types.CohereModels.CommandRPlus,
268
+ temperature: 0.7
269
+ },
270
+ });
271
+ ```
272
+
273
+ ### Provider-Specific Notes
274
+
275
+ - **OpenAI-Compatible**: Groq, Cerebras, and Deepseek use OpenAI-compatible APIs
276
+ - **AWS Bedrock**: Requires AWS credentials and uses the Converse API for streaming
277
+ - **Cohere**: Supports both chat and tool calling with Command models
278
+ - **Google**: Includes advanced multimodal capabilities with Gemini models
279
+ - **Mistral**: Supports both text and vision models (Pixtral)
280
+
209
281
  ## Basic Examples
210
282
 
211
283
  ### 1. Chat with AI
@@ -323,7 +395,73 @@ const response = await client.promptAgent(
323
395
  console.log(response.message);
324
396
  ```
325
397
 
326
- ### 4. Tool Calling
398
+ ### 4. Multiple Provider Streaming
399
+
400
+ Compare responses from different LLM providers:
401
+
402
+ ```typescript
403
+ import { Graphlit, Types } from "graphlit-client";
404
+
405
+ const client = new Graphlit();
406
+
407
+ // Set up multiple providers
408
+ if (process.env.OPENAI_API_KEY) {
409
+ const { OpenAI } = await import("openai");
410
+ client.setOpenAIClient(new OpenAI());
411
+ }
412
+
413
+ if (process.env.COHERE_API_KEY) {
414
+ const { CohereClient } = await import("cohere-ai");
415
+ client.setCohereClient(new CohereClient({ token: process.env.COHERE_API_KEY }));
416
+ }
417
+
418
+ if (process.env.GROQ_API_KEY) {
419
+ const { Groq } = await import("groq-sdk");
420
+ client.setGroqClient(new Groq({ apiKey: process.env.GROQ_API_KEY }));
421
+ }
422
+
423
+ // Create specifications for different providers
424
+ const providers = [
425
+ {
426
+ name: "OpenAI GPT-4o",
427
+ serviceType: Types.ModelServiceTypes.OpenAi,
428
+ openAI: { model: Types.OpenAiModels.Gpt4O_128K }
429
+ },
430
+ {
431
+ name: "Cohere Command R+",
432
+ serviceType: Types.ModelServiceTypes.Cohere,
433
+ cohere: { model: Types.CohereModels.CommandRPlus }
434
+ },
435
+ {
436
+ name: "Groq Llama",
437
+ serviceType: Types.ModelServiceTypes.Groq,
438
+ groq: { model: Types.GroqModels.Llama_3_3_70B }
439
+ }
440
+ ];
441
+
442
+ // Compare responses
443
+ for (const provider of providers) {
444
+ console.log(`\n🤖 ${provider.name}:`);
445
+
446
+ const spec = await client.createSpecification({
447
+ ...provider,
448
+ type: Types.SpecificationTypes.Completion,
449
+ });
450
+
451
+ await client.streamAgent(
452
+ "Explain quantum computing in simple terms",
453
+ (event) => {
454
+ if (event.type === "message_update") {
455
+ process.stdout.write(event.message.message);
456
+ }
457
+ },
458
+ undefined,
459
+ { id: spec.createSpecification.id }
460
+ );
461
+ }
462
+ ```
463
+
464
+ ### 5. Tool Calling
327
465
 
328
466
  Let AI call functions to get real-time data:
329
467
 
@@ -106,8 +106,8 @@ const COHERE_MODEL_MAP = {
106
106
  [Types.CohereModels.CommandR_202403]: "command-r-03-2024",
107
107
  [Types.CohereModels.CommandR_202408]: "command-r-08-2024",
108
108
  [Types.CohereModels.CommandR7B_202412]: "command-r7b-12-2024",
109
- [Types.CohereModels.CommandA]: "command-light",
110
- [Types.CohereModels.CommandA_202503]: "command-light-nightly",
109
+ [Types.CohereModels.CommandA]: "command-a-03-2025",
110
+ [Types.CohereModels.CommandA_202503]: "command-a-03-2025",
111
111
  };
112
112
  // Mistral model mappings
113
113
  const MISTRAL_MODEL_MAP = {
@@ -81,8 +81,23 @@ export declare function formatMessagesForGoogle(messages: ConversationMessage[])
81
81
  * Cohere message format
82
82
  */
83
83
  export interface CohereMessage {
84
- role: "USER" | "CHATBOT" | "SYSTEM";
85
- message: string;
84
+ role: "user" | "assistant" | "system" | "tool";
85
+ content: string;
86
+ tool_calls?: Array<{
87
+ id: string;
88
+ name: string;
89
+ parameters: Record<string, any>;
90
+ }>;
91
+ tool_results?: Array<{
92
+ call: {
93
+ id: string;
94
+ name: string;
95
+ parameters: Record<string, any>;
96
+ };
97
+ outputs: Array<{
98
+ text: string;
99
+ }>;
100
+ }>;
86
101
  }
87
102
  /**
88
103
  * Format GraphQL conversation messages for Cohere SDK
@@ -273,26 +273,59 @@ export function formatMessagesForGoogle(messages) {
273
273
  export function formatMessagesForCohere(messages) {
274
274
  const formattedMessages = [];
275
275
  for (const message of messages) {
276
- if (!message.role || !message.message?.trim())
276
+ if (!message.role)
277
277
  continue;
278
- const trimmedMessage = message.message.trim();
278
+ // Allow messages with tool calls even if they have no text content
279
+ const hasContent = message.message?.trim();
280
+ const hasToolCalls = message.toolCalls && message.toolCalls.length > 0;
281
+ if (!hasContent && !hasToolCalls)
282
+ continue;
283
+ const trimmedMessage = message.message?.trim() || "";
279
284
  switch (message.role) {
280
285
  case ConversationRoleTypes.System:
281
286
  formattedMessages.push({
282
- role: "SYSTEM",
283
- message: trimmedMessage,
287
+ role: "system",
288
+ content: trimmedMessage,
284
289
  });
285
290
  break;
286
291
  case ConversationRoleTypes.Assistant:
292
+ const assistantMessage = {
293
+ role: "assistant",
294
+ content: trimmedMessage,
295
+ };
296
+ // Add tool calls if present
297
+ if (message.toolCalls && message.toolCalls.length > 0) {
298
+ assistantMessage.tool_calls = message.toolCalls
299
+ .filter((tc) => tc !== null)
300
+ .map((toolCall) => ({
301
+ id: toolCall.id,
302
+ name: toolCall.name,
303
+ parameters: toolCall.arguments ? JSON.parse(toolCall.arguments) : {},
304
+ }));
305
+ }
306
+ formattedMessages.push(assistantMessage);
307
+ break;
308
+ case ConversationRoleTypes.Tool:
309
+ // Cohere expects tool results as tool messages
287
310
  formattedMessages.push({
288
- role: "CHATBOT",
289
- message: trimmedMessage,
311
+ role: "tool",
312
+ content: trimmedMessage,
313
+ tool_results: [{
314
+ call: {
315
+ id: message.toolCallId || "",
316
+ name: "", // Would need to be tracked from the tool call
317
+ parameters: {},
318
+ },
319
+ outputs: [{
320
+ text: trimmedMessage,
321
+ }],
322
+ }],
290
323
  });
291
324
  break;
292
325
  default: // User messages
293
326
  formattedMessages.push({
294
- role: "USER",
295
- message: trimmedMessage,
327
+ role: "user",
328
+ content: trimmedMessage,
296
329
  });
297
330
  break;
298
331
  }
@@ -27,6 +27,15 @@ function cleanSchemaForGoogle(schema) {
27
27
  if (key === "$schema" || key === "additionalProperties") {
28
28
  continue;
29
29
  }
30
+ // Handle format field for string types - Google only supports 'enum' and 'date-time'
31
+ if (key === "format" && typeof value === "string") {
32
+ // Only keep supported formats
33
+ if (value === "enum" || value === "date-time") {
34
+ cleaned[key] = value;
35
+ }
36
+ // Skip unsupported formats like "date", "time", "email", etc.
37
+ continue;
38
+ }
30
39
  // Recursively clean nested objects
31
40
  cleaned[key] = cleanSchemaForGoogle(value);
32
41
  }
@@ -1215,15 +1224,21 @@ onEvent, onComplete) {
1215
1224
  if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
1216
1225
  console.log(`🤖 [Cohere] Model Config: Service=Cohere | Model=${modelName} | Temperature=${specification.cohere?.temperature} | Tools=${tools?.length || 0} | Spec="${specification.name}"`);
1217
1226
  }
1218
- // Prepare the latest user message and chat history
1219
- const lastMessage = messages[messages.length - 1];
1220
- const chatHistory = messages.slice(0, -1);
1227
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
1228
+ console.log(`🔍 [Cohere] Messages array length: ${messages.length}`);
1229
+ console.log(`🔍 [Cohere] All messages:`, JSON.stringify(messages, null, 2));
1230
+ }
1231
+ if (messages.length === 0) {
1232
+ throw new Error("No messages found for Cohere streaming");
1233
+ }
1221
1234
  const streamConfig = {
1222
1235
  model: modelName,
1223
- message: lastMessage.message,
1224
- chatHistory: chatHistory,
1225
- temperature: specification.cohere?.temperature,
1236
+ messages: messages, // All messages in chronological order
1226
1237
  };
1238
+ // Only add temperature if it's defined
1239
+ if (specification.cohere?.temperature !== undefined) {
1240
+ streamConfig.temperature = specification.cohere.temperature;
1241
+ }
1227
1242
  // Add tools if provided
1228
1243
  if (tools && tools.length > 0) {
1229
1244
  streamConfig.tools = tools.map((tool) => {
@@ -1231,41 +1246,71 @@ onEvent, onComplete) {
1231
1246
  return {
1232
1247
  name: tool.name,
1233
1248
  description: tool.description,
1234
- parameterDefinitions: {},
1249
+ parameter_definitions: {},
1235
1250
  };
1236
1251
  }
1237
1252
  // Parse the JSON schema
1238
1253
  const schema = JSON.parse(tool.schema);
1239
1254
  // Convert JSON Schema to Cohere's expected format
1240
- const parameterDefinitions = {};
1255
+ const parameter_definitions = {};
1241
1256
  if (schema.properties) {
1242
1257
  for (const [key, value] of Object.entries(schema.properties)) {
1243
1258
  const prop = value;
1244
- parameterDefinitions[key] = {
1259
+ const paramDef = {
1245
1260
  type: prop.type || "string",
1246
1261
  description: prop.description || "",
1247
1262
  required: schema.required?.includes(key) || false,
1248
1263
  };
1249
1264
  // Add additional properties that Cohere might expect
1250
1265
  if (prop.enum) {
1251
- parameterDefinitions[key].options = prop.enum;
1266
+ paramDef.options = prop.enum;
1252
1267
  }
1253
1268
  if (prop.default !== undefined) {
1254
- parameterDefinitions[key].default = prop.default;
1269
+ paramDef.default = prop.default;
1255
1270
  }
1256
1271
  if (prop.items) {
1257
- parameterDefinitions[key].items = prop.items;
1272
+ paramDef.items = prop.items;
1258
1273
  }
1274
+ parameter_definitions[key] = paramDef;
1259
1275
  }
1260
1276
  }
1261
1277
  return {
1262
1278
  name: tool.name,
1263
1279
  description: tool.description,
1264
- parameterDefinitions,
1280
+ parameter_definitions, // Use snake_case as expected by Cohere API
1265
1281
  };
1266
1282
  });
1267
1283
  }
1268
- const stream = await cohereClient.chatStream(streamConfig);
1284
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
1285
+ console.log(`🔍 [Cohere] Final stream config:`, JSON.stringify(streamConfig, null, 2));
1286
+ console.log(`🔍 [Cohere] Cohere client methods available:`, Object.getOwnPropertyNames(cohereClient));
1287
+ console.log(`🔍 [Cohere] Has chatStream method:`, typeof cohereClient.chatStream === 'function');
1288
+ console.log(`🔍 [Cohere] Has chat property:`, !!cohereClient.chat);
1289
+ if (cohereClient.chat) {
1290
+ console.log(`🔍 [Cohere] Chat methods:`, Object.getOwnPropertyNames(cohereClient.chat));
1291
+ }
1292
+ console.log(`⏱️ [Cohere] Starting stream request at: ${new Date().toISOString()}`);
1293
+ }
1294
+ let stream;
1295
+ try {
1296
+ stream = await cohereClient.chatStream(streamConfig);
1297
+ }
1298
+ catch (streamError) {
1299
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
1300
+ console.error(`❌ [Cohere] Stream creation failed:`, streamError);
1301
+ if (streamError.response) {
1302
+ console.error(`❌ [Cohere] Stream response status: ${streamError.response.status}`);
1303
+ console.error(`❌ [Cohere] Stream response data:`, streamError.response.data);
1304
+ }
1305
+ if (streamError.status) {
1306
+ console.error(`❌ [Cohere] Direct status: ${streamError.status}`);
1307
+ }
1308
+ if (streamError.body) {
1309
+ console.error(`❌ [Cohere] Response body:`, streamError.body);
1310
+ }
1311
+ }
1312
+ throw streamError;
1313
+ }
1269
1314
  for await (const chunk of stream) {
1270
1315
  if (chunk.eventType === "text-generation") {
1271
1316
  const text = chunk.text;
@@ -1313,6 +1358,18 @@ onEvent, onComplete) {
1313
1358
  onComplete(fullMessage, toolCalls);
1314
1359
  }
1315
1360
  catch (error) {
1361
+ if (process.env.DEBUG_GRAPHLIT_SDK_STREAMING) {
1362
+ console.error(`❌ [Cohere] Stream error:`, error);
1363
+ if (error instanceof Error) {
1364
+ console.error(`❌ [Cohere] Error message: ${error.message}`);
1365
+ console.error(`❌ [Cohere] Error stack: ${error.stack}`);
1366
+ }
1367
+ // Log additional error details if available
1368
+ if (error.response) {
1369
+ console.error(`❌ [Cohere] Response status: ${error.response.status}`);
1370
+ console.error(`❌ [Cohere] Response data:`, error.response.data);
1371
+ }
1372
+ }
1316
1373
  throw error;
1317
1374
  }
1318
1375
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphlit-client",
3
- "version": "1.0.20250615001",
3
+ "version": "1.0.20250615003",
4
4
  "description": "Graphlit API Client for TypeScript",
5
5
  "type": "module",
6
6
  "main": "./dist/client.js",