cencori 1.0.0 → 1.0.1
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.d.mts +22 -3
- package/dist/ai/index.d.ts +22 -3
- package/dist/ai/index.js +65 -5
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/index.mjs +65 -5
- package/dist/ai/index.mjs.map +1 -1
- package/dist/compute/index.d.mts +1 -1
- package/dist/compute/index.d.ts +1 -1
- package/dist/index.d.mts +52 -3
- package/dist/index.d.ts +52 -3
- package/dist/index.js +200 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +194 -6
- package/dist/index.mjs.map +1 -1
- package/dist/storage/index.d.mts +1 -1
- package/dist/storage/index.d.ts +1 -1
- package/dist/{types-Be_rWV2h.d.mts → types-DIuz6XWN.d.mts} +9 -1
- package/dist/{types-Be_rWV2h.d.ts → types-DIuz6XWN.d.ts} +9 -1
- package/dist/workflow/index.d.mts +1 -1
- package/dist/workflow/index.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -21,13 +21,18 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var src_exports = {};
|
|
22
22
|
__export(src_exports, {
|
|
23
23
|
AINamespace: () => AINamespace,
|
|
24
|
+
AuthenticationError: () => AuthenticationError,
|
|
24
25
|
Cencori: () => Cencori,
|
|
26
|
+
CencoriError: () => CencoriError,
|
|
25
27
|
ComputeNamespace: () => ComputeNamespace,
|
|
28
|
+
RateLimitError: () => RateLimitError,
|
|
29
|
+
SafetyError: () => SafetyError,
|
|
26
30
|
StorageNamespace: () => StorageNamespace,
|
|
27
31
|
WorkflowNamespace: () => WorkflowNamespace,
|
|
28
32
|
cencori: () => cencori,
|
|
29
33
|
createCencori: () => createCencori,
|
|
30
|
-
default: () => Cencori
|
|
34
|
+
default: () => Cencori,
|
|
35
|
+
fetchWithRetry: () => fetchWithRetry
|
|
31
36
|
});
|
|
32
37
|
module.exports = __toCommonJS(src_exports);
|
|
33
38
|
|
|
@@ -46,10 +51,10 @@ var AINamespace = class {
|
|
|
46
51
|
* });
|
|
47
52
|
*/
|
|
48
53
|
async chat(request) {
|
|
49
|
-
const response = await fetch(`${this.config.baseUrl}/api/
|
|
54
|
+
const response = await fetch(`${this.config.baseUrl}/api/ai/chat`, {
|
|
50
55
|
method: "POST",
|
|
51
56
|
headers: {
|
|
52
|
-
"
|
|
57
|
+
"CENCORI_API_KEY": this.config.apiKey,
|
|
53
58
|
"Content-Type": "application/json",
|
|
54
59
|
...this.config.headers
|
|
55
60
|
},
|
|
@@ -57,8 +62,8 @@ var AINamespace = class {
|
|
|
57
62
|
model: request.model,
|
|
58
63
|
messages: request.messages,
|
|
59
64
|
temperature: request.temperature,
|
|
60
|
-
|
|
61
|
-
stream:
|
|
65
|
+
maxTokens: request.maxTokens,
|
|
66
|
+
stream: false
|
|
62
67
|
})
|
|
63
68
|
});
|
|
64
69
|
if (!response.ok) {
|
|
@@ -77,6 +82,66 @@ var AINamespace = class {
|
|
|
77
82
|
}
|
|
78
83
|
};
|
|
79
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Stream chat completions
|
|
87
|
+
* Returns an async generator that yields chunks as they arrive
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* for await (const chunk of cencori.ai.chatStream({ model: 'gpt-4o', messages })) {
|
|
91
|
+
* process.stdout.write(chunk.delta);
|
|
92
|
+
* }
|
|
93
|
+
*/
|
|
94
|
+
async *chatStream(request) {
|
|
95
|
+
const response = await fetch(`${this.config.baseUrl}/api/ai/chat`, {
|
|
96
|
+
method: "POST",
|
|
97
|
+
headers: {
|
|
98
|
+
"CENCORI_API_KEY": this.config.apiKey,
|
|
99
|
+
"Content-Type": "application/json",
|
|
100
|
+
...this.config.headers
|
|
101
|
+
},
|
|
102
|
+
body: JSON.stringify({
|
|
103
|
+
model: request.model,
|
|
104
|
+
messages: request.messages,
|
|
105
|
+
temperature: request.temperature,
|
|
106
|
+
maxTokens: request.maxTokens,
|
|
107
|
+
stream: true
|
|
108
|
+
})
|
|
109
|
+
});
|
|
110
|
+
if (!response.ok) {
|
|
111
|
+
const errorData = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
112
|
+
throw new Error(`Cencori API error: ${errorData.error || response.statusText}`);
|
|
113
|
+
}
|
|
114
|
+
if (!response.body) {
|
|
115
|
+
throw new Error("Response body is null");
|
|
116
|
+
}
|
|
117
|
+
const reader = response.body.getReader();
|
|
118
|
+
const decoder = new TextDecoder();
|
|
119
|
+
let buffer = "";
|
|
120
|
+
try {
|
|
121
|
+
while (true) {
|
|
122
|
+
const { done, value } = await reader.read();
|
|
123
|
+
if (done) break;
|
|
124
|
+
buffer += decoder.decode(value, { stream: true });
|
|
125
|
+
const lines = buffer.split("\n");
|
|
126
|
+
buffer = lines.pop() || "";
|
|
127
|
+
for (const line of lines) {
|
|
128
|
+
if (line.trim() === "") continue;
|
|
129
|
+
if (!line.startsWith("data: ")) continue;
|
|
130
|
+
const data = line.slice(6);
|
|
131
|
+
if (data === "[DONE]") {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
try {
|
|
135
|
+
const chunk = JSON.parse(data);
|
|
136
|
+
yield chunk;
|
|
137
|
+
} catch {
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
} finally {
|
|
142
|
+
reader.releaseLock();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
80
145
|
/**
|
|
81
146
|
* Create a text completion
|
|
82
147
|
*
|
|
@@ -107,7 +172,7 @@ var AINamespace = class {
|
|
|
107
172
|
const response = await fetch(`${this.config.baseUrl}/api/v1/embeddings`, {
|
|
108
173
|
method: "POST",
|
|
109
174
|
headers: {
|
|
110
|
-
"
|
|
175
|
+
"CENCORI_API_KEY": this.config.apiKey,
|
|
111
176
|
"Content-Type": "application/json",
|
|
112
177
|
...this.config.headers
|
|
113
178
|
},
|
|
@@ -303,6 +368,67 @@ var StorageNamespace = class {
|
|
|
303
368
|
}
|
|
304
369
|
};
|
|
305
370
|
|
|
371
|
+
// src/utils.ts
|
|
372
|
+
function sleep(ms) {
|
|
373
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
374
|
+
}
|
|
375
|
+
async function fetchWithRetry(url, options, maxRetries = 3) {
|
|
376
|
+
let lastError = null;
|
|
377
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
378
|
+
try {
|
|
379
|
+
const response = await fetch(url, options);
|
|
380
|
+
if (response.ok || response.status >= 400 && response.status < 500) {
|
|
381
|
+
return response;
|
|
382
|
+
}
|
|
383
|
+
lastError = new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
384
|
+
if (attempt === maxRetries - 1) {
|
|
385
|
+
return response;
|
|
386
|
+
}
|
|
387
|
+
await sleep(Math.pow(2, attempt) * 1e3);
|
|
388
|
+
} catch (error) {
|
|
389
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
390
|
+
if (attempt === maxRetries - 1) {
|
|
391
|
+
throw lastError;
|
|
392
|
+
}
|
|
393
|
+
await sleep(Math.pow(2, attempt) * 1e3);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
throw lastError || new Error("Max retries reached");
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// src/errors.ts
|
|
400
|
+
var CencoriError = class _CencoriError extends Error {
|
|
401
|
+
constructor(message, statusCode, code) {
|
|
402
|
+
super(message);
|
|
403
|
+
this.statusCode = statusCode;
|
|
404
|
+
this.code = code;
|
|
405
|
+
this.name = "CencoriError";
|
|
406
|
+
Object.setPrototypeOf(this, _CencoriError.prototype);
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
var AuthenticationError = class _AuthenticationError extends CencoriError {
|
|
410
|
+
constructor(message = "Invalid API key") {
|
|
411
|
+
super(message, 401, "INVALID_API_KEY");
|
|
412
|
+
this.name = "AuthenticationError";
|
|
413
|
+
Object.setPrototypeOf(this, _AuthenticationError.prototype);
|
|
414
|
+
}
|
|
415
|
+
};
|
|
416
|
+
var RateLimitError = class _RateLimitError extends CencoriError {
|
|
417
|
+
constructor(message = "Rate limit exceeded") {
|
|
418
|
+
super(message, 429, "RATE_LIMIT_EXCEEDED");
|
|
419
|
+
this.name = "RateLimitError";
|
|
420
|
+
Object.setPrototypeOf(this, _RateLimitError.prototype);
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
var SafetyError = class _SafetyError extends CencoriError {
|
|
424
|
+
constructor(message = "Content safety violation", reasons) {
|
|
425
|
+
super(message, 400, "SAFETY_VIOLATION");
|
|
426
|
+
this.reasons = reasons;
|
|
427
|
+
this.name = "SafetyError";
|
|
428
|
+
Object.setPrototypeOf(this, _SafetyError.prototype);
|
|
429
|
+
}
|
|
430
|
+
};
|
|
431
|
+
|
|
306
432
|
// src/cencori.ts
|
|
307
433
|
var DEFAULT_BASE_URL = "https://cencori.com";
|
|
308
434
|
var Cencori = class {
|
|
@@ -336,6 +462,18 @@ var Cencori = class {
|
|
|
336
462
|
this.workflow = new WorkflowNamespace();
|
|
337
463
|
this.storage = new StorageNamespace();
|
|
338
464
|
}
|
|
465
|
+
/**
|
|
466
|
+
* Get the base URL for API calls
|
|
467
|
+
*/
|
|
468
|
+
getBaseUrl() {
|
|
469
|
+
return this.config.baseUrl;
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Get the API key
|
|
473
|
+
*/
|
|
474
|
+
getApiKey() {
|
|
475
|
+
return this.config.apiKey;
|
|
476
|
+
}
|
|
339
477
|
/**
|
|
340
478
|
* Get the current configuration (API key is masked)
|
|
341
479
|
*/
|
|
@@ -345,6 +483,56 @@ var Cencori = class {
|
|
|
345
483
|
apiKeyHint: `${this.config.apiKey.slice(0, 6)}...${this.config.apiKey.slice(-4)}`
|
|
346
484
|
};
|
|
347
485
|
}
|
|
486
|
+
/**
|
|
487
|
+
* Make a generic API request with retry and error handling
|
|
488
|
+
*
|
|
489
|
+
* @example
|
|
490
|
+
* const data = await cencori.request('/api/custom-endpoint', {
|
|
491
|
+
* method: 'POST',
|
|
492
|
+
* body: JSON.stringify({ foo: 'bar' })
|
|
493
|
+
* });
|
|
494
|
+
*/
|
|
495
|
+
async request(endpoint, options) {
|
|
496
|
+
const url = `${this.config.baseUrl}${endpoint}`;
|
|
497
|
+
const headers = {
|
|
498
|
+
"Content-Type": "application/json",
|
|
499
|
+
"CENCORI_API_KEY": this.config.apiKey,
|
|
500
|
+
...this.config.headers,
|
|
501
|
+
...options.headers
|
|
502
|
+
};
|
|
503
|
+
try {
|
|
504
|
+
const response = await fetchWithRetry(url, {
|
|
505
|
+
method: options.method,
|
|
506
|
+
headers,
|
|
507
|
+
body: options.body
|
|
508
|
+
});
|
|
509
|
+
const data = await response.json();
|
|
510
|
+
if (!response.ok) {
|
|
511
|
+
const errorData = data;
|
|
512
|
+
if (response.status === 401) {
|
|
513
|
+
throw new AuthenticationError(errorData.error || "Invalid API key");
|
|
514
|
+
}
|
|
515
|
+
if (response.status === 429) {
|
|
516
|
+
throw new RateLimitError(errorData.error || "Rate limit exceeded");
|
|
517
|
+
}
|
|
518
|
+
if (response.status === 400 && errorData.reasons) {
|
|
519
|
+
throw new SafetyError(errorData.error, errorData.reasons);
|
|
520
|
+
}
|
|
521
|
+
throw new CencoriError(
|
|
522
|
+
errorData.error || "Request failed",
|
|
523
|
+
response.status
|
|
524
|
+
);
|
|
525
|
+
}
|
|
526
|
+
return data;
|
|
527
|
+
} catch (error) {
|
|
528
|
+
if (error instanceof CencoriError) {
|
|
529
|
+
throw error;
|
|
530
|
+
}
|
|
531
|
+
throw new CencoriError(
|
|
532
|
+
error instanceof Error ? error.message : "Unknown error occurred"
|
|
533
|
+
);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
348
536
|
};
|
|
349
537
|
|
|
350
538
|
// src/vercel/cencori-chat-model.ts
|
|
@@ -688,11 +876,16 @@ cencori.chat = cencori;
|
|
|
688
876
|
// Annotate the CommonJS export names for ESM import in node:
|
|
689
877
|
0 && (module.exports = {
|
|
690
878
|
AINamespace,
|
|
879
|
+
AuthenticationError,
|
|
691
880
|
Cencori,
|
|
881
|
+
CencoriError,
|
|
692
882
|
ComputeNamespace,
|
|
883
|
+
RateLimitError,
|
|
884
|
+
SafetyError,
|
|
693
885
|
StorageNamespace,
|
|
694
886
|
WorkflowNamespace,
|
|
695
887
|
cencori,
|
|
696
|
-
createCencori
|
|
888
|
+
createCencori,
|
|
889
|
+
fetchWithRetry
|
|
697
890
|
});
|
|
698
891
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/ai/index.ts","../src/compute/index.ts","../src/workflow/index.ts","../src/storage/index.ts","../src/cencori.ts","../src/vercel/cencori-chat-model.ts","../src/vercel/cencori-provider.ts"],"sourcesContent":["/**\n * Cencori AI SDK\n * \n * The unified infrastructure layer for AI applications.\n * One SDK. Every AI primitive. Always secure. Always logged.\n * \n * @example Unified SDK (Recommended)\n * ```typescript\n * import { Cencori } from 'cencori';\n * \n * const cencori = new Cencori({ apiKey: 'csk_...' });\n * \n * // AI Gateway\n * await cencori.ai.chat({ model: 'gpt-4o', messages: [...] });\n * \n * // Compute (coming soon)\n * await cencori.compute.run('my-function', { input: data });\n * \n * // Workflow (coming soon)\n * await cencori.workflow.trigger('pipeline-id', { data });\n * \n * // Storage (coming soon)\n * await cencori.storage.vectors.search('query');\n * ```\n * \n * @example Vercel AI SDK Integration\n * ```typescript\n * import { cencori } from 'cencori/vercel';\n * import { streamText } from 'ai';\n * \n * const result = await streamText({\n * model: cencori('gpt-4o'),\n * messages: [{ role: 'user', content: 'Hello!' }]\n * });\n * ```\n * \n * @example TanStack AI Integration\n * ```typescript\n * import { cencori } from 'cencori/tanstack';\n * ```\n */\n\n// Unified SDK\nexport { Cencori } from './cencori';\nexport type {\n CencoriConfig,\n ChatRequest,\n ChatResponse,\n ChatMessage,\n CompletionRequest,\n EmbeddingRequest,\n EmbeddingResponse,\n} from './types';\n\n// Namespace exports for advanced usage\nexport { AINamespace } from './ai';\nexport { ComputeNamespace } from './compute';\nexport { WorkflowNamespace } from './workflow';\nexport { StorageNamespace } from './storage';\n\n// Default export for convenience\nexport { Cencori as default } from './cencori';\n\n// Re-export Vercel integration for backwards compatibility\n// Users can also import from 'cencori/vercel' directly\nexport { cencori, createCencori } from './vercel';\nexport type { CencoriProvider, CencoriProviderSettings, CencoriChatSettings } from './vercel';\n","/**\n * AI Gateway - Chat, Completions, and Embeddings\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} from '../types';\n\n// API Response types\ninterface OpenAIChatResponse {\n id: string;\n model: string;\n choices?: Array<{\n message?: {\n content?: string;\n };\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\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/v1/chat/completions`, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${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 max_tokens: request.maxTokens,\n stream: request.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 OpenAIChatResponse;\n\n return {\n id: data.id,\n model: data.model,\n content: data.choices?.[0]?.message?.content ?? '',\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 * 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/v1/embeddings`, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${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 * Compute Namespace - Serverless Functions & GPU Access\n * \n * 🚧 Coming Soon\n * \n * @example\n * const result = await cencori.compute.run('my-function', { \n * input: { data: 'hello' } \n * });\n */\n\nimport type { ComputeRunOptions } from '../types';\n\nexport class ComputeNamespace {\n /**\n * Run a serverless function\n * \n * 🚧 Coming Soon - This feature is not yet available.\n */\n async run(functionId: string, options?: ComputeRunOptions): Promise<never> {\n throw new Error(\n `cencori.compute.run() is coming soon! ` +\n `Function \"${functionId}\" cannot be executed yet. ` +\n `Join our waitlist at https://cencori.com/compute`\n );\n }\n\n /**\n * Deploy a function\n * \n * 🚧 Coming Soon - This feature is not yet available.\n */\n async deploy(config: { name: string; code: string }): Promise<never> {\n throw new Error(\n `cencori.compute.deploy() is coming soon! ` +\n `Join our waitlist at https://cencori.com/compute`\n );\n }\n\n /**\n * List deployed functions\n * \n * 🚧 Coming Soon - This feature is not yet available.\n */\n async list(): Promise<never> {\n throw new Error(\n `cencori.compute.list() is coming soon! ` +\n `Join our waitlist at https://cencori.com/compute`\n );\n }\n}\n","/**\n * Workflow Namespace - AI Pipelines & Orchestration\n * \n * 🚧 Coming Soon\n * \n * @example\n * await cencori.workflow.trigger('data-enrichment', { \n * data: { userId: '123' } \n * });\n */\n\nimport type { WorkflowTriggerOptions } from '../types';\n\nexport class WorkflowNamespace {\n /**\n * Trigger a workflow\n * \n * 🚧 Coming Soon - This feature is not yet available.\n */\n async trigger(workflowId: string, options?: WorkflowTriggerOptions): Promise<never> {\n throw new Error(\n `cencori.workflow.trigger() is coming soon! ` +\n `Workflow \"${workflowId}\" cannot be triggered yet. ` +\n `Join our waitlist at https://cencori.com/workflow`\n );\n }\n\n /**\n * Create a new workflow\n * \n * 🚧 Coming Soon - This feature is not yet available.\n */\n async create(config: { name: string; steps: unknown[] }): Promise<never> {\n throw new Error(\n `cencori.workflow.create() is coming soon! ` +\n `Join our waitlist at https://cencori.com/workflow`\n );\n }\n\n /**\n * Get workflow run status\n * \n * 🚧 Coming Soon - This feature is not yet available.\n */\n async status(runId: string): Promise<never> {\n throw new Error(\n `cencori.workflow.status() is coming soon! ` +\n `Join our waitlist at https://cencori.com/workflow`\n );\n }\n\n /**\n * List workflows\n * \n * 🚧 Coming Soon - This feature is not yet available.\n */\n async list(): Promise<never> {\n throw new Error(\n `cencori.workflow.list() is coming soon! ` +\n `Join our waitlist at https://cencori.com/workflow`\n );\n }\n}\n","/**\n * Storage Namespace - Vector Database, Knowledge Base, RAG\n * \n * 🚧 Coming Soon\n * \n * @example\n * const results = await cencori.storage.vectors.search('query', { limit: 5 });\n */\n\nimport type { VectorSearchOptions } from '../types';\n\nclass VectorsNamespace {\n /**\n * Search vectors by query\n * \n * 🚧 Coming Soon - This feature is not yet available.\n */\n async search(query: string, options?: VectorSearchOptions): Promise<never> {\n throw new Error(\n `cencori.storage.vectors.search() is coming soon! ` +\n `Join our waitlist at https://cencori.com/storage`\n );\n }\n\n /**\n * Upsert vectors\n * \n * 🚧 Coming Soon - This feature is not yet available.\n */\n async upsert(vectors: { id: string; values: number[]; metadata?: Record<string, unknown> }[]): Promise<never> {\n throw new Error(\n `cencori.storage.vectors.upsert() is coming soon! ` +\n `Join our waitlist at https://cencori.com/storage`\n );\n }\n\n /**\n * Delete vectors by ID\n * \n * 🚧 Coming Soon - This feature is not yet available.\n */\n async delete(ids: string[]): Promise<never> {\n throw new Error(\n `cencori.storage.vectors.delete() is coming soon! ` +\n `Join our waitlist at https://cencori.com/storage`\n );\n }\n}\n\nclass KnowledgeNamespace {\n /**\n * Query the knowledge base\n * \n * 🚧 Coming Soon - This feature is not yet available.\n */\n async query(question: string): Promise<never> {\n throw new Error(\n `cencori.storage.knowledge.query() is coming soon! ` +\n `Join our waitlist at https://cencori.com/storage`\n );\n }\n\n /**\n * Add documents to knowledge base\n * \n * 🚧 Coming Soon - This feature is not yet available.\n */\n async add(documents: { content: string; metadata?: Record<string, unknown> }[]): Promise<never> {\n throw new Error(\n `cencori.storage.knowledge.add() is coming soon! ` +\n `Join our waitlist at https://cencori.com/storage`\n );\n }\n}\n\nclass FilesNamespace {\n /**\n * Upload a file\n * \n * 🚧 Coming Soon - This feature is not yet available.\n */\n async upload(file: Blob | Buffer, name: string): Promise<never> {\n throw new Error(\n `cencori.storage.files.upload() is coming soon! ` +\n `Join our waitlist at https://cencori.com/storage`\n );\n }\n\n /**\n * Process a file (extract text, OCR, etc.)\n * \n * 🚧 Coming Soon - This feature is not yet available.\n */\n async process(fileId: string): Promise<never> {\n throw new Error(\n `cencori.storage.files.process() is coming soon! ` +\n `Join our waitlist at https://cencori.com/storage`\n );\n }\n}\n\nexport class StorageNamespace {\n /**\n * Vector database operations\n */\n readonly vectors = new VectorsNamespace();\n\n /**\n * Knowledge base operations (RAG)\n */\n readonly knowledge = new KnowledgeNamespace();\n\n /**\n * File storage and processing\n */\n readonly files = new FilesNamespace();\n}\n","/**\n * Cencori - Unified AI Infrastructure SDK\n * \n * One SDK for AI Gateway, Compute, Workflow, and Storage.\n * Every operation is secured, logged, and tracked.\n * \n * @example\n * import { Cencori } from 'cencori';\n * \n * const cencori = new Cencori({ apiKey: 'csk_...' });\n * \n * // AI Gateway\n * const response = await cencori.ai.chat({\n * model: 'gpt-4o',\n * messages: [{ role: 'user', content: 'Hello!' }]\n * });\n * \n * // Compute (coming soon)\n * await cencori.compute.run('my-function', { input: data });\n * \n * // Workflow (coming soon)\n * await cencori.workflow.trigger('pipeline-id', { data });\n * \n * // Storage (coming soon)\n * await cencori.storage.vectors.search('query');\n */\n\nimport type { CencoriConfig } from './types';\nimport { AINamespace } from './ai';\nimport { ComputeNamespace } from './compute';\nimport { WorkflowNamespace } from './workflow';\nimport { StorageNamespace } from './storage';\n\nconst DEFAULT_BASE_URL = 'https://cencori.com';\n\nexport class Cencori {\n private config: Required<CencoriConfig>;\n\n /**\n * AI Gateway - Chat, completions, embeddings with security & observability\n * \n * @example\n * await cencori.ai.chat({ model: 'gpt-4o', messages: [...] });\n */\n readonly ai: AINamespace;\n\n /**\n * Compute - Serverless functions & GPU access\n * \n * 🚧 Coming Soon\n * \n * @example\n * await cencori.compute.run('my-function', { input: data });\n */\n readonly compute: ComputeNamespace;\n\n /**\n * Workflow - AI pipelines & orchestration\n * \n * 🚧 Coming Soon\n * \n * @example\n * await cencori.workflow.trigger('pipeline-id', { data });\n */\n readonly workflow: WorkflowNamespace;\n\n /**\n * Storage - Vector database, knowledge base, RAG\n * \n * 🚧 Coming Soon\n * \n * @example\n * await cencori.storage.vectors.search('query');\n */\n readonly storage: StorageNamespace;\n\n /**\n * Create a new Cencori client\n * \n * @param config - Configuration options\n * @param config.apiKey - Your Cencori API key (starts with 'csk_')\n * @param config.baseUrl - Custom API base URL (default: https://cencori.com)\n * @param config.headers - Custom headers to include in requests\n * \n * @example\n * const cencori = new Cencori({ \n * apiKey: process.env.CENCORI_API_KEY \n * });\n */\n constructor(config: CencoriConfig = {}) {\n const apiKey = config.apiKey ?? process.env.CENCORI_API_KEY;\n\n if (!apiKey) {\n throw new Error(\n 'Cencori API key is required. ' +\n 'Pass it via new Cencori({ apiKey: \"csk_...\" }) or set CENCORI_API_KEY environment variable.'\n );\n }\n\n this.config = {\n apiKey,\n baseUrl: config.baseUrl ?? DEFAULT_BASE_URL,\n headers: config.headers ?? {},\n };\n\n // Initialize namespaces\n this.ai = new AINamespace(this.config);\n this.compute = new ComputeNamespace();\n this.workflow = new WorkflowNamespace();\n this.storage = new StorageNamespace();\n }\n\n /**\n * Get the current configuration (API key is masked)\n */\n getConfig(): { baseUrl: string; apiKeyHint: string } {\n return {\n baseUrl: this.config.baseUrl,\n apiKeyHint: `${this.config.apiKey.slice(0, 6)}...${this.config.apiKey.slice(-4)}`,\n };\n }\n}\n\n// Export types\nexport type { CencoriConfig, ChatRequest, ChatResponse, ChatMessage } from './types';\nexport type { AINamespace } from './ai';\nexport type { ComputeNamespace } from './compute';\nexport type { WorkflowNamespace } from './workflow';\nexport type { StorageNamespace } from './storage';\n","/**\n * Cencori Chat Language Model\n * \n * Implements the Vercel AI SDK's LanguageModelV3 interface (AI SDK v6 compatible)\n */\n\nimport type {\n LanguageModelV3,\n LanguageModelV3CallOptions,\n LanguageModelV3GenerateResult,\n LanguageModelV3StreamResult,\n LanguageModelV3StreamPart,\n LanguageModelV3Content,\n LanguageModelV3Usage,\n LanguageModelV3FinishReason,\n SharedV3Warning,\n} from '@ai-sdk/provider';\n\nexport interface CencoriChatModelSettings {\n apiKey: string;\n baseUrl: string;\n headers?: Record<string, string>;\n userId?: string;\n}\n\ninterface CencoriMessage {\n role: 'system' | 'user' | 'assistant' | 'tool';\n content: string;\n toolCallId?: string;\n}\n\n/**\n * Tool definition in Cencori format (OpenAI-compatible)\n */\ninterface CencoriTool {\n type: 'function';\n function: {\n name: string;\n description: string;\n parameters: Record<string, any>;\n };\n}\n\n/**\n * Tool call from the model\n */\ninterface CencoriToolCall {\n id: string;\n type: 'function';\n function: {\n name: string;\n arguments: string;\n };\n}\n\ninterface CencoriResponse {\n content: string;\n model: string;\n provider: string;\n usage: {\n prompt_tokens: number;\n completion_tokens: number;\n total_tokens: number;\n };\n cost_usd: number;\n finish_reason?: string;\n tool_calls?: CencoriToolCall[];\n}\n\ninterface CencoriStreamChunk {\n delta: string;\n finish_reason?: string;\n tool_calls?: CencoriToolCall[];\n}\n\nexport class CencoriChatLanguageModel implements LanguageModelV3 {\n readonly specificationVersion = 'v3' as const;\n readonly provider = 'cencori';\n\n readonly modelId: string;\n readonly supportedUrls: Record<string, RegExp[]> = {};\n private readonly settings: CencoriChatModelSettings;\n\n constructor(modelId: string, settings: CencoriChatModelSettings) {\n this.modelId = modelId;\n this.settings = settings;\n }\n\n private getHeaders(): Record<string, string> {\n return {\n 'Content-Type': 'application/json',\n 'CENCORI_API_KEY': this.settings.apiKey,\n ...this.settings.headers,\n };\n }\n\n private convertMessages(options: LanguageModelV3CallOptions): CencoriMessage[] {\n const messages: CencoriMessage[] = [];\n\n // In V3, options.prompt is directly an array of LanguageModelV3Message\n const promptMessages = options.prompt;\n\n if (!promptMessages || !Array.isArray(promptMessages)) {\n return messages;\n }\n\n for (const msg of promptMessages) {\n let content = '';\n\n if (msg.role === 'system') {\n // System messages have content as string directly\n content = msg.content as string;\n } else if (msg.role === 'user' || msg.role === 'assistant') {\n // User and assistant messages have content as array of parts\n const msgContent = msg.content;\n if (Array.isArray(msgContent)) {\n content = msgContent\n .filter((part: { type: string }) => part.type === 'text')\n .map((part: { type: string; text?: string }) => part.text || '')\n .join('');\n } else if (typeof msgContent === 'string') {\n content = msgContent;\n }\n }\n\n if (content && (msg.role === 'system' || msg.role === 'user' || msg.role === 'assistant')) {\n messages.push({\n role: msg.role as 'system' | 'user' | 'assistant',\n content,\n });\n }\n }\n\n return messages;\n }\n\n private mapFinishReason(reason?: string): LanguageModelV3FinishReason {\n let unified: 'stop' | 'length' | 'content-filter' | 'tool-calls' | 'error' | 'other';\n\n switch (reason) {\n case 'stop':\n case 'end_turn':\n unified = 'stop';\n break;\n case 'length':\n case 'max_tokens':\n unified = 'length';\n break;\n case 'content_filter':\n unified = 'content-filter';\n break;\n case 'tool_calls':\n case 'tool-calls':\n unified = 'tool-calls';\n break;\n case 'error':\n unified = 'error';\n break;\n default:\n unified = 'stop';\n }\n\n return { unified, raw: reason };\n }\n\n private buildUsage(inputTokens: number, outputTokens: number): LanguageModelV3Usage {\n return {\n inputTokens: {\n total: inputTokens,\n noCache: inputTokens,\n cacheRead: undefined,\n cacheWrite: undefined,\n },\n outputTokens: {\n total: outputTokens,\n text: outputTokens,\n reasoning: undefined,\n },\n };\n }\n\n /**\n * Convert Vercel AI SDK tools to Cencori format\n */\n private convertTools(options: LanguageModelV3CallOptions): CencoriTool[] | undefined {\n if (!options.tools || options.tools.length === 0) {\n return undefined;\n }\n\n return options.tools\n .filter(t => t.type === 'function')\n .map(t => ({\n type: 'function' as const,\n function: {\n name: t.name,\n description: t.description || '',\n parameters: t.inputSchema as Record<string, any>,\n },\n }));\n }\n\n /**\n * Convert Vercel AI SDK tool choice to Cencori format\n */\n private convertToolChoice(options: LanguageModelV3CallOptions): string | { type: 'function'; function: { name: string } } | undefined {\n const tc = options.toolChoice;\n if (!tc) return undefined;\n\n switch (tc.type) {\n case 'auto':\n return 'auto';\n case 'none':\n return 'none';\n case 'required':\n return 'required';\n case 'tool':\n return { type: 'function', function: { name: tc.toolName } };\n default:\n return undefined;\n }\n }\n\n async doGenerate(options: LanguageModelV3CallOptions): Promise<LanguageModelV3GenerateResult> {\n const messages = this.convertMessages(options);\n const tools = this.convertTools(options);\n const toolChoice = this.convertToolChoice(options);\n\n const response = await fetch(`${this.settings.baseUrl}/api/ai/chat`, {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify({\n messages,\n model: this.modelId,\n temperature: options.temperature,\n maxTokens: options.maxOutputTokens,\n stream: false,\n userId: this.settings.userId,\n tools,\n toolChoice,\n }),\n signal: options.abortSignal,\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({ error: 'Unknown error' })) as { error?: string };\n throw new Error(`Cencori API error: ${error.error || response.statusText}`);\n }\n\n const data = await response.json() as CencoriResponse;\n\n // Build content array\n const content: LanguageModelV3Content[] = [];\n\n // Add text content if present\n if (data.content) {\n content.push({\n type: 'text',\n text: data.content,\n providerMetadata: undefined,\n });\n }\n\n // Add tool calls if present\n if (data.tool_calls && data.tool_calls.length > 0) {\n for (const tc of data.tool_calls) {\n content.push({\n type: 'tool-call',\n toolCallId: tc.id,\n toolName: tc.function.name,\n input: tc.function.arguments,\n providerMetadata: undefined,\n });\n }\n }\n\n const warnings: SharedV3Warning[] = [];\n\n return {\n content,\n finishReason: this.mapFinishReason(data.finish_reason),\n usage: this.buildUsage(data.usage.prompt_tokens, data.usage.completion_tokens),\n warnings,\n };\n }\n\n async doStream(options: LanguageModelV3CallOptions): Promise<LanguageModelV3StreamResult> {\n const messages = this.convertMessages(options);\n const tools = this.convertTools(options);\n const toolChoice = this.convertToolChoice(options);\n const self = this;\n\n const response = await fetch(`${this.settings.baseUrl}/api/ai/chat`, {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify({\n messages,\n model: this.modelId,\n temperature: options.temperature,\n maxTokens: options.maxOutputTokens,\n stream: true,\n userId: this.settings.userId,\n tools,\n toolChoice,\n }),\n signal: options.abortSignal,\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({ error: 'Unknown error' })) as { error?: string };\n throw new Error(`Cencori API error: ${error.error || response.statusText}`);\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 inputTokens = 0;\n let outputTokens = 0;\n const textPartId = 'text-0';\n let started = false;\n\n const stream = new ReadableStream<LanguageModelV3StreamPart>({\n async pull(controller) {\n try {\n const { done, value } = await reader.read();\n\n if (done) {\n // End text block and finish\n if (started) {\n controller.enqueue({\n type: 'text-end',\n id: textPartId,\n });\n }\n controller.enqueue({\n type: 'finish',\n finishReason: self.mapFinishReason('stop'),\n usage: self.buildUsage(inputTokens, outputTokens),\n });\n controller.close();\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 if (started) {\n controller.enqueue({\n type: 'text-end',\n id: textPartId,\n });\n }\n controller.enqueue({\n type: 'finish',\n finishReason: self.mapFinishReason('stop'),\n usage: self.buildUsage(inputTokens, outputTokens),\n });\n controller.close();\n return;\n }\n\n try {\n const chunk = JSON.parse(data) as CencoriStreamChunk;\n\n // Handle text delta\n if (chunk.delta) {\n // Start text if not started\n if (!started) {\n started = true;\n controller.enqueue({\n type: 'text-start',\n id: textPartId,\n });\n }\n\n outputTokens += Math.ceil(chunk.delta.length / 4); // Rough estimate\n controller.enqueue({\n type: 'text-delta',\n id: textPartId,\n delta: chunk.delta,\n });\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 // Emit complete tool-call event\n controller.enqueue({\n type: 'tool-call',\n toolCallId: tc.id,\n toolName: tc.function.name,\n input: tc.function.arguments,\n providerMetadata: undefined,\n });\n }\n }\n\n if (chunk.finish_reason) {\n if (started) {\n controller.enqueue({\n type: 'text-end',\n id: textPartId,\n });\n }\n controller.enqueue({\n type: 'finish',\n finishReason: self.mapFinishReason(chunk.finish_reason),\n usage: self.buildUsage(inputTokens, outputTokens),\n });\n controller.close();\n return;\n }\n } catch {\n // Skip malformed JSON\n }\n }\n } catch (error) {\n controller.error(error);\n }\n },\n cancel() {\n reader.cancel();\n },\n });\n\n return {\n stream,\n };\n }\n}\n","/**\n * Cencori AI Provider for Vercel AI SDK\n * \n * Use Cencori with streamText(), generateText(), and useChat()\n */\n\nimport { CencoriChatLanguageModel } from './cencori-chat-model';\nimport type { CencoriProviderSettings, CencoriChatSettings } from './types';\n\nexport interface CencoriProvider {\n /**\n * Create a Cencori chat model for use with Vercel AI SDK\n * \n * @param modelId - The model ID (e.g., 'gemini-2.5-flash', 'gpt-4o', 'claude-3-opus')\n * @param settings - Optional model-specific settings\n * @returns A LanguageModelV1 compatible model\n * \n * @example\n * import { cencori } from 'cencori';\n * import { streamText } from 'ai';\n * \n * const result = await streamText({\n * model: cencori('gemini-2.5-flash'),\n * messages: [{ role: 'user', content: 'Hello!' }]\n * });\n */\n (modelId: string, settings?: CencoriChatSettings): CencoriChatLanguageModel;\n\n /**\n * Create a chat model (alias for the provider function)\n */\n chat: (modelId: string, settings?: CencoriChatSettings) => CencoriChatLanguageModel;\n}\n\n/**\n * Create a Cencori provider instance\n * \n * @param options - Provider configuration options\n * @returns A Cencori provider\n * \n * @example\n * import { createCencori } from 'cencori';\n * \n * const cencori = createCencori({\n * apiKey: process.env.CENCORI_API_KEY\n * });\n * \n * const result = await streamText({\n * model: cencori('gemini-2.5-flash'),\n * messages: [{ role: 'user', content: 'Hello!' }]\n * });\n */\nexport function createCencori(options: CencoriProviderSettings = {}): CencoriProvider {\n const baseUrl = options.baseUrl ?? 'https://cencori.com';\n const apiKey = options.apiKey ?? process.env.CENCORI_API_KEY;\n\n if (!apiKey) {\n throw new Error('Cencori API key is required. Pass it via options.apiKey or set CENCORI_API_KEY environment variable.');\n }\n\n const createModel = (modelId: string, settings: CencoriChatSettings = {}) => {\n return new CencoriChatLanguageModel(modelId, {\n apiKey,\n baseUrl,\n headers: options.headers,\n ...settings,\n });\n };\n\n const provider = function (modelId: string, settings?: CencoriChatSettings) {\n return createModel(modelId, settings);\n } as CencoriProvider;\n\n provider.chat = createModel;\n\n return provider;\n}\n\n/**\n * Default Cencori provider instance\n * Uses CENCORI_API_KEY environment variable (lazy initialization)\n * \n * @example\n * import { cencori } from 'cencori';\n * import { streamText } from 'ai';\n * \n * const result = await streamText({\n * model: cencori('gemini-2.5-flash'),\n * messages: [{ role: 'user', content: 'Hello!' }]\n * });\n */\nexport const cencori: CencoriProvider = function (modelId: string, settings?: CencoriChatSettings) {\n const apiKey = process.env.CENCORI_API_KEY;\n if (!apiKey) {\n throw new Error('CENCORI_API_KEY environment variable is required. Set it or use createCencori({ apiKey: \"...\" }) instead.');\n }\n return new CencoriChatLanguageModel(modelId, {\n apiKey,\n baseUrl: 'https://cencori.com',\n ...settings,\n });\n} as CencoriProvider;\n\ncencori.chat = cencori;\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/ai/index.ts","../src/compute/index.ts","../src/workflow/index.ts","../src/storage/index.ts","../src/utils.ts","../src/errors.ts","../src/cencori.ts","../src/vercel/cencori-chat-model.ts","../src/vercel/cencori-provider.ts"],"sourcesContent":["/**\n * Cencori AI SDK\n * \n * The unified infrastructure layer for AI applications.\n * One SDK. Every AI primitive. Always secure. Always logged.\n * \n * @example Unified SDK (Recommended)\n * ```typescript\n * import { Cencori } from 'cencori';\n * \n * const cencori = new Cencori({ apiKey: 'csk_...' });\n * \n * // AI Gateway\n * await cencori.ai.chat({ model: 'gpt-4o', messages: [...] });\n * \n * // Streaming\n * for await (const chunk of cencori.ai.chatStream({ model: 'gpt-4o', messages })) {\n * process.stdout.write(chunk.delta);\n * }\n * \n * // Compute (coming soon)\n * await cencori.compute.run('my-function', { input: data });\n * \n * // Workflow (coming soon)\n * await cencori.workflow.trigger('pipeline-id', { data });\n * \n * // Storage (coming soon)\n * await cencori.storage.vectors.search('query');\n * ```\n * \n * @example Vercel AI SDK Integration\n * ```typescript\n * import { cencori } from 'cencori/vercel';\n * import { streamText } from 'ai';\n * \n * const result = await streamText({\n * model: cencori('gpt-4o'),\n * messages: [{ role: 'user', content: 'Hello!' }]\n * });\n * ```\n * \n * @example TanStack AI Integration\n * ```typescript\n * import { cencori } from 'cencori/tanstack';\n * ```\n */\n\n// Unified SDK\nexport { Cencori } from './cencori';\nexport type {\n CencoriConfig,\n ChatRequest,\n ChatResponse,\n ChatMessage,\n CompletionRequest,\n EmbeddingRequest,\n EmbeddingResponse,\n RequestOptions,\n} from './types';\n\n// Error classes\nexport {\n CencoriError,\n AuthenticationError,\n RateLimitError,\n SafetyError,\n} from './errors';\n\n// Utilities\nexport { fetchWithRetry } from './utils';\n\n// Namespace exports for advanced usage\nexport { AINamespace, type StreamChunk } from './ai';\nexport { ComputeNamespace } from './compute';\nexport { WorkflowNamespace } from './workflow';\nexport { StorageNamespace } from './storage';\n\n// Default export for convenience\nexport { Cencori as default } from './cencori';\n\n// Re-export Vercel integration for backwards compatibility\n// Users can also import from 'cencori/vercel' directly\nexport { cencori, createCencori } from './vercel';\nexport type { CencoriProvider, CencoriProviderSettings, CencoriChatSettings } from './vercel';\n\n","/**\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} from '../types';\n\n// API Response types\ninterface OpenAIChatResponse {\n id: string;\n model: string;\n choices?: Array<{\n message?: {\n content?: string;\n };\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' | 'error';\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 }),\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 return {\n id: data.id,\n model: data.model,\n content: data.choices?.[0]?.message?.content ?? '',\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 }),\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/v1/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","/**\n * Compute Namespace - Serverless Functions & GPU Access\n * \n * 🚧 Coming Soon\n * \n * @example\n * const result = await cencori.compute.run('my-function', { \n * input: { data: 'hello' } \n * });\n */\n\nimport type { ComputeRunOptions } from '../types';\n\nexport class ComputeNamespace {\n /**\n * Run a serverless function\n * \n * 🚧 Coming Soon - This feature is not yet available.\n */\n async run(functionId: string, options?: ComputeRunOptions): Promise<never> {\n throw new Error(\n `cencori.compute.run() is coming soon! ` +\n `Function \"${functionId}\" cannot be executed yet. ` +\n `Join our waitlist at https://cencori.com/compute`\n );\n }\n\n /**\n * Deploy a function\n * \n * 🚧 Coming Soon - This feature is not yet available.\n */\n async deploy(config: { name: string; code: string }): Promise<never> {\n throw new Error(\n `cencori.compute.deploy() is coming soon! ` +\n `Join our waitlist at https://cencori.com/compute`\n );\n }\n\n /**\n * List deployed functions\n * \n * 🚧 Coming Soon - This feature is not yet available.\n */\n async list(): Promise<never> {\n throw new Error(\n `cencori.compute.list() is coming soon! ` +\n `Join our waitlist at https://cencori.com/compute`\n );\n }\n}\n","/**\n * Workflow Namespace - AI Pipelines & Orchestration\n * \n * 🚧 Coming Soon\n * \n * @example\n * await cencori.workflow.trigger('data-enrichment', { \n * data: { userId: '123' } \n * });\n */\n\nimport type { WorkflowTriggerOptions } from '../types';\n\nexport class WorkflowNamespace {\n /**\n * Trigger a workflow\n * \n * 🚧 Coming Soon - This feature is not yet available.\n */\n async trigger(workflowId: string, options?: WorkflowTriggerOptions): Promise<never> {\n throw new Error(\n `cencori.workflow.trigger() is coming soon! ` +\n `Workflow \"${workflowId}\" cannot be triggered yet. ` +\n `Join our waitlist at https://cencori.com/workflow`\n );\n }\n\n /**\n * Create a new workflow\n * \n * 🚧 Coming Soon - This feature is not yet available.\n */\n async create(config: { name: string; steps: unknown[] }): Promise<never> {\n throw new Error(\n `cencori.workflow.create() is coming soon! ` +\n `Join our waitlist at https://cencori.com/workflow`\n );\n }\n\n /**\n * Get workflow run status\n * \n * 🚧 Coming Soon - This feature is not yet available.\n */\n async status(runId: string): Promise<never> {\n throw new Error(\n `cencori.workflow.status() is coming soon! ` +\n `Join our waitlist at https://cencori.com/workflow`\n );\n }\n\n /**\n * List workflows\n * \n * 🚧 Coming Soon - This feature is not yet available.\n */\n async list(): Promise<never> {\n throw new Error(\n `cencori.workflow.list() is coming soon! ` +\n `Join our waitlist at https://cencori.com/workflow`\n );\n }\n}\n","/**\n * Storage Namespace - Vector Database, Knowledge Base, RAG\n * \n * 🚧 Coming Soon\n * \n * @example\n * const results = await cencori.storage.vectors.search('query', { limit: 5 });\n */\n\nimport type { VectorSearchOptions } from '../types';\n\nclass VectorsNamespace {\n /**\n * Search vectors by query\n * \n * 🚧 Coming Soon - This feature is not yet available.\n */\n async search(query: string, options?: VectorSearchOptions): Promise<never> {\n throw new Error(\n `cencori.storage.vectors.search() is coming soon! ` +\n `Join our waitlist at https://cencori.com/storage`\n );\n }\n\n /**\n * Upsert vectors\n * \n * 🚧 Coming Soon - This feature is not yet available.\n */\n async upsert(vectors: { id: string; values: number[]; metadata?: Record<string, unknown> }[]): Promise<never> {\n throw new Error(\n `cencori.storage.vectors.upsert() is coming soon! ` +\n `Join our waitlist at https://cencori.com/storage`\n );\n }\n\n /**\n * Delete vectors by ID\n * \n * 🚧 Coming Soon - This feature is not yet available.\n */\n async delete(ids: string[]): Promise<never> {\n throw new Error(\n `cencori.storage.vectors.delete() is coming soon! ` +\n `Join our waitlist at https://cencori.com/storage`\n );\n }\n}\n\nclass KnowledgeNamespace {\n /**\n * Query the knowledge base\n * \n * 🚧 Coming Soon - This feature is not yet available.\n */\n async query(question: string): Promise<never> {\n throw new Error(\n `cencori.storage.knowledge.query() is coming soon! ` +\n `Join our waitlist at https://cencori.com/storage`\n );\n }\n\n /**\n * Add documents to knowledge base\n * \n * 🚧 Coming Soon - This feature is not yet available.\n */\n async add(documents: { content: string; metadata?: Record<string, unknown> }[]): Promise<never> {\n throw new Error(\n `cencori.storage.knowledge.add() is coming soon! ` +\n `Join our waitlist at https://cencori.com/storage`\n );\n }\n}\n\nclass FilesNamespace {\n /**\n * Upload a file\n * \n * 🚧 Coming Soon - This feature is not yet available.\n */\n async upload(file: Blob | Buffer, name: string): Promise<never> {\n throw new Error(\n `cencori.storage.files.upload() is coming soon! ` +\n `Join our waitlist at https://cencori.com/storage`\n );\n }\n\n /**\n * Process a file (extract text, OCR, etc.)\n * \n * 🚧 Coming Soon - This feature is not yet available.\n */\n async process(fileId: string): Promise<never> {\n throw new Error(\n `cencori.storage.files.process() is coming soon! ` +\n `Join our waitlist at https://cencori.com/storage`\n );\n }\n}\n\nexport class StorageNamespace {\n /**\n * Vector database operations\n */\n readonly vectors = new VectorsNamespace();\n\n /**\n * Knowledge base operations (RAG)\n */\n readonly knowledge = new KnowledgeNamespace();\n\n /**\n * File storage and processing\n */\n readonly files = new FilesNamespace();\n}\n","/**\n * Utility functions for Cencori SDK\n */\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n/**\n * Fetch with automatic retry on 5xx errors\n * Uses exponential backoff: 1s, 2s, 4s\n */\nexport async function fetchWithRetry(\n url: string,\n options: RequestInit,\n maxRetries = 3\n): Promise<Response> {\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt < maxRetries; attempt++) {\n try {\n const response = await fetch(url, options);\n\n // Return immediately if request succeeded or if it's a client error (4xx)\n if (response.ok || (response.status >= 400 && response.status < 500)) {\n return response;\n }\n\n // Retry on 5xx errors\n lastError = new Error(`HTTP ${response.status}: ${response.statusText}`);\n\n // Don't retry on last attempt\n if (attempt === maxRetries - 1) {\n return response;\n }\n\n // Exponential backoff: 1s, 2s, 4s\n await sleep(Math.pow(2, attempt) * 1000);\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n // Don't retry on last attempt\n if (attempt === maxRetries - 1) {\n throw lastError;\n }\n\n // Exponential backoff\n await sleep(Math.pow(2, attempt) * 1000);\n }\n }\n\n throw lastError || new Error('Max retries reached');\n}\n","/**\n * Cencori Error Classes\n * \n * Custom error types for better error handling\n */\n\nexport class CencoriError extends Error {\n constructor(\n message: string,\n public statusCode?: number,\n public code?: string\n ) {\n super(message);\n this.name = 'CencoriError';\n Object.setPrototypeOf(this, CencoriError.prototype);\n }\n}\n\nexport class AuthenticationError extends CencoriError {\n constructor(message = 'Invalid API key') {\n super(message, 401, 'INVALID_API_KEY');\n this.name = 'AuthenticationError';\n Object.setPrototypeOf(this, AuthenticationError.prototype);\n }\n}\n\nexport class RateLimitError extends CencoriError {\n constructor(message = 'Rate limit exceeded') {\n super(message, 429, 'RATE_LIMIT_EXCEEDED');\n this.name = 'RateLimitError';\n Object.setPrototypeOf(this, RateLimitError.prototype);\n }\n}\n\nexport class SafetyError extends CencoriError {\n constructor(message = 'Content safety violation', public reasons?: string[]) {\n super(message, 400, 'SAFETY_VIOLATION');\n this.name = 'SafetyError';\n Object.setPrototypeOf(this, SafetyError.prototype);\n }\n}\n","/**\n * Cencori - Unified AI Infrastructure SDK\n * \n * One SDK for AI Gateway, Compute, Workflow, and Storage.\n * Every operation is secured, logged, and tracked.\n * \n * @example\n * import { Cencori } from 'cencori';\n * \n * const cencori = new Cencori({ apiKey: 'csk_...' });\n * \n * // AI Gateway\n * const response = await cencori.ai.chat({\n * model: 'gpt-4o',\n * messages: [{ role: 'user', content: 'Hello!' }]\n * });\n * \n * // Compute (coming soon)\n * await cencori.compute.run('my-function', { input: data });\n * \n * // Workflow (coming soon)\n * await cencori.workflow.trigger('pipeline-id', { data });\n * \n * // Storage (coming soon)\n * await cencori.storage.vectors.search('query');\n */\n\nimport type { CencoriConfig, RequestOptions } from './types';\nimport { AINamespace } from './ai';\nimport { ComputeNamespace } from './compute';\nimport { WorkflowNamespace } from './workflow';\nimport { StorageNamespace } from './storage';\nimport { fetchWithRetry } from './utils';\nimport {\n CencoriError,\n AuthenticationError,\n RateLimitError,\n SafetyError\n} from './errors';\n\nconst DEFAULT_BASE_URL = 'https://cencori.com';\n\ninterface ErrorResponse {\n error?: string;\n reasons?: string[];\n}\n\nexport class Cencori {\n private config: Required<CencoriConfig>;\n\n /**\n * AI Gateway - Chat, completions, embeddings with security & observability\n * \n * @example\n * await cencori.ai.chat({ model: 'gpt-4o', messages: [...] });\n */\n readonly ai: AINamespace;\n\n /**\n * Compute - Serverless functions & GPU access\n * \n * 🚧 Coming Soon\n * \n * @example\n * await cencori.compute.run('my-function', { input: data });\n */\n readonly compute: ComputeNamespace;\n\n /**\n * Workflow - AI pipelines & orchestration\n * \n * 🚧 Coming Soon\n * \n * @example\n * await cencori.workflow.trigger('pipeline-id', { data });\n */\n readonly workflow: WorkflowNamespace;\n\n /**\n * Storage - Vector database, knowledge base, RAG\n * \n * 🚧 Coming Soon\n * \n * @example\n * await cencori.storage.vectors.search('query');\n */\n readonly storage: StorageNamespace;\n\n /**\n * Create a new Cencori client\n * \n * @param config - Configuration options\n * @param config.apiKey - Your Cencori API key (starts with 'csk_')\n * @param config.baseUrl - Custom API base URL (default: https://cencori.com)\n * @param config.headers - Custom headers to include in requests\n * \n * @example\n * const cencori = new Cencori({ \n * apiKey: process.env.CENCORI_API_KEY \n * });\n */\n constructor(config: CencoriConfig = {}) {\n const apiKey = config.apiKey ?? process.env.CENCORI_API_KEY;\n\n if (!apiKey) {\n throw new Error(\n 'Cencori API key is required. ' +\n 'Pass it via new Cencori({ apiKey: \"csk_...\" }) or set CENCORI_API_KEY environment variable.'\n );\n }\n\n this.config = {\n apiKey,\n baseUrl: config.baseUrl ?? DEFAULT_BASE_URL,\n headers: config.headers ?? {},\n };\n\n // Initialize namespaces\n this.ai = new AINamespace(this.config);\n this.compute = new ComputeNamespace();\n this.workflow = new WorkflowNamespace();\n this.storage = new StorageNamespace();\n }\n\n /**\n * Get the base URL for API calls\n */\n getBaseUrl(): string {\n return this.config.baseUrl;\n }\n\n /**\n * Get the API key\n */\n getApiKey(): string {\n return this.config.apiKey;\n }\n\n /**\n * Get the current configuration (API key is masked)\n */\n getConfig(): { baseUrl: string; apiKeyHint: string } {\n return {\n baseUrl: this.config.baseUrl,\n apiKeyHint: `${this.config.apiKey.slice(0, 6)}...${this.config.apiKey.slice(-4)}`,\n };\n }\n\n /**\n * Make a generic API request with retry and error handling\n * \n * @example\n * const data = await cencori.request('/api/custom-endpoint', {\n * method: 'POST',\n * body: JSON.stringify({ foo: 'bar' })\n * });\n */\n async request<T>(endpoint: string, options: RequestOptions): Promise<T> {\n const url = `${this.config.baseUrl}${endpoint}`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'CENCORI_API_KEY': this.config.apiKey,\n ...this.config.headers,\n ...options.headers\n };\n\n try {\n const response = await fetchWithRetry(url, {\n method: options.method,\n headers,\n body: options.body\n });\n\n const data: unknown = await response.json();\n\n // Handle API errors\n if (!response.ok) {\n const errorData = data as ErrorResponse;\n\n if (response.status === 401) {\n throw new AuthenticationError(errorData.error || 'Invalid API key');\n }\n if (response.status === 429) {\n throw new RateLimitError(errorData.error || 'Rate limit exceeded');\n }\n if (response.status === 400 && errorData.reasons) {\n throw new SafetyError(errorData.error, errorData.reasons);\n }\n throw new CencoriError(\n errorData.error || 'Request failed',\n response.status\n );\n }\n\n return data as T;\n } catch (error) {\n // Re-throw custom errors\n if (error instanceof CencoriError) {\n throw error;\n }\n\n // Wrap unknown errors\n throw new CencoriError(\n error instanceof Error ? error.message : 'Unknown error occurred'\n );\n }\n }\n}\n\n// Export types\nexport type { CencoriConfig, ChatRequest, ChatResponse, ChatMessage, RequestOptions } from './types';\nexport type { AINamespace } from './ai';\nexport type { ComputeNamespace } from './compute';\nexport type { WorkflowNamespace } from './workflow';\nexport type { StorageNamespace } from './storage';\n\n","/**\n * Cencori Chat Language Model\n * \n * Implements the Vercel AI SDK's LanguageModelV3 interface (AI SDK v6 compatible)\n */\n\nimport type {\n LanguageModelV3,\n LanguageModelV3CallOptions,\n LanguageModelV3GenerateResult,\n LanguageModelV3StreamResult,\n LanguageModelV3StreamPart,\n LanguageModelV3Content,\n LanguageModelV3Usage,\n LanguageModelV3FinishReason,\n SharedV3Warning,\n} from '@ai-sdk/provider';\n\nexport interface CencoriChatModelSettings {\n apiKey: string;\n baseUrl: string;\n headers?: Record<string, string>;\n userId?: string;\n}\n\ninterface CencoriMessage {\n role: 'system' | 'user' | 'assistant' | 'tool';\n content: string;\n toolCallId?: string;\n}\n\n/**\n * Tool definition in Cencori format (OpenAI-compatible)\n */\ninterface CencoriTool {\n type: 'function';\n function: {\n name: string;\n description: string;\n parameters: Record<string, any>;\n };\n}\n\n/**\n * Tool call from the model\n */\ninterface CencoriToolCall {\n id: string;\n type: 'function';\n function: {\n name: string;\n arguments: string;\n };\n}\n\ninterface CencoriResponse {\n content: string;\n model: string;\n provider: string;\n usage: {\n prompt_tokens: number;\n completion_tokens: number;\n total_tokens: number;\n };\n cost_usd: number;\n finish_reason?: string;\n tool_calls?: CencoriToolCall[];\n}\n\ninterface CencoriStreamChunk {\n delta: string;\n finish_reason?: string;\n tool_calls?: CencoriToolCall[];\n}\n\nexport class CencoriChatLanguageModel implements LanguageModelV3 {\n readonly specificationVersion = 'v3' as const;\n readonly provider = 'cencori';\n\n readonly modelId: string;\n readonly supportedUrls: Record<string, RegExp[]> = {};\n private readonly settings: CencoriChatModelSettings;\n\n constructor(modelId: string, settings: CencoriChatModelSettings) {\n this.modelId = modelId;\n this.settings = settings;\n }\n\n private getHeaders(): Record<string, string> {\n return {\n 'Content-Type': 'application/json',\n 'CENCORI_API_KEY': this.settings.apiKey,\n ...this.settings.headers,\n };\n }\n\n private convertMessages(options: LanguageModelV3CallOptions): CencoriMessage[] {\n const messages: CencoriMessage[] = [];\n\n // In V3, options.prompt is directly an array of LanguageModelV3Message\n const promptMessages = options.prompt;\n\n if (!promptMessages || !Array.isArray(promptMessages)) {\n return messages;\n }\n\n for (const msg of promptMessages) {\n let content = '';\n\n if (msg.role === 'system') {\n // System messages have content as string directly\n content = msg.content as string;\n } else if (msg.role === 'user' || msg.role === 'assistant') {\n // User and assistant messages have content as array of parts\n const msgContent = msg.content;\n if (Array.isArray(msgContent)) {\n content = msgContent\n .filter((part: { type: string }) => part.type === 'text')\n .map((part: { type: string; text?: string }) => part.text || '')\n .join('');\n } else if (typeof msgContent === 'string') {\n content = msgContent;\n }\n }\n\n if (content && (msg.role === 'system' || msg.role === 'user' || msg.role === 'assistant')) {\n messages.push({\n role: msg.role as 'system' | 'user' | 'assistant',\n content,\n });\n }\n }\n\n return messages;\n }\n\n private mapFinishReason(reason?: string): LanguageModelV3FinishReason {\n let unified: 'stop' | 'length' | 'content-filter' | 'tool-calls' | 'error' | 'other';\n\n switch (reason) {\n case 'stop':\n case 'end_turn':\n unified = 'stop';\n break;\n case 'length':\n case 'max_tokens':\n unified = 'length';\n break;\n case 'content_filter':\n unified = 'content-filter';\n break;\n case 'tool_calls':\n case 'tool-calls':\n unified = 'tool-calls';\n break;\n case 'error':\n unified = 'error';\n break;\n default:\n unified = 'stop';\n }\n\n return { unified, raw: reason };\n }\n\n private buildUsage(inputTokens: number, outputTokens: number): LanguageModelV3Usage {\n return {\n inputTokens: {\n total: inputTokens,\n noCache: inputTokens,\n cacheRead: undefined,\n cacheWrite: undefined,\n },\n outputTokens: {\n total: outputTokens,\n text: outputTokens,\n reasoning: undefined,\n },\n };\n }\n\n /**\n * Convert Vercel AI SDK tools to Cencori format\n */\n private convertTools(options: LanguageModelV3CallOptions): CencoriTool[] | undefined {\n if (!options.tools || options.tools.length === 0) {\n return undefined;\n }\n\n return options.tools\n .filter(t => t.type === 'function')\n .map(t => ({\n type: 'function' as const,\n function: {\n name: t.name,\n description: t.description || '',\n parameters: t.inputSchema as Record<string, any>,\n },\n }));\n }\n\n /**\n * Convert Vercel AI SDK tool choice to Cencori format\n */\n private convertToolChoice(options: LanguageModelV3CallOptions): string | { type: 'function'; function: { name: string } } | undefined {\n const tc = options.toolChoice;\n if (!tc) return undefined;\n\n switch (tc.type) {\n case 'auto':\n return 'auto';\n case 'none':\n return 'none';\n case 'required':\n return 'required';\n case 'tool':\n return { type: 'function', function: { name: tc.toolName } };\n default:\n return undefined;\n }\n }\n\n async doGenerate(options: LanguageModelV3CallOptions): Promise<LanguageModelV3GenerateResult> {\n const messages = this.convertMessages(options);\n const tools = this.convertTools(options);\n const toolChoice = this.convertToolChoice(options);\n\n const response = await fetch(`${this.settings.baseUrl}/api/ai/chat`, {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify({\n messages,\n model: this.modelId,\n temperature: options.temperature,\n maxTokens: options.maxOutputTokens,\n stream: false,\n userId: this.settings.userId,\n tools,\n toolChoice,\n }),\n signal: options.abortSignal,\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({ error: 'Unknown error' })) as { error?: string };\n throw new Error(`Cencori API error: ${error.error || response.statusText}`);\n }\n\n const data = await response.json() as CencoriResponse;\n\n // Build content array\n const content: LanguageModelV3Content[] = [];\n\n // Add text content if present\n if (data.content) {\n content.push({\n type: 'text',\n text: data.content,\n providerMetadata: undefined,\n });\n }\n\n // Add tool calls if present\n if (data.tool_calls && data.tool_calls.length > 0) {\n for (const tc of data.tool_calls) {\n content.push({\n type: 'tool-call',\n toolCallId: tc.id,\n toolName: tc.function.name,\n input: tc.function.arguments,\n providerMetadata: undefined,\n });\n }\n }\n\n const warnings: SharedV3Warning[] = [];\n\n return {\n content,\n finishReason: this.mapFinishReason(data.finish_reason),\n usage: this.buildUsage(data.usage.prompt_tokens, data.usage.completion_tokens),\n warnings,\n };\n }\n\n async doStream(options: LanguageModelV3CallOptions): Promise<LanguageModelV3StreamResult> {\n const messages = this.convertMessages(options);\n const tools = this.convertTools(options);\n const toolChoice = this.convertToolChoice(options);\n const self = this;\n\n const response = await fetch(`${this.settings.baseUrl}/api/ai/chat`, {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify({\n messages,\n model: this.modelId,\n temperature: options.temperature,\n maxTokens: options.maxOutputTokens,\n stream: true,\n userId: this.settings.userId,\n tools,\n toolChoice,\n }),\n signal: options.abortSignal,\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({ error: 'Unknown error' })) as { error?: string };\n throw new Error(`Cencori API error: ${error.error || response.statusText}`);\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 inputTokens = 0;\n let outputTokens = 0;\n const textPartId = 'text-0';\n let started = false;\n\n const stream = new ReadableStream<LanguageModelV3StreamPart>({\n async pull(controller) {\n try {\n const { done, value } = await reader.read();\n\n if (done) {\n // End text block and finish\n if (started) {\n controller.enqueue({\n type: 'text-end',\n id: textPartId,\n });\n }\n controller.enqueue({\n type: 'finish',\n finishReason: self.mapFinishReason('stop'),\n usage: self.buildUsage(inputTokens, outputTokens),\n });\n controller.close();\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 if (started) {\n controller.enqueue({\n type: 'text-end',\n id: textPartId,\n });\n }\n controller.enqueue({\n type: 'finish',\n finishReason: self.mapFinishReason('stop'),\n usage: self.buildUsage(inputTokens, outputTokens),\n });\n controller.close();\n return;\n }\n\n try {\n const chunk = JSON.parse(data) as CencoriStreamChunk;\n\n // Handle text delta\n if (chunk.delta) {\n // Start text if not started\n if (!started) {\n started = true;\n controller.enqueue({\n type: 'text-start',\n id: textPartId,\n });\n }\n\n outputTokens += Math.ceil(chunk.delta.length / 4); // Rough estimate\n controller.enqueue({\n type: 'text-delta',\n id: textPartId,\n delta: chunk.delta,\n });\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 // Emit complete tool-call event\n controller.enqueue({\n type: 'tool-call',\n toolCallId: tc.id,\n toolName: tc.function.name,\n input: tc.function.arguments,\n providerMetadata: undefined,\n });\n }\n }\n\n if (chunk.finish_reason) {\n if (started) {\n controller.enqueue({\n type: 'text-end',\n id: textPartId,\n });\n }\n controller.enqueue({\n type: 'finish',\n finishReason: self.mapFinishReason(chunk.finish_reason),\n usage: self.buildUsage(inputTokens, outputTokens),\n });\n controller.close();\n return;\n }\n } catch {\n // Skip malformed JSON\n }\n }\n } catch (error) {\n controller.error(error);\n }\n },\n cancel() {\n reader.cancel();\n },\n });\n\n return {\n stream,\n };\n }\n}\n","/**\n * Cencori AI Provider for Vercel AI SDK\n * \n * Use Cencori with streamText(), generateText(), and useChat()\n */\n\nimport { CencoriChatLanguageModel } from './cencori-chat-model';\nimport type { CencoriProviderSettings, CencoriChatSettings } from './types';\n\nexport interface CencoriProvider {\n /**\n * Create a Cencori chat model for use with Vercel AI SDK\n * \n * @param modelId - The model ID (e.g., 'gemini-2.5-flash', 'gpt-4o', 'claude-3-opus')\n * @param settings - Optional model-specific settings\n * @returns A LanguageModelV1 compatible model\n * \n * @example\n * import { cencori } from 'cencori';\n * import { streamText } from 'ai';\n * \n * const result = await streamText({\n * model: cencori('gemini-2.5-flash'),\n * messages: [{ role: 'user', content: 'Hello!' }]\n * });\n */\n (modelId: string, settings?: CencoriChatSettings): CencoriChatLanguageModel;\n\n /**\n * Create a chat model (alias for the provider function)\n */\n chat: (modelId: string, settings?: CencoriChatSettings) => CencoriChatLanguageModel;\n}\n\n/**\n * Create a Cencori provider instance\n * \n * @param options - Provider configuration options\n * @returns A Cencori provider\n * \n * @example\n * import { createCencori } from 'cencori';\n * \n * const cencori = createCencori({\n * apiKey: process.env.CENCORI_API_KEY\n * });\n * \n * const result = await streamText({\n * model: cencori('gemini-2.5-flash'),\n * messages: [{ role: 'user', content: 'Hello!' }]\n * });\n */\nexport function createCencori(options: CencoriProviderSettings = {}): CencoriProvider {\n const baseUrl = options.baseUrl ?? 'https://cencori.com';\n const apiKey = options.apiKey ?? process.env.CENCORI_API_KEY;\n\n if (!apiKey) {\n throw new Error('Cencori API key is required. Pass it via options.apiKey or set CENCORI_API_KEY environment variable.');\n }\n\n const createModel = (modelId: string, settings: CencoriChatSettings = {}) => {\n return new CencoriChatLanguageModel(modelId, {\n apiKey,\n baseUrl,\n headers: options.headers,\n ...settings,\n });\n };\n\n const provider = function (modelId: string, settings?: CencoriChatSettings) {\n return createModel(modelId, settings);\n } as CencoriProvider;\n\n provider.chat = createModel;\n\n return provider;\n}\n\n/**\n * Default Cencori provider instance\n * Uses CENCORI_API_KEY environment variable (lazy initialization)\n * \n * @example\n * import { cencori } from 'cencori';\n * import { streamText } from 'ai';\n * \n * const result = await streamText({\n * model: cencori('gemini-2.5-flash'),\n * messages: [{ role: 'user', content: 'Hello!' }]\n * });\n */\nexport const cencori: CencoriProvider = function (modelId: string, settings?: CencoriChatSettings) {\n const apiKey = process.env.CENCORI_API_KEY;\n if (!apiKey) {\n throw new Error('CENCORI_API_KEY environment variable is required. Set it or use createCencori({ apiKey: \"...\" }) instead.');\n }\n return new CencoriChatLanguageModel(modelId, {\n apiKey,\n baseUrl: 'https://cencori.com',\n ...settings,\n });\n} as CencoriProvider;\n\ncencori.chat = cencori;\n"],"mappings":"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","names":[]}
|