cencori 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,140 +1,192 @@
1
- # Cencori
2
-
3
- Official SDK for the Cencori.
4
-
5
- ## Installation
6
-
7
- ```bash
8
- npm install cencori
9
- # or
10
- yarn add cencori
11
- ```
12
-
13
- ## Quick Start
14
-
15
- ```typescript
16
- import { CencoriClient } from 'cencori';
17
-
18
- const cencori = new CencoriClient({
19
- apiKey: process.env.CENCORI_API_KEY!
20
- });
21
-
22
- const response = await cencori.ai.chat({
23
- messages: [
24
- { role: 'user', content: 'Hello, AI!' }
25
- ]
26
- });
27
-
28
- console.log(response.content);
29
- ```
30
-
31
- ## Authentication
32
-
33
- Get your API key from the [Cencori Dashboard](https://cencori.com/dashboard):
34
-
35
- 1. Create a project
36
- 2. Navigate to API Keys
37
- 3. Generate a new key
38
- 4. Copy and store it securely
39
-
40
- ## API Reference
41
-
42
- ### CencoriClient
43
-
44
- Initialize the SDK client.
45
-
46
- ```typescript
47
- const cencori = new CencoriClient({
48
- apiKey: 'your_api_key_here',
49
- baseUrl: 'https://cencori.com' // Optional, defaults to production
50
- });
51
- ```
52
-
53
- ### AI Module
54
-
55
- #### `ai.chat(params)`
56
-
57
- Send a chat message to the AI.
58
-
59
- **Parameters:**
60
- - `messages`: Array of message objects with `role` ('user' | 'assistant') and `content`
61
- - `model`: Optional AI model (defaults to 'gemini-1.5-flash')
62
- - `temperature`: Optional temperature (0-1)
63
- - `maxOutputTokens`: Optional max tokens for response
64
-
65
- **Example:**
66
-
67
- ```typescript
68
- const response = await cencori.ai.chat({
69
- messages: [
70
- { role: 'user', content: 'Explain quantum computing' }
71
- ],
72
- temperature: 0.7
73
- });
74
-
75
- console.log(response.content);
76
- console.log(response.usage); // Token usage stats
77
- ```
78
-
79
- ## Error Handling
80
-
81
- The SDK includes custom error classes for common scenarios:
82
-
83
- ```typescript
84
- import {
85
- CencoriClient,
86
- AuthenticationError,
87
- RateLimitError,
88
- SafetyError
89
- } from 'cencori';
90
-
91
- try {
92
- const response = await cencori.ai.chat({ messages: [...] });
93
- } catch (error) {
94
- if (error instanceof AuthenticationError) {
95
- console.error('Invalid API key');
96
- } else if (error instanceof RateLimitError) {
97
- console.error('Too many requests, please slow down');
98
- } else if (error instanceof SafetyError) {
99
- console.error('Content blocked:', error.reasons);
100
- }
101
- }
102
- ```
103
-
104
- ## TypeScript Support
105
-
106
- The SDK is written in TypeScript and includes full type definitions.
107
-
108
- ```typescript
109
- import type { ChatParams, ChatResponse, Message } from 'cencori';
110
- ```
111
-
112
- ## Features
113
-
114
- - Full TypeScript support with type definitions
115
- - Built-in authentication
116
- - Automatic retry logic with exponential backoff
117
- - Custom error classes
118
- - Content safety filtering
119
- - Rate limiting protection
120
-
121
- ## Local Development
122
-
123
- For local development or testing:
124
-
125
- ```typescript
126
- const cencori = new CencoriClient({
127
- apiKey: 'cen_test_...',
128
- baseUrl: 'http://localhost:3000'
129
- });
130
- ```
131
-
132
- ## Support
133
-
134
- - **Documentation**: [docs.cencori.com](https://docs.cencori.com)
135
- - **Dashboard**: [cencori.com/dashboard](https://cencori.com/dashboard)
136
- - **GitHub**: [github.com/bolaabanjo/cencori](https://github.com/bolaabanjo/cencori)
137
-
138
- ## License
139
-
140
- MIT © FohnAI
1
+ # Cencori
2
+
3
+ Official SDK for Cencori - The Security Layer for AI Development.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install cencori
9
+ # or
10
+ yarn add cencori
11
+ # or
12
+ pnpm add cencori
13
+ ```
14
+
15
+ ## Quick Start
16
+
17
+ ```typescript
18
+ import { Cencori } from 'cencori';
19
+
20
+ const cencori = new Cencori({
21
+ apiKey: process.env.CENCORI_API_KEY!
22
+ });
23
+
24
+ const response = await cencori.ai.chat({
25
+ messages: [
26
+ { role: 'user', content: 'Hello, AI!' }
27
+ ]
28
+ });
29
+
30
+ console.log(response.content);
31
+ ```
32
+
33
+ ## Authentication
34
+
35
+ Get your API key from the [Cencori Dashboard](https://cencori.com/dashboard):
36
+
37
+ 1. Create a project
38
+ 2. Navigate to Settings API tab
39
+ 3. Generate a new key:
40
+ - **Secret key (`csk_`)** - For server-side use only
41
+ - **Publishable key (`cpk_`)** - Safe for browser use (requires domain whitelisting)
42
+ 4. Copy and store it securely
43
+
44
+ ## API Reference
45
+
46
+ ### Cencori
47
+
48
+ Initialize the SDK client.
49
+
50
+ ```typescript
51
+ import { Cencori } from 'cencori';
52
+
53
+ const cencori = new Cencori({
54
+ apiKey: 'csk_xxx', // Secret key for server-side
55
+ baseUrl: 'https://cencori.com' // Optional, defaults to production
56
+ });
57
+ ```
58
+
59
+ ### AI Module
60
+
61
+ #### `ai.chat(params)`
62
+
63
+ Send a chat message to the AI (non-streaming).
64
+
65
+ **Parameters:**
66
+ - `messages`: Array of message objects with `role` ('system' | 'user' | 'assistant') and `content`
67
+ - `model`: Optional AI model (defaults to 'gemini-2.5-flash')
68
+ - `temperature`: Optional temperature (0-1)
69
+ - `maxTokens`: Optional max tokens for response
70
+ - `userId`: Optional user ID for rate limiting
71
+
72
+ **Example:**
73
+
74
+ ```typescript
75
+ const response = await cencori.ai.chat({
76
+ messages: [
77
+ { role: 'user', content: 'Explain quantum computing' }
78
+ ],
79
+ model: 'gpt-4o',
80
+ temperature: 0.7
81
+ });
82
+
83
+ console.log(response.content);
84
+ console.log(response.usage); // Token usage stats
85
+ console.log(response.cost_usd); // Cost in USD
86
+ ```
87
+
88
+ #### `ai.chatStream(params)`
89
+
90
+ Stream a chat response token-by-token.
91
+
92
+ **Example:**
93
+
94
+ ```typescript
95
+ const stream = cencori.ai.chatStream({
96
+ messages: [
97
+ { role: 'user', content: 'Tell me a story' }
98
+ ],
99
+ model: 'gpt-4o'
100
+ });
101
+
102
+ for await (const chunk of stream) {
103
+ process.stdout.write(chunk.delta);
104
+ }
105
+ ```
106
+
107
+ ## Error Handling
108
+
109
+ The SDK includes custom error classes for common scenarios:
110
+
111
+ ```typescript
112
+ import {
113
+ Cencori,
114
+ AuthenticationError,
115
+ RateLimitError,
116
+ SafetyError
117
+ } from 'cencori';
118
+
119
+ try {
120
+ const response = await cencori.ai.chat({ messages: [...] });
121
+ } catch (error) {
122
+ if (error instanceof AuthenticationError) {
123
+ console.error('Invalid API key');
124
+ } else if (error instanceof RateLimitError) {
125
+ console.error('Too many requests, please slow down');
126
+ } else if (error instanceof SafetyError) {
127
+ console.error('Content blocked:', error.reasons);
128
+ }
129
+ }
130
+ ```
131
+
132
+ ## TypeScript Support
133
+
134
+ The SDK is written in TypeScript and includes full type definitions.
135
+
136
+ ```typescript
137
+ import type { ChatParams, ChatResponse, Message, StreamChunk } from 'cencori';
138
+ ```
139
+
140
+ ## Features
141
+
142
+ - ✅ Full TypeScript support with type definitions
143
+ - ✅ Built-in authentication
144
+ - ✅ Automatic retry logic with exponential backoff
145
+ - ✅ Custom error classes
146
+ - ✅ Content safety filtering (PII, prompt injection, harmful content)
147
+ - ✅ Rate limiting protection
148
+ - ✅ Streaming support with `chatStream()`
149
+
150
+ ## Supported Models
151
+
152
+ | Provider | Models |
153
+ |----------|--------|
154
+ | OpenAI | `gpt-4o`, `gpt-4-turbo`, `gpt-3.5-turbo` |
155
+ | Anthropic | `claude-3-opus`, `claude-3-sonnet`, `claude-3-haiku` |
156
+ | Google | `gemini-2.5-flash`, `gemini-2.0-flash` |
157
+
158
+ ## Local Development
159
+
160
+ For local development or testing:
161
+
162
+ ```typescript
163
+ const cencori = new Cencori({
164
+ apiKey: 'csk_test_xxx', // Test secret key
165
+ baseUrl: 'http://localhost:3000'
166
+ });
167
+ ```
168
+
169
+ ## Browser Usage (Publishable Keys)
170
+
171
+ For browser/client-side usage, use publishable keys:
172
+
173
+ ```typescript
174
+ // Safe to use in browser - only works from allowed domains
175
+ const cencori = new Cencori({
176
+ apiKey: 'cpk_xxx' // Publishable key
177
+ });
178
+
179
+ const response = await cencori.ai.chat({
180
+ messages: [{ role: 'user', content: 'Hello!' }]
181
+ });
182
+ ```
183
+
184
+ ## Support
185
+
186
+ - **Documentation**: [cencori.com/docs](https://cencori.com/docs)
187
+ - **Dashboard**: [cencori.com/dashboard](https://cencori.com/dashboard)
188
+ - **GitHub**: [github.com/cencori](https://github.com/cencori)
189
+
190
+ ## License
191
+
192
+ MIT © FohnAI
package/dist/index.d.mts CHANGED
@@ -76,4 +76,4 @@ declare class SafetyError extends CencoriError {
76
76
  constructor(message?: string, reasons?: string[] | undefined);
77
77
  }
78
78
 
79
- export { AIModule, AuthenticationError, CencoriClient, type CencoriConfig, CencoriError, type ChatParams, type ChatResponse, type Message, RateLimitError, type RequestOptions, SafetyError, type StreamChunk };
79
+ export { AIModule, AuthenticationError, CencoriClient as Cencori, CencoriClient, type CencoriConfig, CencoriError, type ChatParams, type ChatResponse, type Message, RateLimitError, type RequestOptions, SafetyError, type StreamChunk, CencoriClient as default };
package/dist/index.d.ts CHANGED
@@ -76,4 +76,4 @@ declare class SafetyError extends CencoriError {
76
76
  constructor(message?: string, reasons?: string[] | undefined);
77
77
  }
78
78
 
79
- export { AIModule, AuthenticationError, CencoriClient, type CencoriConfig, CencoriError, type ChatParams, type ChatResponse, type Message, RateLimitError, type RequestOptions, SafetyError, type StreamChunk };
79
+ export { AIModule, AuthenticationError, CencoriClient as Cencori, CencoriClient, type CencoriConfig, CencoriError, type ChatParams, type ChatResponse, type Message, RateLimitError, type RequestOptions, SafetyError, type StreamChunk, CencoriClient as default };
package/dist/index.js CHANGED
@@ -22,10 +22,12 @@ var index_exports = {};
22
22
  __export(index_exports, {
23
23
  AIModule: () => AIModule,
24
24
  AuthenticationError: () => AuthenticationError,
25
+ Cencori: () => CencoriClient,
25
26
  CencoriClient: () => CencoriClient,
26
27
  CencoriError: () => CencoriError,
27
28
  RateLimitError: () => RateLimitError,
28
- SafetyError: () => SafetyError
29
+ SafetyError: () => SafetyError,
30
+ default: () => CencoriClient
29
31
  });
30
32
  module.exports = __toCommonJS(index_exports);
31
33
 
@@ -220,6 +222,7 @@ var CencoriClient = class {
220
222
  0 && (module.exports = {
221
223
  AIModule,
222
224
  AuthenticationError,
225
+ Cencori,
223
226
  CencoriClient,
224
227
  CencoriError,
225
228
  RateLimitError,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/modules/ai.ts","../src/utils.ts","../src/errors.ts","../src/client.ts"],"sourcesContent":["export { CencoriClient } from './client';\r\nexport * from './types';\r\nexport * from './errors';\r\n","import type { CencoriClient, ErrorResponse } from '../client';\r\n\r\nexport interface Message {\r\n role: 'system' | 'user' | 'assistant';\r\n content: string;\r\n}\r\n\r\nexport interface ChatParams {\r\n messages: Message[];\r\n model?: string;\r\n temperature?: number;\r\n maxTokens?: number;\r\n stream?: boolean;\r\n userId?: string;\r\n}\r\n\r\nexport interface ChatResponse {\r\n content: string;\r\n model: string;\r\n provider: string;\r\n usage: {\r\n prompt_tokens: number;\r\n completion_tokens: number;\r\n total_tokens: number;\r\n };\r\n cost_usd: number;\r\n finish_reason: 'stop' | 'length' | 'content_filter' | 'error';\r\n}\r\n\r\nexport interface StreamChunk {\r\n delta: string;\r\n finish_reason?: 'stop' | 'length' | 'content_filter' | 'error';\r\n}\r\n\r\nexport class AIModule {\r\n constructor(private client: CencoriClient) { }\r\n\r\n /**\r\n * Send a chat completion request (non-streaming)\r\n */\r\n async chat(params: ChatParams): Promise<ChatResponse> {\r\n const response = await this.client.request<ChatResponse>('/api/ai/chat', {\r\n method: 'POST',\r\n body: JSON.stringify({ ...params, stream: false }),\r\n });\r\n\r\n return response;\r\n }\r\n\r\n /**\r\n * Send a chat completion request with streaming\r\n * Returns an async generator that yields chunks as they arrive\r\n */\r\n async *chatStream(params: ChatParams): AsyncGenerator<StreamChunk, void, unknown> {\r\n const url = `${this.client.getBaseUrl()}/api/ai/chat`;\r\n\r\n const headers: Record<string, string> = {\r\n 'Content-Type': 'application/json',\r\n 'CENCORI_API_KEY': this.client.getApiKey(),\r\n };\r\n\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers,\r\n body: JSON.stringify({ ...params, stream: true }),\r\n });\r\n\r\n if (!response.ok) {\r\n const error = await response.json() as ErrorResponse;\r\n throw new Error(error.error || 'Stream request failed');\r\n }\r\n\r\n if (!response.body) {\r\n throw new Error('Response body is null');\r\n }\r\n\r\n const reader = response.body.getReader();\r\n const decoder = new TextDecoder();\r\n let buffer = '';\r\n\r\n try {\r\n while (true) {\r\n const { done, value } = await reader.read();\r\n\r\n if (done) break;\r\n\r\n buffer += decoder.decode(value, { stream: true });\r\n const lines = buffer.split('\\n');\r\n\r\n // Keep the last incomplete line in the buffer\r\n buffer = lines.pop() || '';\r\n\r\n for (const line of lines) {\r\n if (line.trim() === '') continue;\r\n if (!line.startsWith('data: ')) continue;\r\n\r\n const data = line.slice(6); // Remove 'data: ' prefix\r\n\r\n if (data === '[DONE]') {\r\n return;\r\n }\r\n\r\n try {\r\n const chunk = JSON.parse(data) as StreamChunk;\r\n yield chunk;\r\n } catch (e) {\r\n console.error('Failed to parse SSE data:', e);\r\n }\r\n }\r\n }\r\n } finally {\r\n reader.releaseLock();\r\n }\r\n }\r\n}\r\n","function sleep(ms: number): Promise<void> {\r\n return new Promise(resolve => setTimeout(resolve, ms));\r\n}\r\n\r\nexport async function fetchWithRetry(\r\n url: string,\r\n options: RequestInit,\r\n maxRetries = 3\r\n): Promise<Response> {\r\n let lastError: Error | null = null;\r\n\r\n for (let attempt = 0; attempt < maxRetries; attempt++) {\r\n try {\r\n const response = await fetch(url, options);\r\n\r\n // Return immediately if request succeeded or if it's a client error (4xx)\r\n if (response.ok || (response.status >= 400 && response.status < 500)) {\r\n return response;\r\n }\r\n\r\n // Retry on 5xx errors\r\n lastError = new Error(`HTTP ${response.status}: ${response.statusText}`);\r\n\r\n // Don't retry on last attempt\r\n if (attempt === maxRetries - 1) {\r\n return response;\r\n }\r\n\r\n // Exponential backoff: 1s, 2s, 4s\r\n await sleep(Math.pow(2, attempt) * 1000);\r\n } catch (error) {\r\n lastError = error instanceof Error ? error : new Error(String(error));\r\n\r\n // Don't retry on last attempt\r\n if (attempt === maxRetries - 1) {\r\n throw lastError;\r\n }\r\n\r\n // Exponential backoff\r\n await sleep(Math.pow(2, attempt) * 1000);\r\n }\r\n }\r\n\r\n throw lastError || new Error('Max retries reached');\r\n}\r\n","export class CencoriError extends Error {\r\n constructor(\r\n message: string,\r\n public statusCode?: number,\r\n public code?: string\r\n ) {\r\n super(message);\r\n this.name = 'CencoriError';\r\n Object.setPrototypeOf(this, CencoriError.prototype);\r\n }\r\n}\r\n\r\nexport class AuthenticationError extends CencoriError {\r\n constructor(message = 'Invalid API key') {\r\n super(message, 401, 'INVALID_API_KEY');\r\n this.name = 'AuthenticationError';\r\n Object.setPrototypeOf(this, AuthenticationError.prototype);\r\n }\r\n}\r\n\r\nexport class RateLimitError extends CencoriError {\r\n constructor(message = 'Rate limit exceeded') {\r\n super(message, 429, 'RATE_LIMIT_EXCEEDED');\r\n this.name = 'RateLimitError';\r\n Object.setPrototypeOf(this, RateLimitError.prototype);\r\n }\r\n}\r\n\r\nexport class SafetyError extends CencoriError {\r\n constructor(message = 'Content safety violation', public reasons?: string[]) {\r\n super(message, 400, 'SAFETY_VIOLATION');\r\n this.name = 'SafetyError';\r\n Object.setPrototypeOf(this, SafetyError.prototype);\r\n }\r\n}\r\n","import type { CencoriConfig, RequestOptions } from './types/common';\r\nimport { AIModule } from './modules/ai';\r\nimport { fetchWithRetry } from './utils';\r\nimport {\r\n CencoriError,\r\n AuthenticationError,\r\n RateLimitError,\r\n SafetyError\r\n} from './errors';\r\n\r\nexport interface ErrorResponse {\r\n error?: string;\r\n reasons?: string[];\r\n}\r\n\r\nexport class CencoriClient {\r\n private apiKey: string;\r\n private baseUrl: string;\r\n\r\n public ai: AIModule;\r\n\r\n constructor(config: CencoriConfig) {\r\n if (!config.apiKey) {\r\n throw new Error('API key is required');\r\n }\r\n\r\n this.apiKey = config.apiKey;\r\n this.baseUrl = config.baseUrl || 'https://cencori.com';\r\n\r\n this.ai = new AIModule(this);\r\n }\r\n\r\n // Public getters for internal use by modules\r\n getBaseUrl(): string {\r\n return this.baseUrl;\r\n }\r\n\r\n getApiKey(): string {\r\n return this.apiKey;\r\n }\r\n\r\n async request<T>(endpoint: string, options: RequestOptions): Promise<T> {\r\n const url = `${this.baseUrl}${endpoint}`;\r\n\r\n const headers: Record<string, string> = {\r\n 'Content-Type': 'application/json',\r\n 'CENCORI_API_KEY': this.apiKey,\r\n ...options.headers\r\n };\r\n\r\n try {\r\n const response = await fetchWithRetry(url, {\r\n method: options.method,\r\n headers,\r\n body: options.body\r\n });\r\n\r\n const data: unknown = await response.json();\r\n\r\n // Handle API errors\r\n if (!response.ok) {\r\n const errorData = data as ErrorResponse;\r\n\r\n if (response.status === 401) {\r\n throw new AuthenticationError(errorData.error || 'Invalid API key');\r\n }\r\n if (response.status === 429) {\r\n throw new RateLimitError(errorData.error || 'Rate limit exceeded');\r\n }\r\n if (response.status === 400 && errorData.reasons) {\r\n throw new SafetyError(errorData.error, errorData.reasons);\r\n }\r\n throw new CencoriError(\r\n errorData.error || 'Request failed',\r\n response.status\r\n );\r\n }\r\n\r\n return data as T;\r\n } catch (error) {\r\n // Re-throw custom errors\r\n if (error instanceof CencoriError) {\r\n throw error;\r\n }\r\n\r\n // Wrap unknown errors\r\n throw new CencoriError(\r\n error instanceof Error ? error.message : 'Unknown error occurred'\r\n );\r\n }\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/modules/ai.ts","../src/utils.ts","../src/errors.ts","../src/client.ts"],"sourcesContent":["export { CencoriClient } from './client';\nexport { CencoriClient as Cencori } from './client'; // Alias for convenience\nexport * from './types';\nexport * from './errors';\n\n// Default export for: import Cencori from 'cencori'\nexport { CencoriClient as default } from './client';\n","import type { CencoriClient, ErrorResponse } from '../client';\n\nexport interface Message {\n role: 'system' | 'user' | 'assistant';\n content: string;\n}\n\nexport interface ChatParams {\n messages: Message[];\n model?: string;\n temperature?: number;\n maxTokens?: number;\n stream?: boolean;\n userId?: string;\n}\n\nexport interface ChatResponse {\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: 'stop' | 'length' | 'content_filter' | 'error';\n}\n\nexport interface StreamChunk {\n delta: string;\n finish_reason?: 'stop' | 'length' | 'content_filter' | 'error';\n}\n\nexport class AIModule {\n constructor(private client: CencoriClient) { }\n\n /**\n * Send a chat completion request (non-streaming)\n */\n async chat(params: ChatParams): Promise<ChatResponse> {\n const response = await this.client.request<ChatResponse>('/api/ai/chat', {\n method: 'POST',\n body: JSON.stringify({ ...params, stream: false }),\n });\n\n return response;\n }\n\n /**\n * Send a chat completion request with streaming\n * Returns an async generator that yields chunks as they arrive\n */\n async *chatStream(params: ChatParams): AsyncGenerator<StreamChunk, void, unknown> {\n const url = `${this.client.getBaseUrl()}/api/ai/chat`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'CENCORI_API_KEY': this.client.getApiKey(),\n };\n\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify({ ...params, stream: true }),\n });\n\n if (!response.ok) {\n const error = await response.json() as ErrorResponse;\n throw new Error(error.error || 'Stream request failed');\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 (e) {\n console.error('Failed to parse SSE data:', e);\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n}\n","function sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\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","export 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","import type { CencoriConfig, RequestOptions } from './types/common';\nimport { AIModule } from './modules/ai';\nimport { fetchWithRetry } from './utils';\nimport {\n CencoriError,\n AuthenticationError,\n RateLimitError,\n SafetyError\n} from './errors';\n\nexport interface ErrorResponse {\n error?: string;\n reasons?: string[];\n}\n\nexport class CencoriClient {\n private apiKey: string;\n private baseUrl: string;\n\n public ai: AIModule;\n\n constructor(config: CencoriConfig) {\n if (!config.apiKey) {\n throw new Error('API key is required');\n }\n\n this.apiKey = config.apiKey;\n this.baseUrl = config.baseUrl || 'https://cencori.com';\n\n this.ai = new AIModule(this);\n }\n\n // Public getters for internal use by modules\n getBaseUrl(): string {\n return this.baseUrl;\n }\n\n getApiKey(): string {\n return this.apiKey;\n }\n\n async request<T>(endpoint: string, options: RequestOptions): Promise<T> {\n const url = `${this.baseUrl}${endpoint}`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'CENCORI_API_KEY': this.apiKey,\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"],"mappings":"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","names":[]}
package/dist/index.mjs CHANGED
@@ -188,9 +188,11 @@ var CencoriClient = class {
188
188
  export {
189
189
  AIModule,
190
190
  AuthenticationError,
191
+ CencoriClient as Cencori,
191
192
  CencoriClient,
192
193
  CencoriError,
193
194
  RateLimitError,
194
- SafetyError
195
+ SafetyError,
196
+ CencoriClient as default
195
197
  };
196
198
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/modules/ai.ts","../src/utils.ts","../src/errors.ts","../src/client.ts"],"sourcesContent":["import type { CencoriClient, ErrorResponse } from '../client';\r\n\r\nexport interface Message {\r\n role: 'system' | 'user' | 'assistant';\r\n content: string;\r\n}\r\n\r\nexport interface ChatParams {\r\n messages: Message[];\r\n model?: string;\r\n temperature?: number;\r\n maxTokens?: number;\r\n stream?: boolean;\r\n userId?: string;\r\n}\r\n\r\nexport interface ChatResponse {\r\n content: string;\r\n model: string;\r\n provider: string;\r\n usage: {\r\n prompt_tokens: number;\r\n completion_tokens: number;\r\n total_tokens: number;\r\n };\r\n cost_usd: number;\r\n finish_reason: 'stop' | 'length' | 'content_filter' | 'error';\r\n}\r\n\r\nexport interface StreamChunk {\r\n delta: string;\r\n finish_reason?: 'stop' | 'length' | 'content_filter' | 'error';\r\n}\r\n\r\nexport class AIModule {\r\n constructor(private client: CencoriClient) { }\r\n\r\n /**\r\n * Send a chat completion request (non-streaming)\r\n */\r\n async chat(params: ChatParams): Promise<ChatResponse> {\r\n const response = await this.client.request<ChatResponse>('/api/ai/chat', {\r\n method: 'POST',\r\n body: JSON.stringify({ ...params, stream: false }),\r\n });\r\n\r\n return response;\r\n }\r\n\r\n /**\r\n * Send a chat completion request with streaming\r\n * Returns an async generator that yields chunks as they arrive\r\n */\r\n async *chatStream(params: ChatParams): AsyncGenerator<StreamChunk, void, unknown> {\r\n const url = `${this.client.getBaseUrl()}/api/ai/chat`;\r\n\r\n const headers: Record<string, string> = {\r\n 'Content-Type': 'application/json',\r\n 'CENCORI_API_KEY': this.client.getApiKey(),\r\n };\r\n\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers,\r\n body: JSON.stringify({ ...params, stream: true }),\r\n });\r\n\r\n if (!response.ok) {\r\n const error = await response.json() as ErrorResponse;\r\n throw new Error(error.error || 'Stream request failed');\r\n }\r\n\r\n if (!response.body) {\r\n throw new Error('Response body is null');\r\n }\r\n\r\n const reader = response.body.getReader();\r\n const decoder = new TextDecoder();\r\n let buffer = '';\r\n\r\n try {\r\n while (true) {\r\n const { done, value } = await reader.read();\r\n\r\n if (done) break;\r\n\r\n buffer += decoder.decode(value, { stream: true });\r\n const lines = buffer.split('\\n');\r\n\r\n // Keep the last incomplete line in the buffer\r\n buffer = lines.pop() || '';\r\n\r\n for (const line of lines) {\r\n if (line.trim() === '') continue;\r\n if (!line.startsWith('data: ')) continue;\r\n\r\n const data = line.slice(6); // Remove 'data: ' prefix\r\n\r\n if (data === '[DONE]') {\r\n return;\r\n }\r\n\r\n try {\r\n const chunk = JSON.parse(data) as StreamChunk;\r\n yield chunk;\r\n } catch (e) {\r\n console.error('Failed to parse SSE data:', e);\r\n }\r\n }\r\n }\r\n } finally {\r\n reader.releaseLock();\r\n }\r\n }\r\n}\r\n","function sleep(ms: number): Promise<void> {\r\n return new Promise(resolve => setTimeout(resolve, ms));\r\n}\r\n\r\nexport async function fetchWithRetry(\r\n url: string,\r\n options: RequestInit,\r\n maxRetries = 3\r\n): Promise<Response> {\r\n let lastError: Error | null = null;\r\n\r\n for (let attempt = 0; attempt < maxRetries; attempt++) {\r\n try {\r\n const response = await fetch(url, options);\r\n\r\n // Return immediately if request succeeded or if it's a client error (4xx)\r\n if (response.ok || (response.status >= 400 && response.status < 500)) {\r\n return response;\r\n }\r\n\r\n // Retry on 5xx errors\r\n lastError = new Error(`HTTP ${response.status}: ${response.statusText}`);\r\n\r\n // Don't retry on last attempt\r\n if (attempt === maxRetries - 1) {\r\n return response;\r\n }\r\n\r\n // Exponential backoff: 1s, 2s, 4s\r\n await sleep(Math.pow(2, attempt) * 1000);\r\n } catch (error) {\r\n lastError = error instanceof Error ? error : new Error(String(error));\r\n\r\n // Don't retry on last attempt\r\n if (attempt === maxRetries - 1) {\r\n throw lastError;\r\n }\r\n\r\n // Exponential backoff\r\n await sleep(Math.pow(2, attempt) * 1000);\r\n }\r\n }\r\n\r\n throw lastError || new Error('Max retries reached');\r\n}\r\n","export class CencoriError extends Error {\r\n constructor(\r\n message: string,\r\n public statusCode?: number,\r\n public code?: string\r\n ) {\r\n super(message);\r\n this.name = 'CencoriError';\r\n Object.setPrototypeOf(this, CencoriError.prototype);\r\n }\r\n}\r\n\r\nexport class AuthenticationError extends CencoriError {\r\n constructor(message = 'Invalid API key') {\r\n super(message, 401, 'INVALID_API_KEY');\r\n this.name = 'AuthenticationError';\r\n Object.setPrototypeOf(this, AuthenticationError.prototype);\r\n }\r\n}\r\n\r\nexport class RateLimitError extends CencoriError {\r\n constructor(message = 'Rate limit exceeded') {\r\n super(message, 429, 'RATE_LIMIT_EXCEEDED');\r\n this.name = 'RateLimitError';\r\n Object.setPrototypeOf(this, RateLimitError.prototype);\r\n }\r\n}\r\n\r\nexport class SafetyError extends CencoriError {\r\n constructor(message = 'Content safety violation', public reasons?: string[]) {\r\n super(message, 400, 'SAFETY_VIOLATION');\r\n this.name = 'SafetyError';\r\n Object.setPrototypeOf(this, SafetyError.prototype);\r\n }\r\n}\r\n","import type { CencoriConfig, RequestOptions } from './types/common';\r\nimport { AIModule } from './modules/ai';\r\nimport { fetchWithRetry } from './utils';\r\nimport {\r\n CencoriError,\r\n AuthenticationError,\r\n RateLimitError,\r\n SafetyError\r\n} from './errors';\r\n\r\nexport interface ErrorResponse {\r\n error?: string;\r\n reasons?: string[];\r\n}\r\n\r\nexport class CencoriClient {\r\n private apiKey: string;\r\n private baseUrl: string;\r\n\r\n public ai: AIModule;\r\n\r\n constructor(config: CencoriConfig) {\r\n if (!config.apiKey) {\r\n throw new Error('API key is required');\r\n }\r\n\r\n this.apiKey = config.apiKey;\r\n this.baseUrl = config.baseUrl || 'https://cencori.com';\r\n\r\n this.ai = new AIModule(this);\r\n }\r\n\r\n // Public getters for internal use by modules\r\n getBaseUrl(): string {\r\n return this.baseUrl;\r\n }\r\n\r\n getApiKey(): string {\r\n return this.apiKey;\r\n }\r\n\r\n async request<T>(endpoint: string, options: RequestOptions): Promise<T> {\r\n const url = `${this.baseUrl}${endpoint}`;\r\n\r\n const headers: Record<string, string> = {\r\n 'Content-Type': 'application/json',\r\n 'CENCORI_API_KEY': this.apiKey,\r\n ...options.headers\r\n };\r\n\r\n try {\r\n const response = await fetchWithRetry(url, {\r\n method: options.method,\r\n headers,\r\n body: options.body\r\n });\r\n\r\n const data: unknown = await response.json();\r\n\r\n // Handle API errors\r\n if (!response.ok) {\r\n const errorData = data as ErrorResponse;\r\n\r\n if (response.status === 401) {\r\n throw new AuthenticationError(errorData.error || 'Invalid API key');\r\n }\r\n if (response.status === 429) {\r\n throw new RateLimitError(errorData.error || 'Rate limit exceeded');\r\n }\r\n if (response.status === 400 && errorData.reasons) {\r\n throw new SafetyError(errorData.error, errorData.reasons);\r\n }\r\n throw new CencoriError(\r\n errorData.error || 'Request failed',\r\n response.status\r\n );\r\n }\r\n\r\n return data as T;\r\n } catch (error) {\r\n // Re-throw custom errors\r\n if (error instanceof CencoriError) {\r\n throw error;\r\n }\r\n\r\n // Wrap unknown errors\r\n throw new CencoriError(\r\n error instanceof Error ? error.message : 'Unknown error occurred'\r\n );\r\n }\r\n }\r\n}\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/modules/ai.ts","../src/utils.ts","../src/errors.ts","../src/client.ts"],"sourcesContent":["import type { CencoriClient, ErrorResponse } from '../client';\n\nexport interface Message {\n role: 'system' | 'user' | 'assistant';\n content: string;\n}\n\nexport interface ChatParams {\n messages: Message[];\n model?: string;\n temperature?: number;\n maxTokens?: number;\n stream?: boolean;\n userId?: string;\n}\n\nexport interface ChatResponse {\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: 'stop' | 'length' | 'content_filter' | 'error';\n}\n\nexport interface StreamChunk {\n delta: string;\n finish_reason?: 'stop' | 'length' | 'content_filter' | 'error';\n}\n\nexport class AIModule {\n constructor(private client: CencoriClient) { }\n\n /**\n * Send a chat completion request (non-streaming)\n */\n async chat(params: ChatParams): Promise<ChatResponse> {\n const response = await this.client.request<ChatResponse>('/api/ai/chat', {\n method: 'POST',\n body: JSON.stringify({ ...params, stream: false }),\n });\n\n return response;\n }\n\n /**\n * Send a chat completion request with streaming\n * Returns an async generator that yields chunks as they arrive\n */\n async *chatStream(params: ChatParams): AsyncGenerator<StreamChunk, void, unknown> {\n const url = `${this.client.getBaseUrl()}/api/ai/chat`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'CENCORI_API_KEY': this.client.getApiKey(),\n };\n\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify({ ...params, stream: true }),\n });\n\n if (!response.ok) {\n const error = await response.json() as ErrorResponse;\n throw new Error(error.error || 'Stream request failed');\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 (e) {\n console.error('Failed to parse SSE data:', e);\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n}\n","function sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\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","export 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","import type { CencoriConfig, RequestOptions } from './types/common';\nimport { AIModule } from './modules/ai';\nimport { fetchWithRetry } from './utils';\nimport {\n CencoriError,\n AuthenticationError,\n RateLimitError,\n SafetyError\n} from './errors';\n\nexport interface ErrorResponse {\n error?: string;\n reasons?: string[];\n}\n\nexport class CencoriClient {\n private apiKey: string;\n private baseUrl: string;\n\n public ai: AIModule;\n\n constructor(config: CencoriConfig) {\n if (!config.apiKey) {\n throw new Error('API key is required');\n }\n\n this.apiKey = config.apiKey;\n this.baseUrl = config.baseUrl || 'https://cencori.com';\n\n this.ai = new AIModule(this);\n }\n\n // Public getters for internal use by modules\n getBaseUrl(): string {\n return this.baseUrl;\n }\n\n getApiKey(): string {\n return this.apiKey;\n }\n\n async request<T>(endpoint: string, options: RequestOptions): Promise<T> {\n const url = `${this.baseUrl}${endpoint}`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'CENCORI_API_KEY': this.apiKey,\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"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,42 +1,42 @@
1
- {
2
- "name": "cencori",
3
- "version": "0.3.0",
4
- "description": "Official TypeScript SDK for Cencori - The Security Layer for AI Development",
5
- "main": "dist/index.js",
6
- "module": "dist/index.mjs",
7
- "types": "dist/index.d.ts",
8
- "files": [
9
- "dist",
10
- "README.md"
11
- ],
12
- "keywords": [
13
- "ai",
14
- "gateway",
15
- "cencori",
16
- "sdk",
17
- "typescript",
18
- "openai",
19
- "anthropic",
20
- "streaming",
21
- "security"
22
- ],
23
- "author": "FohnAI",
24
- "license": "MIT",
25
- "repository": {
26
- "type": "git",
27
- "url": "https://github.com/bolaabanjo/cencori"
28
- },
29
- "homepage": "https://cencori.com",
30
- "bugs": {
31
- "url": "https://github.com/bolaabanjo/cencori/issues"
32
- },
33
- "scripts": {
34
- "build": "tsup",
35
- "dev": "tsup --watch",
36
- "prepublishOnly": "npm run build"
37
- },
38
- "devDependencies": {
39
- "tsup": "^8.0.0",
40
- "typescript": "^5.3.0"
41
- }
42
- }
1
+ {
2
+ "name": "cencori",
3
+ "version": "0.3.2",
4
+ "description": "Official TypeScript SDK for Cencori - The Security Layer for AI Development",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist",
10
+ "README.md"
11
+ ],
12
+ "keywords": [
13
+ "ai",
14
+ "gateway",
15
+ "cencori",
16
+ "sdk",
17
+ "typescript",
18
+ "openai",
19
+ "anthropic",
20
+ "streaming",
21
+ "security"
22
+ ],
23
+ "author": "FohnAI",
24
+ "license": "MIT",
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "https://github.com/cencori/cencori"
28
+ },
29
+ "homepage": "https://cencori.com",
30
+ "bugs": {
31
+ "url": "https://github.com/cencori/cencori/issues"
32
+ },
33
+ "scripts": {
34
+ "build": "tsup",
35
+ "dev": "tsup --watch",
36
+ "prepublishOnly": "npm run build"
37
+ },
38
+ "devDependencies": {
39
+ "tsup": "^8.0.0",
40
+ "typescript": "^5.3.0"
41
+ }
42
+ }