cencori 1.1.0 → 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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/tanstack/index.ts"],"sourcesContent":["/**\n * Cencori AI SDK - TanStack AI Integration\n * \n * @example\n * import { cencori } from 'cencori/tanstack';\n * import { chat } from '@tanstack/ai';\n * \n * const result = await chat({\n * adapter: cencori('gpt-4o'),\n * messages: [{ role: 'user', content: 'Hello!' }]\n * });\n * \n * @packageDocumentation\n */\n\nimport type {\n TextAdapter,\n TextOptions,\n StreamChunk,\n ContentStreamChunk,\n DoneStreamChunk,\n ErrorStreamChunk,\n ToolCallStreamChunk,\n Modality,\n DefaultMessageMetadataByModality,\n} from '@tanstack/ai';\n\n// Re-export types for convenience\nexport type {\n TextAdapter,\n TextOptions,\n StreamChunk,\n};\n\n/**\n * Cencori provider options\n */\nexport interface CencoriProviderOptions {\n /** Cencori API key */\n apiKey?: string;\n /** Base URL for Cencori API (defaults to https://cencori.com) */\n baseUrl?: string;\n /** Custom headers */\n headers?: Record<string, string>;\n}\n\n/**\n * Cencori model-specific options\n */\nexport interface CencoriModelOptions {\n /** User ID for attribution */\n userId?: string;\n}\n\n// All models supported through Cencori Gateway\nexport const CENCORI_CHAT_MODELS = [\n // OpenAI\n 'gpt-4o',\n 'gpt-4o-mini',\n 'o1',\n 'o1-mini',\n // Anthropic\n 'claude-3-5-sonnet',\n 'claude-3-opus',\n 'claude-3-haiku',\n // Google\n 'gemini-2.5-flash',\n 'gemini-2.0-flash',\n 'gemini-3-pro',\n // xAI\n 'grok-4',\n 'grok-3',\n // Mistral\n 'mistral-large',\n 'codestral',\n // DeepSeek\n 'deepseek-v3.2',\n 'deepseek-reasoner',\n // Groq\n 'llama-3-70b',\n 'mixtral-8x7b',\n] as const;\n\nexport type CencoriChatModel = (typeof CENCORI_CHAT_MODELS)[number];\n\n/**\n * Cencori adapter for TanStack AI\n */\nclass CencoriTextAdapter implements TextAdapter<\n CencoriChatModel,\n CencoriModelOptions,\n readonly ['text', 'image'],\n DefaultMessageMetadataByModality\n> {\n readonly kind = 'text' as const;\n readonly name = 'cencori';\n readonly model: CencoriChatModel;\n\n '~types': {\n providerOptions: CencoriModelOptions;\n inputModalities: readonly ['text', 'image'];\n messageMetadataByModality: DefaultMessageMetadataByModality;\n } = {} as any;\n\n private config: {\n apiKey: string;\n baseUrl: string;\n headers?: Record<string, string>;\n };\n private providerOptions: CencoriProviderOptions;\n\n constructor(model: CencoriChatModel, options: CencoriProviderOptions = {}) {\n this.model = model;\n this.providerOptions = options;\n\n const apiKey = options.apiKey ?? process.env.CENCORI_API_KEY;\n if (!apiKey) {\n throw new Error(\n 'Cencori API key is required. Pass it via options.apiKey or set CENCORI_API_KEY environment variable.'\n );\n }\n\n this.config = {\n apiKey,\n baseUrl: options.baseUrl ?? 'https://cencori.com',\n headers: options.headers,\n };\n }\n\n /**\n * Stream chat completions from the model\n */\n async *chatStream(options: TextOptions<CencoriModelOptions>): AsyncIterable<StreamChunk> {\n // Convert tools to Cencori format if present\n const tools = options.tools ? Object.values(options.tools).map(t => ({\n type: 'function' as const,\n function: {\n name: t.name,\n description: t.description,\n parameters: t.inputSchema || {},\n },\n })) : undefined;\n\n const response = await fetch(`${this.config.baseUrl}/api/ai/chat`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'CENCORI_API_KEY': this.config.apiKey!,\n ...this.config.headers,\n },\n body: JSON.stringify({\n model: this.model,\n messages: options.messages,\n temperature: options.temperature,\n maxTokens: options.maxTokens,\n stream: true,\n userId: options.modelOptions?.userId,\n tools,\n }),\n signal: options.abortController?.signal,\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({ error: 'Unknown error' })) as { error?: string };\n const errorChunk: ErrorStreamChunk = {\n type: 'error',\n id: this.generateId(),\n model: this.model,\n timestamp: Date.now(),\n error: {\n message: errorData.error || response.statusText,\n code: String(response.status),\n },\n };\n yield errorChunk;\n return;\n }\n\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error('Response body is null');\n }\n\n const decoder = new TextDecoder();\n let buffer = '';\n let content = '';\n const promptTokens = 0;\n let completionTokens = 0;\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n // Emit done chunk\n const doneChunk: DoneStreamChunk = {\n type: 'done',\n id: this.generateId(),\n model: this.model,\n timestamp: Date.now(),\n finishReason: 'stop',\n usage: {\n promptTokens,\n completionTokens,\n totalTokens: promptTokens + completionTokens,\n },\n };\n yield doneChunk;\n return;\n }\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 if (data === '[DONE]') {\n const doneChunk: DoneStreamChunk = {\n type: 'done',\n id: this.generateId(),\n model: this.model,\n timestamp: Date.now(),\n finishReason: 'stop',\n usage: {\n promptTokens,\n completionTokens,\n totalTokens: promptTokens + completionTokens,\n },\n };\n yield doneChunk;\n return;\n }\n\n try {\n const chunk = JSON.parse(data);\n\n if (chunk.delta) {\n content += chunk.delta;\n completionTokens += Math.ceil(chunk.delta.length / 4);\n\n const contentChunk: ContentStreamChunk = {\n type: 'content',\n id: this.generateId(),\n model: this.model,\n timestamp: Date.now(),\n delta: chunk.delta,\n content: content,\n role: 'assistant',\n };\n yield contentChunk;\n }\n\n // Handle tool calls\n if (chunk.tool_calls && chunk.tool_calls.length > 0) {\n for (const tc of chunk.tool_calls) {\n const toolCallChunk: ToolCallStreamChunk = {\n type: 'tool_call',\n id: this.generateId(),\n model: this.model,\n timestamp: Date.now(),\n toolCall: {\n id: tc.id,\n type: 'function',\n function: {\n name: tc.function.name,\n arguments: tc.function.arguments,\n },\n },\n index: 0,\n };\n yield toolCallChunk;\n }\n }\n\n if (chunk.finish_reason) {\n const doneChunk: DoneStreamChunk = {\n type: 'done',\n id: this.generateId(),\n model: this.model,\n timestamp: Date.now(),\n finishReason: chunk.finish_reason === 'tool_calls' ? 'tool_calls'\n : chunk.finish_reason === 'stop' ? 'stop' : null,\n usage: {\n promptTokens,\n completionTokens,\n totalTokens: promptTokens + completionTokens,\n },\n };\n yield doneChunk;\n return;\n }\n } catch {\n // Skip malformed JSON\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n /**\n * Generate structured output\n */\n async structuredOutput(options: {\n chatOptions: TextOptions<CencoriModelOptions>;\n outputSchema: any;\n }): Promise<{ data: unknown; rawText: string }> {\n const response = await fetch(`${this.config.baseUrl}/api/ai/chat`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'CENCORI_API_KEY': this.config.apiKey!,\n ...this.config.headers,\n },\n body: JSON.stringify({\n model: this.model,\n messages: options.chatOptions.messages,\n temperature: options.chatOptions.temperature,\n maxTokens: options.chatOptions.maxTokens,\n stream: false,\n responseFormat: {\n type: 'json_schema',\n json_schema: {\n name: 'structured_output',\n schema: options.outputSchema,\n strict: true,\n },\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 result = await response.json() as { content: string };\n const rawText = result.content;\n\n try {\n const data = JSON.parse(rawText);\n return { data, rawText };\n } catch {\n throw new Error(`Failed to parse structured output: ${rawText}`);\n }\n }\n\n private generateId(): string {\n return `cencori-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n}\n\n/**\n * Create a Cencori adapter for TanStack AI\n * \n * @example\n * import { createCencori } from 'cencori/tanstack';\n * \n * const myProvider = createCencori({ apiKey: 'csk_...' });\n * const adapter = myProvider('gpt-4o');\n */\nexport function createCencori(options: CencoriProviderOptions = {}) {\n return function cencoriProvider<T extends CencoriChatModel>(model: T) {\n return new CencoriTextAdapter(model, options);\n };\n}\n\n/**\n * Default Cencori provider\n * Uses CENCORI_API_KEY environment variable\n * \n * @example\n * import { cencori } from 'cencori/tanstack';\n * import { chat } from '@tanstack/ai';\n * \n * const result = await chat({\n * adapter: cencori('gpt-4o'),\n * messages: [{ role: 'user', content: 'Hello!' }]\n * });\n */\nexport function cencori<T extends CencoriChatModel>(model: T) {\n return new CencoriTextAdapter(model, {});\n}\n\n// Export adapter class for advanced use cases\nexport { CencoriTextAdapter };\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/tanstack/index.ts"],"sourcesContent":["/**\n * Cencori AI SDK - TanStack AI Integration\n * \n * @example\n * import { cencori } from 'cencori/tanstack';\n * import { chat } from '@tanstack/ai';\n * \n * const result = await chat({\n * adapter: cencori('gpt-4o'),\n * messages: [{ role: 'user', content: 'Hello!' }]\n * });\n * \n * @packageDocumentation\n */\n\nimport type {\n TextAdapter,\n TextOptions,\n StreamChunk,\n ContentStreamChunk,\n DoneStreamChunk,\n ErrorStreamChunk,\n ToolCallStreamChunk,\n Modality,\n DefaultMessageMetadataByModality,\n} from '@tanstack/ai';\n\n// Re-export types for convenience\nexport type {\n TextAdapter,\n TextOptions,\n StreamChunk,\n};\n\n/**\n * Cencori provider options\n */\nexport interface CencoriProviderOptions {\n /** Cencori API key */\n apiKey?: string;\n /** Base URL for Cencori API (defaults to https://cencori.com) */\n baseUrl?: string;\n /** Custom headers */\n headers?: Record<string, string>;\n}\n\n/**\n * Cencori model-specific options\n */\nexport interface CencoriModelOptions {\n /** User ID for attribution */\n userId?: string;\n}\n\n// All models supported through Cencori Gateway\nexport const CENCORI_CHAT_MODELS = [\n // OpenAI\n 'gpt-5.5',\n 'gpt-5.4',\n 'gpt-5.4-pro',\n 'gpt-5.3-chat-latest',\n 'gpt-5.2',\n 'gpt-5.1',\n 'gpt-5',\n 'gpt-5-mini',\n 'gpt-5-nano',\n 'gpt-4.1',\n 'gpt-4o',\n 'gpt-4o-mini',\n 'o3-pro',\n 'o3',\n 'o4-mini',\n 'o1',\n // Anthropic\n 'claude-3-5-sonnet',\n 'claude-3-opus',\n 'claude-3-haiku',\n // Google\n 'gemini-2.5-flash',\n 'gemini-2.0-flash',\n 'gemini-3-pro',\n // xAI\n 'grok-voice-think-fast',\n 'grok-4',\n 'grok-3',\n // Mistral\n 'mistral-large',\n 'codestral',\n // DeepSeek\n 'deepseek-v3.2',\n 'deepseek-reasoner',\n // Groq\n 'llama-3-70b',\n 'mixtral-8x7b',\n] as const;\n\nexport type CencoriChatModel = (typeof CENCORI_CHAT_MODELS)[number];\n\n/**\n * Cencori adapter for TanStack AI\n */\nclass CencoriTextAdapter implements TextAdapter<\n CencoriChatModel,\n CencoriModelOptions,\n readonly ['text', 'image'],\n DefaultMessageMetadataByModality\n> {\n readonly kind = 'text' as const;\n readonly name = 'cencori';\n readonly model: CencoriChatModel;\n\n '~types': {\n providerOptions: CencoriModelOptions;\n inputModalities: readonly ['text', 'image'];\n messageMetadataByModality: DefaultMessageMetadataByModality;\n } = {} as any;\n\n private config: {\n apiKey: string;\n baseUrl: string;\n headers?: Record<string, string>;\n };\n private providerOptions: CencoriProviderOptions;\n\n constructor(model: CencoriChatModel, options: CencoriProviderOptions = {}) {\n this.model = model;\n this.providerOptions = options;\n\n const apiKey = options.apiKey ?? process.env.CENCORI_API_KEY;\n if (!apiKey) {\n throw new Error(\n 'Cencori API key is required. Pass it via options.apiKey or set CENCORI_API_KEY environment variable.'\n );\n }\n\n this.config = {\n apiKey,\n baseUrl: options.baseUrl ?? 'https://cencori.com',\n headers: options.headers,\n };\n }\n\n /**\n * Stream chat completions from the model\n */\n async *chatStream(options: TextOptions<CencoriModelOptions>): AsyncIterable<StreamChunk> {\n // Convert tools to Cencori format if present\n const tools = options.tools ? Object.values(options.tools).map(t => ({\n type: 'function' as const,\n function: {\n name: t.name,\n description: t.description,\n parameters: t.inputSchema || {},\n },\n })) : undefined;\n\n const response = await fetch(`${this.config.baseUrl}/api/ai/chat`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'CENCORI_API_KEY': this.config.apiKey!,\n ...this.config.headers,\n },\n body: JSON.stringify({\n model: this.model,\n messages: options.messages,\n temperature: options.temperature,\n maxTokens: options.maxTokens,\n stream: true,\n userId: options.modelOptions?.userId,\n tools,\n }),\n signal: options.abortController?.signal,\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({ error: 'Unknown error' })) as { error?: string };\n const errorChunk: ErrorStreamChunk = {\n type: 'error',\n id: this.generateId(),\n model: this.model,\n timestamp: Date.now(),\n error: {\n message: errorData.error || response.statusText,\n code: String(response.status),\n },\n };\n yield errorChunk;\n return;\n }\n\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error('Response body is null');\n }\n\n const decoder = new TextDecoder();\n let buffer = '';\n let content = '';\n const promptTokens = 0;\n let completionTokens = 0;\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n // Emit done chunk\n const doneChunk: DoneStreamChunk = {\n type: 'done',\n id: this.generateId(),\n model: this.model,\n timestamp: Date.now(),\n finishReason: 'stop',\n usage: {\n promptTokens,\n completionTokens,\n totalTokens: promptTokens + completionTokens,\n },\n };\n yield doneChunk;\n return;\n }\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 if (data === '[DONE]') {\n const doneChunk: DoneStreamChunk = {\n type: 'done',\n id: this.generateId(),\n model: this.model,\n timestamp: Date.now(),\n finishReason: 'stop',\n usage: {\n promptTokens,\n completionTokens,\n totalTokens: promptTokens + completionTokens,\n },\n };\n yield doneChunk;\n return;\n }\n\n try {\n const chunk = JSON.parse(data);\n\n if (chunk.delta) {\n content += chunk.delta;\n completionTokens += Math.ceil(chunk.delta.length / 4);\n\n const contentChunk: ContentStreamChunk = {\n type: 'content',\n id: this.generateId(),\n model: this.model,\n timestamp: Date.now(),\n delta: chunk.delta,\n content: content,\n role: 'assistant',\n };\n yield contentChunk;\n }\n\n // Handle tool calls\n if (chunk.tool_calls && chunk.tool_calls.length > 0) {\n for (const tc of chunk.tool_calls) {\n const toolCallChunk: ToolCallStreamChunk = {\n type: 'tool_call',\n id: this.generateId(),\n model: this.model,\n timestamp: Date.now(),\n toolCall: {\n id: tc.id,\n type: 'function',\n function: {\n name: tc.function.name,\n arguments: tc.function.arguments,\n },\n },\n index: 0,\n };\n yield toolCallChunk;\n }\n }\n\n if (chunk.finish_reason) {\n const doneChunk: DoneStreamChunk = {\n type: 'done',\n id: this.generateId(),\n model: this.model,\n timestamp: Date.now(),\n finishReason: chunk.finish_reason === 'tool_calls' ? 'tool_calls'\n : chunk.finish_reason === 'stop' ? 'stop' : null,\n usage: {\n promptTokens,\n completionTokens,\n totalTokens: promptTokens + completionTokens,\n },\n };\n yield doneChunk;\n return;\n }\n } catch {\n // Skip malformed JSON\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n /**\n * Generate structured output\n */\n async structuredOutput(options: {\n chatOptions: TextOptions<CencoriModelOptions>;\n outputSchema: any;\n }): Promise<{ data: unknown; rawText: string }> {\n const response = await fetch(`${this.config.baseUrl}/api/ai/chat`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'CENCORI_API_KEY': this.config.apiKey!,\n ...this.config.headers,\n },\n body: JSON.stringify({\n model: this.model,\n messages: options.chatOptions.messages,\n temperature: options.chatOptions.temperature,\n maxTokens: options.chatOptions.maxTokens,\n stream: false,\n responseFormat: {\n type: 'json_schema',\n json_schema: {\n name: 'structured_output',\n schema: options.outputSchema,\n strict: true,\n },\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 result = await response.json() as { content: string };\n const rawText = result.content;\n\n try {\n const data = JSON.parse(rawText);\n return { data, rawText };\n } catch {\n throw new Error(`Failed to parse structured output: ${rawText}`);\n }\n }\n\n private generateId(): string {\n return `cencori-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n}\n\n/**\n * Create a Cencori adapter for TanStack AI\n * \n * @example\n * import { createCencori } from 'cencori/tanstack';\n * \n * const myProvider = createCencori({ apiKey: 'csk_...' });\n * const adapter = myProvider('gpt-4o');\n */\nexport function createCencori(options: CencoriProviderOptions = {}) {\n return function cencoriProvider<T extends CencoriChatModel>(model: T) {\n return new CencoriTextAdapter(model, options);\n };\n}\n\n/**\n * Default Cencori provider\n * Uses CENCORI_API_KEY environment variable\n * \n * @example\n * import { cencori } from 'cencori/tanstack';\n * import { chat } from '@tanstack/ai';\n * \n * const result = await chat({\n * adapter: cencori('gpt-4o'),\n * messages: [{ role: 'user', content: 'Hello!' }]\n * });\n */\nexport function cencori<T extends CencoriChatModel>(model: T) {\n return new CencoriTextAdapter(model, {});\n}\n\n// Export adapter class for advanced use cases\nexport { CencoriTextAdapter };\n"],"mappings":"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","names":[]}
@@ -1,10 +1,22 @@
1
1
  // src/tanstack/index.ts
2
2
  var CENCORI_CHAT_MODELS = [
3
3
  // OpenAI
4
+ "gpt-5.5",
5
+ "gpt-5.4",
6
+ "gpt-5.4-pro",
7
+ "gpt-5.3-chat-latest",
8
+ "gpt-5.2",
9
+ "gpt-5.1",
10
+ "gpt-5",
11
+ "gpt-5-mini",
12
+ "gpt-5-nano",
13
+ "gpt-4.1",
4
14
  "gpt-4o",
5
15
  "gpt-4o-mini",
16
+ "o3-pro",
17
+ "o3",
18
+ "o4-mini",
6
19
  "o1",
7
- "o1-mini",
8
20
  // Anthropic
9
21
  "claude-3-5-sonnet",
10
22
  "claude-3-opus",
@@ -14,6 +26,7 @@ var CENCORI_CHAT_MODELS = [
14
26
  "gemini-2.0-flash",
15
27
  "gemini-3-pro",
16
28
  // xAI
29
+ "grok-voice-think-fast",
17
30
  "grok-4",
18
31
  "grok-3",
19
32
  // Mistral
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/tanstack/index.ts"],"sourcesContent":["/**\n * Cencori AI SDK - TanStack AI Integration\n * \n * @example\n * import { cencori } from 'cencori/tanstack';\n * import { chat } from '@tanstack/ai';\n * \n * const result = await chat({\n * adapter: cencori('gpt-4o'),\n * messages: [{ role: 'user', content: 'Hello!' }]\n * });\n * \n * @packageDocumentation\n */\n\nimport type {\n TextAdapter,\n TextOptions,\n StreamChunk,\n ContentStreamChunk,\n DoneStreamChunk,\n ErrorStreamChunk,\n ToolCallStreamChunk,\n Modality,\n DefaultMessageMetadataByModality,\n} from '@tanstack/ai';\n\n// Re-export types for convenience\nexport type {\n TextAdapter,\n TextOptions,\n StreamChunk,\n};\n\n/**\n * Cencori provider options\n */\nexport interface CencoriProviderOptions {\n /** Cencori API key */\n apiKey?: string;\n /** Base URL for Cencori API (defaults to https://cencori.com) */\n baseUrl?: string;\n /** Custom headers */\n headers?: Record<string, string>;\n}\n\n/**\n * Cencori model-specific options\n */\nexport interface CencoriModelOptions {\n /** User ID for attribution */\n userId?: string;\n}\n\n// All models supported through Cencori Gateway\nexport const CENCORI_CHAT_MODELS = [\n // OpenAI\n 'gpt-4o',\n 'gpt-4o-mini',\n 'o1',\n 'o1-mini',\n // Anthropic\n 'claude-3-5-sonnet',\n 'claude-3-opus',\n 'claude-3-haiku',\n // Google\n 'gemini-2.5-flash',\n 'gemini-2.0-flash',\n 'gemini-3-pro',\n // xAI\n 'grok-4',\n 'grok-3',\n // Mistral\n 'mistral-large',\n 'codestral',\n // DeepSeek\n 'deepseek-v3.2',\n 'deepseek-reasoner',\n // Groq\n 'llama-3-70b',\n 'mixtral-8x7b',\n] as const;\n\nexport type CencoriChatModel = (typeof CENCORI_CHAT_MODELS)[number];\n\n/**\n * Cencori adapter for TanStack AI\n */\nclass CencoriTextAdapter implements TextAdapter<\n CencoriChatModel,\n CencoriModelOptions,\n readonly ['text', 'image'],\n DefaultMessageMetadataByModality\n> {\n readonly kind = 'text' as const;\n readonly name = 'cencori';\n readonly model: CencoriChatModel;\n\n '~types': {\n providerOptions: CencoriModelOptions;\n inputModalities: readonly ['text', 'image'];\n messageMetadataByModality: DefaultMessageMetadataByModality;\n } = {} as any;\n\n private config: {\n apiKey: string;\n baseUrl: string;\n headers?: Record<string, string>;\n };\n private providerOptions: CencoriProviderOptions;\n\n constructor(model: CencoriChatModel, options: CencoriProviderOptions = {}) {\n this.model = model;\n this.providerOptions = options;\n\n const apiKey = options.apiKey ?? process.env.CENCORI_API_KEY;\n if (!apiKey) {\n throw new Error(\n 'Cencori API key is required. Pass it via options.apiKey or set CENCORI_API_KEY environment variable.'\n );\n }\n\n this.config = {\n apiKey,\n baseUrl: options.baseUrl ?? 'https://cencori.com',\n headers: options.headers,\n };\n }\n\n /**\n * Stream chat completions from the model\n */\n async *chatStream(options: TextOptions<CencoriModelOptions>): AsyncIterable<StreamChunk> {\n // Convert tools to Cencori format if present\n const tools = options.tools ? Object.values(options.tools).map(t => ({\n type: 'function' as const,\n function: {\n name: t.name,\n description: t.description,\n parameters: t.inputSchema || {},\n },\n })) : undefined;\n\n const response = await fetch(`${this.config.baseUrl}/api/ai/chat`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'CENCORI_API_KEY': this.config.apiKey!,\n ...this.config.headers,\n },\n body: JSON.stringify({\n model: this.model,\n messages: options.messages,\n temperature: options.temperature,\n maxTokens: options.maxTokens,\n stream: true,\n userId: options.modelOptions?.userId,\n tools,\n }),\n signal: options.abortController?.signal,\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({ error: 'Unknown error' })) as { error?: string };\n const errorChunk: ErrorStreamChunk = {\n type: 'error',\n id: this.generateId(),\n model: this.model,\n timestamp: Date.now(),\n error: {\n message: errorData.error || response.statusText,\n code: String(response.status),\n },\n };\n yield errorChunk;\n return;\n }\n\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error('Response body is null');\n }\n\n const decoder = new TextDecoder();\n let buffer = '';\n let content = '';\n const promptTokens = 0;\n let completionTokens = 0;\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n // Emit done chunk\n const doneChunk: DoneStreamChunk = {\n type: 'done',\n id: this.generateId(),\n model: this.model,\n timestamp: Date.now(),\n finishReason: 'stop',\n usage: {\n promptTokens,\n completionTokens,\n totalTokens: promptTokens + completionTokens,\n },\n };\n yield doneChunk;\n return;\n }\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 if (data === '[DONE]') {\n const doneChunk: DoneStreamChunk = {\n type: 'done',\n id: this.generateId(),\n model: this.model,\n timestamp: Date.now(),\n finishReason: 'stop',\n usage: {\n promptTokens,\n completionTokens,\n totalTokens: promptTokens + completionTokens,\n },\n };\n yield doneChunk;\n return;\n }\n\n try {\n const chunk = JSON.parse(data);\n\n if (chunk.delta) {\n content += chunk.delta;\n completionTokens += Math.ceil(chunk.delta.length / 4);\n\n const contentChunk: ContentStreamChunk = {\n type: 'content',\n id: this.generateId(),\n model: this.model,\n timestamp: Date.now(),\n delta: chunk.delta,\n content: content,\n role: 'assistant',\n };\n yield contentChunk;\n }\n\n // Handle tool calls\n if (chunk.tool_calls && chunk.tool_calls.length > 0) {\n for (const tc of chunk.tool_calls) {\n const toolCallChunk: ToolCallStreamChunk = {\n type: 'tool_call',\n id: this.generateId(),\n model: this.model,\n timestamp: Date.now(),\n toolCall: {\n id: tc.id,\n type: 'function',\n function: {\n name: tc.function.name,\n arguments: tc.function.arguments,\n },\n },\n index: 0,\n };\n yield toolCallChunk;\n }\n }\n\n if (chunk.finish_reason) {\n const doneChunk: DoneStreamChunk = {\n type: 'done',\n id: this.generateId(),\n model: this.model,\n timestamp: Date.now(),\n finishReason: chunk.finish_reason === 'tool_calls' ? 'tool_calls'\n : chunk.finish_reason === 'stop' ? 'stop' : null,\n usage: {\n promptTokens,\n completionTokens,\n totalTokens: promptTokens + completionTokens,\n },\n };\n yield doneChunk;\n return;\n }\n } catch {\n // Skip malformed JSON\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n /**\n * Generate structured output\n */\n async structuredOutput(options: {\n chatOptions: TextOptions<CencoriModelOptions>;\n outputSchema: any;\n }): Promise<{ data: unknown; rawText: string }> {\n const response = await fetch(`${this.config.baseUrl}/api/ai/chat`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'CENCORI_API_KEY': this.config.apiKey!,\n ...this.config.headers,\n },\n body: JSON.stringify({\n model: this.model,\n messages: options.chatOptions.messages,\n temperature: options.chatOptions.temperature,\n maxTokens: options.chatOptions.maxTokens,\n stream: false,\n responseFormat: {\n type: 'json_schema',\n json_schema: {\n name: 'structured_output',\n schema: options.outputSchema,\n strict: true,\n },\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 result = await response.json() as { content: string };\n const rawText = result.content;\n\n try {\n const data = JSON.parse(rawText);\n return { data, rawText };\n } catch {\n throw new Error(`Failed to parse structured output: ${rawText}`);\n }\n }\n\n private generateId(): string {\n return `cencori-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n}\n\n/**\n * Create a Cencori adapter for TanStack AI\n * \n * @example\n * import { createCencori } from 'cencori/tanstack';\n * \n * const myProvider = createCencori({ apiKey: 'csk_...' });\n * const adapter = myProvider('gpt-4o');\n */\nexport function createCencori(options: CencoriProviderOptions = {}) {\n return function cencoriProvider<T extends CencoriChatModel>(model: T) {\n return new CencoriTextAdapter(model, options);\n };\n}\n\n/**\n * Default Cencori provider\n * Uses CENCORI_API_KEY environment variable\n * \n * @example\n * import { cencori } from 'cencori/tanstack';\n * import { chat } from '@tanstack/ai';\n * \n * const result = await chat({\n * adapter: cencori('gpt-4o'),\n * messages: [{ role: 'user', content: 'Hello!' }]\n * });\n */\nexport function cencori<T extends CencoriChatModel>(model: T) {\n return new CencoriTextAdapter(model, {});\n}\n\n// Export adapter class for advanced use cases\nexport { CencoriTextAdapter };\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/tanstack/index.ts"],"sourcesContent":["/**\n * Cencori AI SDK - TanStack AI Integration\n * \n * @example\n * import { cencori } from 'cencori/tanstack';\n * import { chat } from '@tanstack/ai';\n * \n * const result = await chat({\n * adapter: cencori('gpt-4o'),\n * messages: [{ role: 'user', content: 'Hello!' }]\n * });\n * \n * @packageDocumentation\n */\n\nimport type {\n TextAdapter,\n TextOptions,\n StreamChunk,\n ContentStreamChunk,\n DoneStreamChunk,\n ErrorStreamChunk,\n ToolCallStreamChunk,\n Modality,\n DefaultMessageMetadataByModality,\n} from '@tanstack/ai';\n\n// Re-export types for convenience\nexport type {\n TextAdapter,\n TextOptions,\n StreamChunk,\n};\n\n/**\n * Cencori provider options\n */\nexport interface CencoriProviderOptions {\n /** Cencori API key */\n apiKey?: string;\n /** Base URL for Cencori API (defaults to https://cencori.com) */\n baseUrl?: string;\n /** Custom headers */\n headers?: Record<string, string>;\n}\n\n/**\n * Cencori model-specific options\n */\nexport interface CencoriModelOptions {\n /** User ID for attribution */\n userId?: string;\n}\n\n// All models supported through Cencori Gateway\nexport const CENCORI_CHAT_MODELS = [\n // OpenAI\n 'gpt-5.5',\n 'gpt-5.4',\n 'gpt-5.4-pro',\n 'gpt-5.3-chat-latest',\n 'gpt-5.2',\n 'gpt-5.1',\n 'gpt-5',\n 'gpt-5-mini',\n 'gpt-5-nano',\n 'gpt-4.1',\n 'gpt-4o',\n 'gpt-4o-mini',\n 'o3-pro',\n 'o3',\n 'o4-mini',\n 'o1',\n // Anthropic\n 'claude-3-5-sonnet',\n 'claude-3-opus',\n 'claude-3-haiku',\n // Google\n 'gemini-2.5-flash',\n 'gemini-2.0-flash',\n 'gemini-3-pro',\n // xAI\n 'grok-voice-think-fast',\n 'grok-4',\n 'grok-3',\n // Mistral\n 'mistral-large',\n 'codestral',\n // DeepSeek\n 'deepseek-v3.2',\n 'deepseek-reasoner',\n // Groq\n 'llama-3-70b',\n 'mixtral-8x7b',\n] as const;\n\nexport type CencoriChatModel = (typeof CENCORI_CHAT_MODELS)[number];\n\n/**\n * Cencori adapter for TanStack AI\n */\nclass CencoriTextAdapter implements TextAdapter<\n CencoriChatModel,\n CencoriModelOptions,\n readonly ['text', 'image'],\n DefaultMessageMetadataByModality\n> {\n readonly kind = 'text' as const;\n readonly name = 'cencori';\n readonly model: CencoriChatModel;\n\n '~types': {\n providerOptions: CencoriModelOptions;\n inputModalities: readonly ['text', 'image'];\n messageMetadataByModality: DefaultMessageMetadataByModality;\n } = {} as any;\n\n private config: {\n apiKey: string;\n baseUrl: string;\n headers?: Record<string, string>;\n };\n private providerOptions: CencoriProviderOptions;\n\n constructor(model: CencoriChatModel, options: CencoriProviderOptions = {}) {\n this.model = model;\n this.providerOptions = options;\n\n const apiKey = options.apiKey ?? process.env.CENCORI_API_KEY;\n if (!apiKey) {\n throw new Error(\n 'Cencori API key is required. Pass it via options.apiKey or set CENCORI_API_KEY environment variable.'\n );\n }\n\n this.config = {\n apiKey,\n baseUrl: options.baseUrl ?? 'https://cencori.com',\n headers: options.headers,\n };\n }\n\n /**\n * Stream chat completions from the model\n */\n async *chatStream(options: TextOptions<CencoriModelOptions>): AsyncIterable<StreamChunk> {\n // Convert tools to Cencori format if present\n const tools = options.tools ? Object.values(options.tools).map(t => ({\n type: 'function' as const,\n function: {\n name: t.name,\n description: t.description,\n parameters: t.inputSchema || {},\n },\n })) : undefined;\n\n const response = await fetch(`${this.config.baseUrl}/api/ai/chat`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'CENCORI_API_KEY': this.config.apiKey!,\n ...this.config.headers,\n },\n body: JSON.stringify({\n model: this.model,\n messages: options.messages,\n temperature: options.temperature,\n maxTokens: options.maxTokens,\n stream: true,\n userId: options.modelOptions?.userId,\n tools,\n }),\n signal: options.abortController?.signal,\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({ error: 'Unknown error' })) as { error?: string };\n const errorChunk: ErrorStreamChunk = {\n type: 'error',\n id: this.generateId(),\n model: this.model,\n timestamp: Date.now(),\n error: {\n message: errorData.error || response.statusText,\n code: String(response.status),\n },\n };\n yield errorChunk;\n return;\n }\n\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error('Response body is null');\n }\n\n const decoder = new TextDecoder();\n let buffer = '';\n let content = '';\n const promptTokens = 0;\n let completionTokens = 0;\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n // Emit done chunk\n const doneChunk: DoneStreamChunk = {\n type: 'done',\n id: this.generateId(),\n model: this.model,\n timestamp: Date.now(),\n finishReason: 'stop',\n usage: {\n promptTokens,\n completionTokens,\n totalTokens: promptTokens + completionTokens,\n },\n };\n yield doneChunk;\n return;\n }\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 if (data === '[DONE]') {\n const doneChunk: DoneStreamChunk = {\n type: 'done',\n id: this.generateId(),\n model: this.model,\n timestamp: Date.now(),\n finishReason: 'stop',\n usage: {\n promptTokens,\n completionTokens,\n totalTokens: promptTokens + completionTokens,\n },\n };\n yield doneChunk;\n return;\n }\n\n try {\n const chunk = JSON.parse(data);\n\n if (chunk.delta) {\n content += chunk.delta;\n completionTokens += Math.ceil(chunk.delta.length / 4);\n\n const contentChunk: ContentStreamChunk = {\n type: 'content',\n id: this.generateId(),\n model: this.model,\n timestamp: Date.now(),\n delta: chunk.delta,\n content: content,\n role: 'assistant',\n };\n yield contentChunk;\n }\n\n // Handle tool calls\n if (chunk.tool_calls && chunk.tool_calls.length > 0) {\n for (const tc of chunk.tool_calls) {\n const toolCallChunk: ToolCallStreamChunk = {\n type: 'tool_call',\n id: this.generateId(),\n model: this.model,\n timestamp: Date.now(),\n toolCall: {\n id: tc.id,\n type: 'function',\n function: {\n name: tc.function.name,\n arguments: tc.function.arguments,\n },\n },\n index: 0,\n };\n yield toolCallChunk;\n }\n }\n\n if (chunk.finish_reason) {\n const doneChunk: DoneStreamChunk = {\n type: 'done',\n id: this.generateId(),\n model: this.model,\n timestamp: Date.now(),\n finishReason: chunk.finish_reason === 'tool_calls' ? 'tool_calls'\n : chunk.finish_reason === 'stop' ? 'stop' : null,\n usage: {\n promptTokens,\n completionTokens,\n totalTokens: promptTokens + completionTokens,\n },\n };\n yield doneChunk;\n return;\n }\n } catch {\n // Skip malformed JSON\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n /**\n * Generate structured output\n */\n async structuredOutput(options: {\n chatOptions: TextOptions<CencoriModelOptions>;\n outputSchema: any;\n }): Promise<{ data: unknown; rawText: string }> {\n const response = await fetch(`${this.config.baseUrl}/api/ai/chat`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'CENCORI_API_KEY': this.config.apiKey!,\n ...this.config.headers,\n },\n body: JSON.stringify({\n model: this.model,\n messages: options.chatOptions.messages,\n temperature: options.chatOptions.temperature,\n maxTokens: options.chatOptions.maxTokens,\n stream: false,\n responseFormat: {\n type: 'json_schema',\n json_schema: {\n name: 'structured_output',\n schema: options.outputSchema,\n strict: true,\n },\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 result = await response.json() as { content: string };\n const rawText = result.content;\n\n try {\n const data = JSON.parse(rawText);\n return { data, rawText };\n } catch {\n throw new Error(`Failed to parse structured output: ${rawText}`);\n }\n }\n\n private generateId(): string {\n return `cencori-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n}\n\n/**\n * Create a Cencori adapter for TanStack AI\n * \n * @example\n * import { createCencori } from 'cencori/tanstack';\n * \n * const myProvider = createCencori({ apiKey: 'csk_...' });\n * const adapter = myProvider('gpt-4o');\n */\nexport function createCencori(options: CencoriProviderOptions = {}) {\n return function cencoriProvider<T extends CencoriChatModel>(model: T) {\n return new CencoriTextAdapter(model, options);\n };\n}\n\n/**\n * Default Cencori provider\n * Uses CENCORI_API_KEY environment variable\n * \n * @example\n * import { cencori } from 'cencori/tanstack';\n * import { chat } from '@tanstack/ai';\n * \n * const result = await chat({\n * adapter: cencori('gpt-4o'),\n * messages: [{ role: 'user', content: 'Hello!' }]\n * });\n */\nexport function cencori<T extends CencoriChatModel>(model: T) {\n return new CencoriTextAdapter(model, {});\n}\n\n// Export adapter class for advanced use cases\nexport { CencoriTextAdapter };\n"],"mappings":"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","names":[]}
@@ -1,4 +1,4 @@
1
- import { C as CencoriConfig } from '../types-Azq6TqIA.mjs';
1
+ import { C as CencoriConfig } from '../types-Cr0muEt3.mjs';
2
2
 
3
3
  /**
4
4
  * Cencori Telemetry Client
@@ -1,4 +1,4 @@
1
- import { C as CencoriConfig } from '../types-Azq6TqIA.js';
1
+ import { C as CencoriConfig } from '../types-Cr0muEt3.js';
2
2
 
3
3
  /**
4
4
  * Cencori Telemetry Client
@@ -81,6 +81,20 @@ interface ChatRequest {
81
81
  tools?: ToolDefinition[];
82
82
  /** How the model chooses to call tools */
83
83
  toolChoice?: ToolChoice;
84
+ /**
85
+ * Reference a named prompt from the Cencori Prompt Registry.
86
+ * When provided, the gateway resolves the active version and
87
+ * injects it as the system message — no need to hardcode prompts.
88
+ *
89
+ * @example
90
+ * prompt: { name: 'support-agent', variables: { tier: 'pro' } }
91
+ */
92
+ prompt?: {
93
+ /** Prompt name or slug as shown in the dashboard */
94
+ name: string;
95
+ /** Template variables to interpolate (e.g. {{tier}} → 'pro') */
96
+ variables?: Record<string, string>;
97
+ };
84
98
  }
85
99
  interface ChatResponse {
86
100
  id: string;
@@ -81,6 +81,20 @@ interface ChatRequest {
81
81
  tools?: ToolDefinition[];
82
82
  /** How the model chooses to call tools */
83
83
  toolChoice?: ToolChoice;
84
+ /**
85
+ * Reference a named prompt from the Cencori Prompt Registry.
86
+ * When provided, the gateway resolves the active version and
87
+ * injects it as the system message — no need to hardcode prompts.
88
+ *
89
+ * @example
90
+ * prompt: { name: 'support-agent', variables: { tier: 'pro' } }
91
+ */
92
+ prompt?: {
93
+ /** Prompt name or slug as shown in the dashboard */
94
+ name: string;
95
+ /** Template variables to interpolate (e.g. {{tier}} → 'pro') */
96
+ variables?: Record<string, string>;
97
+ };
84
98
  }
85
99
  interface ChatResponse {
86
100
  id: string;
@@ -1,4 +1,4 @@
1
- import { W as WorkflowTriggerOptions } from '../types-Azq6TqIA.mjs';
1
+ import { W as WorkflowTriggerOptions } from '../types-Cr0muEt3.mjs';
2
2
 
3
3
  /**
4
4
  * Workflow Namespace - AI Pipelines & Orchestration
@@ -1,4 +1,4 @@
1
- import { W as WorkflowTriggerOptions } from '../types-Azq6TqIA.js';
1
+ import { W as WorkflowTriggerOptions } from '../types-Cr0muEt3.js';
2
2
 
3
3
  /**
4
4
  * Workflow Namespace - AI Pipelines & Orchestration
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "cencori",
4
- "version": "1.1.0",
4
+ "version": "1.2.0",
5
5
  "description": "Cencori - The unified infrastructure layer for AI applications. One SDK for AI Gateway, Compute, Workflow, and Storage.",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.mjs",