cencori 1.0.4 → 1.2.0

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/ai/index.mjs CHANGED
@@ -27,7 +27,8 @@ var AINamespace = class {
27
27
  maxTokens: request.maxTokens,
28
28
  stream: false,
29
29
  tools: request.tools,
30
- toolChoice: request.toolChoice
30
+ toolChoice: request.toolChoice,
31
+ prompt: request.prompt
31
32
  })
32
33
  });
33
34
  if (!response.ok) {
@@ -36,7 +37,8 @@ var AINamespace = class {
36
37
  }
37
38
  const data = await response.json();
38
39
  const choice = data.choices?.[0];
39
- const toolCalls = choice?.message?.tool_calls?.map((tc) => ({
40
+ const rawToolCalls = data.toolCalls ?? data.tool_calls ?? choice?.message?.tool_calls;
41
+ const toolCalls = rawToolCalls?.map((tc) => ({
40
42
  id: tc.id,
41
43
  type: tc.type,
42
44
  function: {
@@ -45,11 +47,11 @@ var AINamespace = class {
45
47
  }
46
48
  }));
47
49
  return {
48
- id: data.id,
49
- model: data.model,
50
- content: choice?.message?.content ?? "",
50
+ id: data.id ?? `chatcmpl-${Date.now()}`,
51
+ model: data.model ?? request.model,
52
+ content: data.content ?? choice?.message?.content ?? "",
51
53
  toolCalls,
52
- finishReason: choice?.finish_reason,
54
+ finishReason: data.finish_reason ?? choice?.finish_reason,
53
55
  usage: {
54
56
  promptTokens: data.usage?.prompt_tokens ?? 0,
55
57
  completionTokens: data.usage?.completion_tokens ?? 0,
@@ -81,7 +83,8 @@ var AINamespace = class {
81
83
  maxTokens: request.maxTokens,
82
84
  stream: true,
83
85
  tools: request.tools,
84
- toolChoice: request.toolChoice
86
+ toolChoice: request.toolChoice,
87
+ prompt: request.prompt
85
88
  })
86
89
  });
87
90
  if (!response.ok) {
@@ -225,7 +228,7 @@ var AINamespace = class {
225
228
  throw new Error(`Cencori API error: ${errorData.error || response.statusText}`);
226
229
  }
227
230
  const data = await response.json();
228
- const toolCall = data.choices?.[0]?.message?.tool_calls?.[0];
231
+ const toolCall = data.toolCalls?.[0] ?? data.tool_calls?.[0] ?? data.choices?.[0]?.message?.tool_calls?.[0];
229
232
  if (!toolCall) {
230
233
  throw new Error("Model did not return structured output");
231
234
  }
@@ -288,6 +291,131 @@ var AINamespace = class {
288
291
  provider: data.provider
289
292
  };
290
293
  }
294
+ /**
295
+ * RAG (Retrieval-Augmented Generation) - Chat with automatic memory context
296
+ *
297
+ * Searches your memory namespace for relevant context and includes it
298
+ * in the prompt automatically. Returns the AI response along with sources.
299
+ *
300
+ * @example
301
+ * const response = await cencori.ai.rag({
302
+ * model: 'gpt-4o',
303
+ * messages: [{ role: 'user', content: 'What are our company policies?' }],
304
+ * namespace: 'company-docs',
305
+ * limit: 5, // number of memories to retrieve
306
+ * });
307
+ * console.log(response.message.content);
308
+ * console.log(response.sources); // retrieved context
309
+ */
310
+ async rag(request) {
311
+ const response = await fetch(`${this.config.baseUrl}/api/ai/rag`, {
312
+ method: "POST",
313
+ headers: {
314
+ "CENCORI_API_KEY": this.config.apiKey,
315
+ "Content-Type": "application/json",
316
+ ...this.config.headers
317
+ },
318
+ body: JSON.stringify({
319
+ model: request.model,
320
+ messages: request.messages,
321
+ namespace: request.namespace,
322
+ temperature: request.temperature,
323
+ maxTokens: request.maxTokens,
324
+ limit: request.limit ?? 5,
325
+ threshold: request.threshold ?? 0.5,
326
+ include_sources: request.includeSources ?? true,
327
+ stream: false
328
+ })
329
+ });
330
+ if (!response.ok) {
331
+ const errorData = await response.json().catch(() => ({ error: "Unknown error" }));
332
+ throw new Error(`Cencori API error: ${errorData.error || response.statusText}`);
333
+ }
334
+ const data = await response.json();
335
+ return {
336
+ message: {
337
+ role: "assistant",
338
+ content: data.message.content
339
+ },
340
+ model: data.model,
341
+ provider: data.provider,
342
+ usage: {
343
+ promptTokens: data.usage.prompt_tokens,
344
+ completionTokens: data.usage.completion_tokens,
345
+ totalTokens: data.usage.total_tokens
346
+ },
347
+ sources: data.sources?.map((s) => ({
348
+ content: s.content,
349
+ metadata: s.metadata,
350
+ similarity: s.similarity
351
+ })),
352
+ latencyMs: data.latency_ms
353
+ };
354
+ }
355
+ /**
356
+ * Stream RAG responses with automatic memory context
357
+ *
358
+ * @example
359
+ * for await (const chunk of cencori.ai.ragStream({ model: 'gpt-4o', messages, namespace: 'docs' })) {
360
+ * if (chunk.type === 'sources') console.log('Sources:', chunk.sources);
361
+ * if (chunk.type === 'content') process.stdout.write(chunk.delta);
362
+ * }
363
+ */
364
+ async *ragStream(request) {
365
+ const response = await fetch(`${this.config.baseUrl}/api/ai/rag`, {
366
+ method: "POST",
367
+ headers: {
368
+ "CENCORI_API_KEY": this.config.apiKey,
369
+ "Content-Type": "application/json",
370
+ ...this.config.headers
371
+ },
372
+ body: JSON.stringify({
373
+ model: request.model,
374
+ messages: request.messages,
375
+ namespace: request.namespace,
376
+ temperature: request.temperature,
377
+ maxTokens: request.maxTokens,
378
+ limit: request.limit ?? 5,
379
+ threshold: request.threshold ?? 0.5,
380
+ include_sources: request.includeSources ?? true,
381
+ stream: true
382
+ })
383
+ });
384
+ if (!response.ok) {
385
+ const errorData = await response.json().catch(() => ({ error: "Unknown error" }));
386
+ throw new Error(`Cencori API error: ${errorData.error || response.statusText}`);
387
+ }
388
+ if (!response.body) {
389
+ throw new Error("Response body is null");
390
+ }
391
+ const reader = response.body.getReader();
392
+ const decoder = new TextDecoder();
393
+ let buffer = "";
394
+ try {
395
+ while (true) {
396
+ const { done, value } = await reader.read();
397
+ if (done) break;
398
+ buffer += decoder.decode(value, { stream: true });
399
+ const lines = buffer.split("\n");
400
+ buffer = lines.pop() || "";
401
+ for (const line of lines) {
402
+ if (line.trim() === "") continue;
403
+ if (!line.startsWith("data: ")) continue;
404
+ const data = line.slice(6);
405
+ if (data === "[DONE]") {
406
+ return;
407
+ }
408
+ try {
409
+ const chunk = JSON.parse(data);
410
+ yield chunk;
411
+ } catch {
412
+ }
413
+ }
414
+ }
415
+ } finally {
416
+ reader.releaseLock();
417
+ }
418
+ }
291
419
  };
292
420
  export {
293
421
  AINamespace
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/ai/index.ts"],"sourcesContent":["/**\n * AI Gateway - Chat, Completions, Embeddings, and Streaming\n * \n * @example\n * const response = await cencori.ai.chat({\n * model: 'gpt-4o',\n * messages: [{ role: 'user', content: 'Hello!' }]\n * });\n */\n\nimport type {\n CencoriConfig,\n ChatRequest,\n ChatResponse,\n CompletionRequest,\n EmbeddingRequest,\n EmbeddingResponse,\n GenerateObjectRequest,\n GenerateObjectResponse,\n ImageGenerationRequest,\n ImageGenerationResponse,\n ToolCall\n} from '../types';\n\n// API Response types\ninterface OpenAIChatResponse {\n id: string;\n model: string;\n choices?: Array<{\n message?: {\n content?: string;\n tool_calls?: Array<{\n id: string;\n type: 'function';\n function: {\n name: string;\n arguments: string;\n };\n }>;\n };\n finish_reason?: string;\n }>;\n usage?: {\n prompt_tokens?: number;\n completion_tokens?: number;\n total_tokens?: number;\n };\n}\n\ninterface OpenAIEmbeddingResponse {\n model: string;\n data?: Array<{\n embedding: number[];\n }>;\n usage?: {\n total_tokens?: number;\n };\n}\n\n/**\n * Stream chunk from chat stream\n */\nexport interface StreamChunk {\n delta: string;\n finish_reason?: 'stop' | 'length' | 'content_filter' | 'tool_calls' | 'error';\n /** Tool calls in progress during streaming */\n toolCalls?: ToolCall[];\n /** Error message if the stream encountered an error */\n error?: string;\n}\n\nexport class AINamespace {\n private config: Required<CencoriConfig>;\n\n constructor(config: Required<CencoriConfig>) {\n this.config = config;\n }\n\n /**\n * Create a chat completion\n * \n * @example\n * const response = await cencori.ai.chat({\n * model: 'gpt-4o',\n * messages: [{ role: 'user', content: 'Hello!' }]\n * });\n */\n async chat(request: ChatRequest): Promise<ChatResponse> {\n const response = await fetch(`${this.config.baseUrl}/api/ai/chat`, {\n method: 'POST',\n headers: {\n 'CENCORI_API_KEY': this.config.apiKey,\n 'Content-Type': 'application/json',\n ...this.config.headers,\n },\n body: JSON.stringify({\n model: request.model,\n messages: request.messages,\n temperature: request.temperature,\n maxTokens: request.maxTokens,\n stream: false,\n tools: request.tools,\n toolChoice: request.toolChoice,\n }),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({ error: 'Unknown error' })) as { error?: string };\n throw new Error(`Cencori API error: ${errorData.error || response.statusText}`);\n }\n\n const data = await response.json() as OpenAIChatResponse;\n\n const choice = data.choices?.[0];\n const toolCalls = choice?.message?.tool_calls?.map(tc => ({\n id: tc.id,\n type: tc.type as 'function',\n function: {\n name: tc.function.name,\n arguments: tc.function.arguments,\n },\n }));\n\n return {\n id: data.id,\n model: data.model,\n content: choice?.message?.content ?? '',\n toolCalls,\n finishReason: choice?.finish_reason as ChatResponse['finishReason'],\n usage: {\n promptTokens: data.usage?.prompt_tokens ?? 0,\n completionTokens: data.usage?.completion_tokens ?? 0,\n totalTokens: data.usage?.total_tokens ?? 0,\n },\n };\n }\n\n /**\n * Stream chat completions\n * Returns an async generator that yields chunks as they arrive\n * \n * @example\n * for await (const chunk of cencori.ai.chatStream({ model: 'gpt-4o', messages })) {\n * process.stdout.write(chunk.delta);\n * }\n */\n async *chatStream(request: ChatRequest): AsyncGenerator<StreamChunk, void, unknown> {\n const response = await fetch(`${this.config.baseUrl}/api/ai/chat`, {\n method: 'POST',\n headers: {\n 'CENCORI_API_KEY': this.config.apiKey,\n 'Content-Type': 'application/json',\n ...this.config.headers,\n },\n body: JSON.stringify({\n model: request.model,\n messages: request.messages,\n temperature: request.temperature,\n maxTokens: request.maxTokens,\n stream: true,\n tools: request.tools,\n toolChoice: request.toolChoice,\n }),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({ error: 'Unknown error' })) as { error?: string };\n throw new Error(`Cencori API error: ${errorData.error || response.statusText}`);\n }\n\n if (!response.body) {\n throw new Error('Response body is null');\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n\n // Keep the last incomplete line in the buffer\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n if (line.trim() === '') continue;\n if (!line.startsWith('data: ')) continue;\n\n const data = line.slice(6); // Remove 'data: ' prefix\n\n if (data === '[DONE]') {\n return;\n }\n\n try {\n const chunk = JSON.parse(data) as StreamChunk;\n yield chunk;\n } catch {\n // Skip malformed JSON\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n /**\n * Create a text completion\n * \n * @example\n * const response = await cencori.ai.completions({\n * model: 'gpt-4o',\n * prompt: 'Write a haiku about coding'\n * });\n */\n async completions(request: CompletionRequest): Promise<ChatResponse> {\n // Convert to chat format internally\n return this.chat({\n model: request.model,\n messages: [{ role: 'user', content: request.prompt }],\n temperature: request.temperature,\n maxTokens: request.maxTokens,\n });\n }\n\n /**\n * Create embeddings\n * \n * @example\n * const response = await cencori.ai.embeddings({\n * model: 'text-embedding-3-small',\n * input: 'Hello world'\n * });\n */\n async embeddings(request: EmbeddingRequest): Promise<EmbeddingResponse> {\n const response = await fetch(`${this.config.baseUrl}/api/ai/embeddings`, {\n method: 'POST',\n headers: {\n 'CENCORI_API_KEY': this.config.apiKey,\n 'Content-Type': 'application/json',\n ...this.config.headers,\n },\n body: JSON.stringify({\n model: request.model,\n input: request.input,\n }),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({ error: 'Unknown error' })) as { error?: string };\n throw new Error(`Cencori API error: ${errorData.error || response.statusText}`);\n }\n\n const data = await response.json() as OpenAIEmbeddingResponse;\n\n return {\n model: data.model,\n embeddings: data.data?.map((d) => d.embedding) ?? [],\n usage: {\n totalTokens: data.usage?.total_tokens ?? 0,\n },\n };\n }\n\n /**\n * Generate structured output with JSON schema\n * \n * @example\n * const response = await cencori.ai.generateObject({\n * model: 'gpt-4o',\n * prompt: 'Generate a user profile',\n * schema: {\n * type: 'object',\n * properties: {\n * name: { type: 'string' },\n * age: { type: 'number' }\n * },\n * required: ['name', 'age']\n * }\n * });\n * console.log(response.object); // { name: 'John', age: 30 }\n */\n async generateObject<T = unknown>(request: GenerateObjectRequest): Promise<GenerateObjectResponse<T>> {\n // Build messages from prompt or use provided messages\n const messages = request.messages ?? [\n { role: 'user' as const, content: request.prompt ?? '' }\n ];\n\n // Use function calling to enforce JSON schema\n const response = await fetch(`${this.config.baseUrl}/api/ai/chat`, {\n method: 'POST',\n headers: {\n 'CENCORI_API_KEY': this.config.apiKey,\n 'Content-Type': 'application/json',\n ...this.config.headers,\n },\n body: JSON.stringify({\n model: request.model,\n messages,\n temperature: request.temperature,\n maxTokens: request.maxTokens,\n stream: false,\n tools: [{\n type: 'function',\n function: {\n name: request.schemaName ?? 'generate_object',\n description: request.schemaDescription ?? 'Generate a structured object matching the schema',\n parameters: request.schema,\n },\n }],\n toolChoice: {\n type: 'function',\n function: { name: request.schemaName ?? 'generate_object' },\n },\n }),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({ error: 'Unknown error' })) as { error?: string };\n throw new Error(`Cencori API error: ${errorData.error || response.statusText}`);\n }\n\n const data = await response.json() as OpenAIChatResponse;\n const toolCall = data.choices?.[0]?.message?.tool_calls?.[0];\n\n if (!toolCall) {\n throw new Error('Model did not return structured output');\n }\n\n let parsedObject: T;\n try {\n parsedObject = JSON.parse(toolCall.function.arguments) as T;\n } catch {\n throw new Error('Failed to parse structured output as JSON');\n }\n\n return {\n object: parsedObject,\n usage: {\n promptTokens: data.usage?.prompt_tokens ?? 0,\n completionTokens: data.usage?.completion_tokens ?? 0,\n totalTokens: data.usage?.total_tokens ?? 0,\n },\n };\n }\n\n /**\n * Generate images from a text prompt\n * \n * @example\n * const response = await cencori.ai.generateImage({\n * prompt: 'A futuristic city at sunset',\n * model: 'dall-e-3',\n * size: '1024x1024'\n * });\n * console.log(response.images[0].url);\n */\n async generateImage(request: ImageGenerationRequest): Promise<ImageGenerationResponse> {\n const response = await fetch(`${this.config.baseUrl}/api/ai/images/generate`, {\n method: 'POST',\n headers: {\n 'CENCORI_API_KEY': this.config.apiKey,\n 'Content-Type': 'application/json',\n ...this.config.headers,\n },\n body: JSON.stringify({\n prompt: request.prompt,\n model: request.model ?? 'dall-e-3',\n n: request.n,\n size: request.size,\n quality: request.quality,\n style: request.style,\n responseFormat: request.responseFormat,\n }),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({ error: 'Unknown error' })) as { error?: string; message?: string };\n throw new Error(`Cencori API error: ${errorData.message || errorData.error || response.statusText}`);\n }\n\n const data = await response.json() as {\n images: Array<{ url?: string; b64_json?: string; revisedPrompt?: string }>;\n model: string;\n provider: string;\n };\n\n return {\n images: data.images.map(img => ({\n url: img.url,\n b64Json: img.b64_json,\n revisedPrompt: img.revisedPrompt,\n })),\n model: data.model,\n provider: data.provider,\n };\n }\n}\n\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/ai/index.ts"],"sourcesContent":["/**\n * AI Gateway - Chat, Completions, Embeddings, and Streaming\n * \n * @example\n * const response = await cencori.ai.chat({\n * model: 'gpt-4o',\n * messages: [{ role: 'user', content: 'Hello!' }]\n * });\n */\n\nimport type {\n CencoriConfig,\n ChatRequest,\n ChatResponse,\n CompletionRequest,\n EmbeddingRequest,\n EmbeddingResponse,\n GenerateObjectRequest,\n GenerateObjectResponse,\n ImageGenerationRequest,\n ImageGenerationResponse,\n ToolCall\n} from '../types';\n\n// API Response types\ninterface OpenAIChatResponse {\n id?: string;\n model?: string;\n content?: string;\n finish_reason?: string;\n toolCalls?: Array<{\n id: string;\n type: 'function';\n function: {\n name: string;\n arguments: string;\n };\n }>;\n tool_calls?: Array<{\n id: string;\n type: 'function';\n function: {\n name: string;\n arguments: string;\n };\n }>;\n choices?: Array<{\n message?: {\n content?: string;\n tool_calls?: Array<{\n id: string;\n type: 'function';\n function: {\n name: string;\n arguments: string;\n };\n }>;\n };\n finish_reason?: string;\n }>;\n usage?: {\n prompt_tokens?: number;\n completion_tokens?: number;\n total_tokens?: number;\n };\n}\n\ninterface OpenAIEmbeddingResponse {\n model: string;\n data?: Array<{\n embedding: number[];\n }>;\n usage?: {\n total_tokens?: number;\n };\n}\n\n/**\n * Stream chunk from chat stream\n */\nexport interface StreamChunk {\n delta: string;\n finish_reason?: 'stop' | 'length' | 'content_filter' | 'tool_calls' | 'error';\n /** Tool calls in progress during streaming */\n toolCalls?: ToolCall[];\n /** Error message if the stream encountered an error */\n error?: string;\n}\n\nexport class AINamespace {\n private config: Required<CencoriConfig>;\n\n constructor(config: Required<CencoriConfig>) {\n this.config = config;\n }\n\n /**\n * Create a chat completion\n * \n * @example\n * const response = await cencori.ai.chat({\n * model: 'gpt-4o',\n * messages: [{ role: 'user', content: 'Hello!' }]\n * });\n */\n async chat(request: ChatRequest): Promise<ChatResponse> {\n const response = await fetch(`${this.config.baseUrl}/api/ai/chat`, {\n method: 'POST',\n headers: {\n 'CENCORI_API_KEY': this.config.apiKey,\n 'Content-Type': 'application/json',\n ...this.config.headers,\n },\n body: JSON.stringify({\n model: request.model,\n messages: request.messages,\n temperature: request.temperature,\n maxTokens: request.maxTokens,\n stream: false,\n tools: request.tools,\n toolChoice: request.toolChoice,\n prompt: request.prompt,\n }),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({ error: 'Unknown error' })) as { error?: string };\n throw new Error(`Cencori API error: ${errorData.error || response.statusText}`);\n }\n\n const data = await response.json() as OpenAIChatResponse;\n\n const choice = data.choices?.[0];\n const rawToolCalls = data.toolCalls ?? data.tool_calls ?? choice?.message?.tool_calls;\n const toolCalls = rawToolCalls?.map(tc => ({\n id: tc.id,\n type: tc.type as 'function',\n function: {\n name: tc.function.name,\n arguments: tc.function.arguments,\n },\n }));\n\n return {\n id: data.id ?? `chatcmpl-${Date.now()}`,\n model: data.model ?? request.model,\n content: data.content ?? choice?.message?.content ?? '',\n toolCalls,\n finishReason: (data.finish_reason ?? choice?.finish_reason) as ChatResponse['finishReason'],\n usage: {\n promptTokens: data.usage?.prompt_tokens ?? 0,\n completionTokens: data.usage?.completion_tokens ?? 0,\n totalTokens: data.usage?.total_tokens ?? 0,\n },\n };\n }\n\n /**\n * Stream chat completions\n * Returns an async generator that yields chunks as they arrive\n * \n * @example\n * for await (const chunk of cencori.ai.chatStream({ model: 'gpt-4o', messages })) {\n * process.stdout.write(chunk.delta);\n * }\n */\n async *chatStream(request: ChatRequest): AsyncGenerator<StreamChunk, void, unknown> {\n const response = await fetch(`${this.config.baseUrl}/api/ai/chat`, {\n method: 'POST',\n headers: {\n 'CENCORI_API_KEY': this.config.apiKey,\n 'Content-Type': 'application/json',\n ...this.config.headers,\n },\n body: JSON.stringify({\n model: request.model,\n messages: request.messages,\n temperature: request.temperature,\n maxTokens: request.maxTokens,\n stream: true,\n tools: request.tools,\n toolChoice: request.toolChoice,\n prompt: request.prompt,\n }),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({ error: 'Unknown error' })) as { error?: string };\n throw new Error(`Cencori API error: ${errorData.error || response.statusText}`);\n }\n\n if (!response.body) {\n throw new Error('Response body is null');\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n\n // Keep the last incomplete line in the buffer\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n if (line.trim() === '') continue;\n if (!line.startsWith('data: ')) continue;\n\n const data = line.slice(6); // Remove 'data: ' prefix\n\n if (data === '[DONE]') {\n return;\n }\n\n try {\n const chunk = JSON.parse(data) as StreamChunk;\n yield chunk;\n } catch {\n // Skip malformed JSON\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n /**\n * Create a text completion\n * \n * @example\n * const response = await cencori.ai.completions({\n * model: 'gpt-4o',\n * prompt: 'Write a haiku about coding'\n * });\n */\n async completions(request: CompletionRequest): Promise<ChatResponse> {\n // Convert to chat format internally\n return this.chat({\n model: request.model,\n messages: [{ role: 'user', content: request.prompt }],\n temperature: request.temperature,\n maxTokens: request.maxTokens,\n });\n }\n\n /**\n * Create embeddings\n * \n * @example\n * const response = await cencori.ai.embeddings({\n * model: 'text-embedding-3-small',\n * input: 'Hello world'\n * });\n */\n async embeddings(request: EmbeddingRequest): Promise<EmbeddingResponse> {\n const response = await fetch(`${this.config.baseUrl}/api/ai/embeddings`, {\n method: 'POST',\n headers: {\n 'CENCORI_API_KEY': this.config.apiKey,\n 'Content-Type': 'application/json',\n ...this.config.headers,\n },\n body: JSON.stringify({\n model: request.model,\n input: request.input,\n }),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({ error: 'Unknown error' })) as { error?: string };\n throw new Error(`Cencori API error: ${errorData.error || response.statusText}`);\n }\n\n const data = await response.json() as OpenAIEmbeddingResponse;\n\n return {\n model: data.model,\n embeddings: data.data?.map((d) => d.embedding) ?? [],\n usage: {\n totalTokens: data.usage?.total_tokens ?? 0,\n },\n };\n }\n\n /**\n * Generate structured output with JSON schema\n * \n * @example\n * const response = await cencori.ai.generateObject({\n * model: 'gpt-4o',\n * prompt: 'Generate a user profile',\n * schema: {\n * type: 'object',\n * properties: {\n * name: { type: 'string' },\n * age: { type: 'number' }\n * },\n * required: ['name', 'age']\n * }\n * });\n * console.log(response.object); // { name: 'John', age: 30 }\n */\n async generateObject<T = unknown>(request: GenerateObjectRequest): Promise<GenerateObjectResponse<T>> {\n // Build messages from prompt or use provided messages\n const messages = request.messages ?? [\n { role: 'user' as const, content: request.prompt ?? '' }\n ];\n\n // Use function calling to enforce JSON schema\n const response = await fetch(`${this.config.baseUrl}/api/ai/chat`, {\n method: 'POST',\n headers: {\n 'CENCORI_API_KEY': this.config.apiKey,\n 'Content-Type': 'application/json',\n ...this.config.headers,\n },\n body: JSON.stringify({\n model: request.model,\n messages,\n temperature: request.temperature,\n maxTokens: request.maxTokens,\n stream: false,\n tools: [{\n type: 'function',\n function: {\n name: request.schemaName ?? 'generate_object',\n description: request.schemaDescription ?? 'Generate a structured object matching the schema',\n parameters: request.schema,\n },\n }],\n toolChoice: {\n type: 'function',\n function: { name: request.schemaName ?? 'generate_object' },\n },\n }),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({ error: 'Unknown error' })) as { error?: string };\n throw new Error(`Cencori API error: ${errorData.error || response.statusText}`);\n }\n\n const data = await response.json() as OpenAIChatResponse;\n const toolCall = data.toolCalls?.[0] ?? data.tool_calls?.[0] ?? data.choices?.[0]?.message?.tool_calls?.[0];\n\n if (!toolCall) {\n throw new Error('Model did not return structured output');\n }\n\n let parsedObject: T;\n try {\n parsedObject = JSON.parse(toolCall.function.arguments) as T;\n } catch {\n throw new Error('Failed to parse structured output as JSON');\n }\n\n return {\n object: parsedObject,\n usage: {\n promptTokens: data.usage?.prompt_tokens ?? 0,\n completionTokens: data.usage?.completion_tokens ?? 0,\n totalTokens: data.usage?.total_tokens ?? 0,\n },\n };\n }\n\n /**\n * Generate images from a text prompt\n * \n * @example\n * const response = await cencori.ai.generateImage({\n * prompt: 'A futuristic city at sunset',\n * model: 'dall-e-3',\n * size: '1024x1024'\n * });\n * console.log(response.images[0].url);\n */\n async generateImage(request: ImageGenerationRequest): Promise<ImageGenerationResponse> {\n const response = await fetch(`${this.config.baseUrl}/api/ai/images/generate`, {\n method: 'POST',\n headers: {\n 'CENCORI_API_KEY': this.config.apiKey,\n 'Content-Type': 'application/json',\n ...this.config.headers,\n },\n body: JSON.stringify({\n prompt: request.prompt,\n model: request.model ?? 'dall-e-3',\n n: request.n,\n size: request.size,\n quality: request.quality,\n style: request.style,\n responseFormat: request.responseFormat,\n }),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({ error: 'Unknown error' })) as { error?: string; message?: string };\n throw new Error(`Cencori API error: ${errorData.message || errorData.error || response.statusText}`);\n }\n\n const data = await response.json() as {\n images: Array<{ url?: string; b64_json?: string; revisedPrompt?: string }>;\n model: string;\n provider: string;\n };\n\n return {\n images: data.images.map(img => ({\n url: img.url,\n b64Json: img.b64_json,\n revisedPrompt: img.revisedPrompt,\n })),\n model: data.model,\n provider: data.provider,\n };\n }\n\n /**\n * RAG (Retrieval-Augmented Generation) - Chat with automatic memory context\n * \n * Searches your memory namespace for relevant context and includes it\n * in the prompt automatically. Returns the AI response along with sources.\n * \n * @example\n * const response = await cencori.ai.rag({\n * model: 'gpt-4o',\n * messages: [{ role: 'user', content: 'What are our company policies?' }],\n * namespace: 'company-docs',\n * limit: 5, // number of memories to retrieve\n * });\n * console.log(response.message.content);\n * console.log(response.sources); // retrieved context\n */\n async rag(request: RagRequest): Promise<RagResponse> {\n const response = await fetch(`${this.config.baseUrl}/api/ai/rag`, {\n method: 'POST',\n headers: {\n 'CENCORI_API_KEY': this.config.apiKey,\n 'Content-Type': 'application/json',\n ...this.config.headers,\n },\n body: JSON.stringify({\n model: request.model,\n messages: request.messages,\n namespace: request.namespace,\n temperature: request.temperature,\n maxTokens: request.maxTokens,\n limit: request.limit ?? 5,\n threshold: request.threshold ?? 0.5,\n include_sources: request.includeSources ?? true,\n stream: false,\n }),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({ error: 'Unknown error' })) as { error?: string };\n throw new Error(`Cencori API error: ${errorData.error || response.statusText}`);\n }\n\n const data = await response.json() as RagApiResponse;\n\n return {\n message: {\n role: 'assistant',\n content: data.message.content,\n },\n model: data.model,\n provider: data.provider,\n usage: {\n promptTokens: data.usage.prompt_tokens,\n completionTokens: data.usage.completion_tokens,\n totalTokens: data.usage.total_tokens,\n },\n sources: data.sources?.map(s => ({\n content: s.content,\n metadata: s.metadata,\n similarity: s.similarity,\n })),\n latencyMs: data.latency_ms,\n };\n }\n\n /**\n * Stream RAG responses with automatic memory context\n * \n * @example\n * for await (const chunk of cencori.ai.ragStream({ model: 'gpt-4o', messages, namespace: 'docs' })) {\n * if (chunk.type === 'sources') console.log('Sources:', chunk.sources);\n * if (chunk.type === 'content') process.stdout.write(chunk.delta);\n * }\n */\n async *ragStream(request: RagRequest): AsyncGenerator<RagStreamChunk, void, unknown> {\n const response = await fetch(`${this.config.baseUrl}/api/ai/rag`, {\n method: 'POST',\n headers: {\n 'CENCORI_API_KEY': this.config.apiKey,\n 'Content-Type': 'application/json',\n ...this.config.headers,\n },\n body: JSON.stringify({\n model: request.model,\n messages: request.messages,\n namespace: request.namespace,\n temperature: request.temperature,\n maxTokens: request.maxTokens,\n limit: request.limit ?? 5,\n threshold: request.threshold ?? 0.5,\n include_sources: request.includeSources ?? true,\n stream: true,\n }),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({ error: 'Unknown error' })) as { error?: string };\n throw new Error(`Cencori API error: ${errorData.error || response.statusText}`);\n }\n\n if (!response.body) {\n throw new Error('Response body is null');\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n if (line.trim() === '') continue;\n if (!line.startsWith('data: ')) continue;\n\n const data = line.slice(6);\n\n if (data === '[DONE]') {\n return;\n }\n\n try {\n const chunk = JSON.parse(data) as RagStreamChunk;\n yield chunk;\n } catch {\n // Skip malformed JSON\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n}\n\n// RAG Types\nexport interface RagRequest {\n model: string;\n messages: Array<{ role: 'system' | 'user' | 'assistant'; content: string }>;\n namespace: string;\n temperature?: number;\n maxTokens?: number;\n limit?: number;\n threshold?: number;\n includeSources?: boolean;\n}\n\nexport interface RagResponse {\n message: { role: string; content: string };\n model: string;\n provider: string;\n usage: {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n };\n sources?: Array<{\n content: string;\n metadata: Record<string, unknown>;\n similarity: number;\n }>;\n latencyMs: number;\n}\n\nexport interface RagStreamChunk {\n type: 'sources' | 'content';\n delta?: string;\n finish_reason?: string;\n sources?: Array<{\n content: string;\n metadata: Record<string, unknown>;\n similarity: number;\n }>;\n}\n\ninterface RagApiResponse {\n message: { role: string; content: string };\n model: string;\n provider: string;\n usage: {\n prompt_tokens: number;\n completion_tokens: number;\n total_tokens: number;\n };\n sources?: Array<{\n content: string;\n metadata: Record<string, unknown>;\n similarity: number;\n }>;\n latency_ms: number;\n}\n"],"mappings":"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","names":[]}
@@ -1,4 +1,4 @@
1
- import { g as ComputeRunOptions } from '../types-Azq6TqIA.mjs';
1
+ import { g as ComputeRunOptions } from '../types-Cr0muEt3.mjs';
2
2
 
3
3
  /**
4
4
  * Compute Namespace - Serverless Functions & GPU Access
@@ -1,4 +1,4 @@
1
- import { g as ComputeRunOptions } from '../types-Azq6TqIA.js';
1
+ import { g as ComputeRunOptions } from '../types-Cr0muEt3.js';
2
2
 
3
3
  /**
4
4
  * Compute Namespace - Serverless Functions & GPU Access
package/dist/index.d.mts CHANGED
@@ -1,11 +1,13 @@
1
- import { C as CencoriConfig, R as RequestOptions } from './types-Azq6TqIA.mjs';
2
- export { h as ChatMessage, a as ChatRequest, b as ChatResponse, c as CompletionRequest, E as EmbeddingRequest, d as EmbeddingResponse } from './types-Azq6TqIA.mjs';
1
+ import { C as CencoriConfig, R as RequestOptions } from './types-Cr0muEt3.mjs';
2
+ export { h as ChatMessage, a as ChatRequest, b as ChatResponse, c as CompletionRequest, E as EmbeddingRequest, d as EmbeddingResponse } from './types-Cr0muEt3.mjs';
3
3
  import { AINamespace } from './ai/index.mjs';
4
4
  export { StreamChunk } from './ai/index.mjs';
5
5
  import { ComputeNamespace } from './compute/index.mjs';
6
6
  import { WorkflowNamespace } from './workflow/index.mjs';
7
7
  import { StorageNamespace } from './storage/index.mjs';
8
8
  import { MemoryClient } from './memory/index.mjs';
9
+ import { TelemetryClient } from './telemetry/index.mjs';
10
+ export { WebTelemetryPayload } from './telemetry/index.mjs';
9
11
  export { CencoriChatSettings, CencoriProvider, CencoriProviderSettings, cencori, createCencori } from './vercel/index.mjs';
10
12
  import '@ai-sdk/provider';
11
13
 
@@ -80,6 +82,18 @@ declare class Cencori {
80
82
  * await cencori.memory.search({ namespace: 'conversations', query: '...' });
81
83
  */
82
84
  readonly memory: MemoryClient;
85
+ /**
86
+ * Telemetry - Report web traffic from your app to the Cencori dashboard
87
+ *
88
+ * @example
89
+ * await cencori.telemetry.reportWebRequest({
90
+ * host: 'dochat-zeta.vercel.app',
91
+ * method: 'GET',
92
+ * path: '/api/chat',
93
+ * statusCode: 200,
94
+ * });
95
+ */
96
+ readonly telemetry: TelemetryClient;
83
97
  /**
84
98
  * Create a new Cencori client
85
99
  *
@@ -151,4 +165,4 @@ declare class SafetyError extends CencoriError {
151
165
  */
152
166
  declare function fetchWithRetry(url: string, options: RequestInit, maxRetries?: number): Promise<Response>;
153
167
 
154
- export { AINamespace, AuthenticationError, Cencori, CencoriConfig, CencoriError, ComputeNamespace, MemoryClient, RateLimitError, RequestOptions, SafetyError, StorageNamespace, WorkflowNamespace, Cencori as default, fetchWithRetry };
168
+ export { AINamespace, AuthenticationError, Cencori, CencoriConfig, CencoriError, ComputeNamespace, MemoryClient, RateLimitError, RequestOptions, SafetyError, StorageNamespace, TelemetryClient, WorkflowNamespace, Cencori as default, fetchWithRetry };
package/dist/index.d.ts CHANGED
@@ -1,11 +1,13 @@
1
- import { C as CencoriConfig, R as RequestOptions } from './types-Azq6TqIA.js';
2
- export { h as ChatMessage, a as ChatRequest, b as ChatResponse, c as CompletionRequest, E as EmbeddingRequest, d as EmbeddingResponse } from './types-Azq6TqIA.js';
1
+ import { C as CencoriConfig, R as RequestOptions } from './types-Cr0muEt3.js';
2
+ export { h as ChatMessage, a as ChatRequest, b as ChatResponse, c as CompletionRequest, E as EmbeddingRequest, d as EmbeddingResponse } from './types-Cr0muEt3.js';
3
3
  import { AINamespace } from './ai/index.js';
4
4
  export { StreamChunk } from './ai/index.js';
5
5
  import { ComputeNamespace } from './compute/index.js';
6
6
  import { WorkflowNamespace } from './workflow/index.js';
7
7
  import { StorageNamespace } from './storage/index.js';
8
8
  import { MemoryClient } from './memory/index.js';
9
+ import { TelemetryClient } from './telemetry/index.js';
10
+ export { WebTelemetryPayload } from './telemetry/index.js';
9
11
  export { CencoriChatSettings, CencoriProvider, CencoriProviderSettings, cencori, createCencori } from './vercel/index.js';
10
12
  import '@ai-sdk/provider';
11
13
 
@@ -80,6 +82,18 @@ declare class Cencori {
80
82
  * await cencori.memory.search({ namespace: 'conversations', query: '...' });
81
83
  */
82
84
  readonly memory: MemoryClient;
85
+ /**
86
+ * Telemetry - Report web traffic from your app to the Cencori dashboard
87
+ *
88
+ * @example
89
+ * await cencori.telemetry.reportWebRequest({
90
+ * host: 'dochat-zeta.vercel.app',
91
+ * method: 'GET',
92
+ * path: '/api/chat',
93
+ * statusCode: 200,
94
+ * });
95
+ */
96
+ readonly telemetry: TelemetryClient;
83
97
  /**
84
98
  * Create a new Cencori client
85
99
  *
@@ -151,4 +165,4 @@ declare class SafetyError extends CencoriError {
151
165
  */
152
166
  declare function fetchWithRetry(url: string, options: RequestInit, maxRetries?: number): Promise<Response>;
153
167
 
154
- export { AINamespace, AuthenticationError, Cencori, CencoriConfig, CencoriError, ComputeNamespace, MemoryClient, RateLimitError, RequestOptions, SafetyError, StorageNamespace, WorkflowNamespace, Cencori as default, fetchWithRetry };
168
+ export { AINamespace, AuthenticationError, Cencori, CencoriConfig, CencoriError, ComputeNamespace, MemoryClient, RateLimitError, RequestOptions, SafetyError, StorageNamespace, TelemetryClient, WorkflowNamespace, Cencori as default, fetchWithRetry };
package/dist/index.js CHANGED
@@ -29,6 +29,7 @@ __export(src_exports, {
29
29
  RateLimitError: () => RateLimitError,
30
30
  SafetyError: () => SafetyError,
31
31
  StorageNamespace: () => StorageNamespace,
32
+ TelemetryClient: () => TelemetryClient,
32
33
  WorkflowNamespace: () => WorkflowNamespace,
33
34
  cencori: () => cencori,
34
35
  createCencori: () => createCencori,
@@ -66,7 +67,8 @@ var AINamespace = class {
66
67
  maxTokens: request.maxTokens,
67
68
  stream: false,
68
69
  tools: request.tools,
69
- toolChoice: request.toolChoice
70
+ toolChoice: request.toolChoice,
71
+ prompt: request.prompt
70
72
  })
71
73
  });
72
74
  if (!response.ok) {
@@ -75,7 +77,8 @@ var AINamespace = class {
75
77
  }
76
78
  const data = await response.json();
77
79
  const choice = data.choices?.[0];
78
- const toolCalls = choice?.message?.tool_calls?.map((tc) => ({
80
+ const rawToolCalls = data.toolCalls ?? data.tool_calls ?? choice?.message?.tool_calls;
81
+ const toolCalls = rawToolCalls?.map((tc) => ({
79
82
  id: tc.id,
80
83
  type: tc.type,
81
84
  function: {
@@ -84,11 +87,11 @@ var AINamespace = class {
84
87
  }
85
88
  }));
86
89
  return {
87
- id: data.id,
88
- model: data.model,
89
- content: choice?.message?.content ?? "",
90
+ id: data.id ?? `chatcmpl-${Date.now()}`,
91
+ model: data.model ?? request.model,
92
+ content: data.content ?? choice?.message?.content ?? "",
90
93
  toolCalls,
91
- finishReason: choice?.finish_reason,
94
+ finishReason: data.finish_reason ?? choice?.finish_reason,
92
95
  usage: {
93
96
  promptTokens: data.usage?.prompt_tokens ?? 0,
94
97
  completionTokens: data.usage?.completion_tokens ?? 0,
@@ -120,7 +123,8 @@ var AINamespace = class {
120
123
  maxTokens: request.maxTokens,
121
124
  stream: true,
122
125
  tools: request.tools,
123
- toolChoice: request.toolChoice
126
+ toolChoice: request.toolChoice,
127
+ prompt: request.prompt
124
128
  })
125
129
  });
126
130
  if (!response.ok) {
@@ -264,7 +268,7 @@ var AINamespace = class {
264
268
  throw new Error(`Cencori API error: ${errorData.error || response.statusText}`);
265
269
  }
266
270
  const data = await response.json();
267
- const toolCall = data.choices?.[0]?.message?.tool_calls?.[0];
271
+ const toolCall = data.toolCalls?.[0] ?? data.tool_calls?.[0] ?? data.choices?.[0]?.message?.tool_calls?.[0];
268
272
  if (!toolCall) {
269
273
  throw new Error("Model did not return structured output");
270
274
  }
@@ -327,6 +331,131 @@ var AINamespace = class {
327
331
  provider: data.provider
328
332
  };
329
333
  }
334
+ /**
335
+ * RAG (Retrieval-Augmented Generation) - Chat with automatic memory context
336
+ *
337
+ * Searches your memory namespace for relevant context and includes it
338
+ * in the prompt automatically. Returns the AI response along with sources.
339
+ *
340
+ * @example
341
+ * const response = await cencori.ai.rag({
342
+ * model: 'gpt-4o',
343
+ * messages: [{ role: 'user', content: 'What are our company policies?' }],
344
+ * namespace: 'company-docs',
345
+ * limit: 5, // number of memories to retrieve
346
+ * });
347
+ * console.log(response.message.content);
348
+ * console.log(response.sources); // retrieved context
349
+ */
350
+ async rag(request) {
351
+ const response = await fetch(`${this.config.baseUrl}/api/ai/rag`, {
352
+ method: "POST",
353
+ headers: {
354
+ "CENCORI_API_KEY": this.config.apiKey,
355
+ "Content-Type": "application/json",
356
+ ...this.config.headers
357
+ },
358
+ body: JSON.stringify({
359
+ model: request.model,
360
+ messages: request.messages,
361
+ namespace: request.namespace,
362
+ temperature: request.temperature,
363
+ maxTokens: request.maxTokens,
364
+ limit: request.limit ?? 5,
365
+ threshold: request.threshold ?? 0.5,
366
+ include_sources: request.includeSources ?? true,
367
+ stream: false
368
+ })
369
+ });
370
+ if (!response.ok) {
371
+ const errorData = await response.json().catch(() => ({ error: "Unknown error" }));
372
+ throw new Error(`Cencori API error: ${errorData.error || response.statusText}`);
373
+ }
374
+ const data = await response.json();
375
+ return {
376
+ message: {
377
+ role: "assistant",
378
+ content: data.message.content
379
+ },
380
+ model: data.model,
381
+ provider: data.provider,
382
+ usage: {
383
+ promptTokens: data.usage.prompt_tokens,
384
+ completionTokens: data.usage.completion_tokens,
385
+ totalTokens: data.usage.total_tokens
386
+ },
387
+ sources: data.sources?.map((s) => ({
388
+ content: s.content,
389
+ metadata: s.metadata,
390
+ similarity: s.similarity
391
+ })),
392
+ latencyMs: data.latency_ms
393
+ };
394
+ }
395
+ /**
396
+ * Stream RAG responses with automatic memory context
397
+ *
398
+ * @example
399
+ * for await (const chunk of cencori.ai.ragStream({ model: 'gpt-4o', messages, namespace: 'docs' })) {
400
+ * if (chunk.type === 'sources') console.log('Sources:', chunk.sources);
401
+ * if (chunk.type === 'content') process.stdout.write(chunk.delta);
402
+ * }
403
+ */
404
+ async *ragStream(request) {
405
+ const response = await fetch(`${this.config.baseUrl}/api/ai/rag`, {
406
+ method: "POST",
407
+ headers: {
408
+ "CENCORI_API_KEY": this.config.apiKey,
409
+ "Content-Type": "application/json",
410
+ ...this.config.headers
411
+ },
412
+ body: JSON.stringify({
413
+ model: request.model,
414
+ messages: request.messages,
415
+ namespace: request.namespace,
416
+ temperature: request.temperature,
417
+ maxTokens: request.maxTokens,
418
+ limit: request.limit ?? 5,
419
+ threshold: request.threshold ?? 0.5,
420
+ include_sources: request.includeSources ?? true,
421
+ stream: true
422
+ })
423
+ });
424
+ if (!response.ok) {
425
+ const errorData = await response.json().catch(() => ({ error: "Unknown error" }));
426
+ throw new Error(`Cencori API error: ${errorData.error || response.statusText}`);
427
+ }
428
+ if (!response.body) {
429
+ throw new Error("Response body is null");
430
+ }
431
+ const reader = response.body.getReader();
432
+ const decoder = new TextDecoder();
433
+ let buffer = "";
434
+ try {
435
+ while (true) {
436
+ const { done, value } = await reader.read();
437
+ if (done) break;
438
+ buffer += decoder.decode(value, { stream: true });
439
+ const lines = buffer.split("\n");
440
+ buffer = lines.pop() || "";
441
+ for (const line of lines) {
442
+ if (line.trim() === "") continue;
443
+ if (!line.startsWith("data: ")) continue;
444
+ const data = line.slice(6);
445
+ if (data === "[DONE]") {
446
+ return;
447
+ }
448
+ try {
449
+ const chunk = JSON.parse(data);
450
+ yield chunk;
451
+ } catch {
452
+ }
453
+ }
454
+ }
455
+ } finally {
456
+ reader.releaseLock();
457
+ }
458
+ }
330
459
  };
331
460
 
332
461
  // src/compute/index.ts
@@ -629,6 +758,46 @@ var MemoryClient = class {
629
758
  }
630
759
  };
631
760
 
761
+ // src/telemetry/index.ts
762
+ var TelemetryClient = class {
763
+ constructor(config) {
764
+ this.config = config;
765
+ }
766
+ /**
767
+ * Report a web request to the Cencori dashboard.
768
+ *
769
+ * Fire-and-forget — this method never throws and never blocks
770
+ * your application. If the request fails, the error is silently
771
+ * swallowed so it cannot disrupt your app's critical path.
772
+ *
773
+ * @param payload - Web request details to log
774
+ *
775
+ * @example
776
+ * await cencori.telemetry.reportWebRequest({
777
+ * host: req.headers.get('host') || 'unknown',
778
+ * method: req.method,
779
+ * path: new URL(req.url).pathname,
780
+ * statusCode: response.status,
781
+ * userAgent: req.headers.get('user-agent') || undefined,
782
+ * latencyMs: Date.now() - startTime,
783
+ * });
784
+ */
785
+ async reportWebRequest(payload) {
786
+ try {
787
+ const url = `${this.config.baseUrl}/api/v1/telemetry/web`;
788
+ await fetch(url, {
789
+ method: "POST",
790
+ headers: {
791
+ "Content-Type": "application/json",
792
+ "CENCORI_API_KEY": this.config.apiKey
793
+ },
794
+ body: JSON.stringify(payload)
795
+ });
796
+ } catch {
797
+ }
798
+ }
799
+ };
800
+
632
801
  // src/utils.ts
633
802
  function sleep(ms) {
634
803
  return new Promise((resolve) => setTimeout(resolve, ms));
@@ -723,6 +892,7 @@ var Cencori = class {
723
892
  this.workflow = new WorkflowNamespace();
724
893
  this.storage = new StorageNamespace();
725
894
  this.memory = new MemoryClient(this.config);
895
+ this.telemetry = new TelemetryClient(this.config);
726
896
  }
727
897
  /**
728
898
  * Get the base URL for API calls
@@ -1146,6 +1316,7 @@ cencori.chat = cencori;
1146
1316
  RateLimitError,
1147
1317
  SafetyError,
1148
1318
  StorageNamespace,
1319
+ TelemetryClient,
1149
1320
  WorkflowNamespace,
1150
1321
  cencori,
1151
1322
  createCencori,