cencori 1.3.0 → 1.3.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.
@@ -31,6 +31,15 @@ interface VisionRequest {
31
31
  temperature?: number;
32
32
  responseFormat?: 'text' | 'json';
33
33
  }
34
+ interface VisionStreamChunk {
35
+ delta?: string;
36
+ done?: boolean;
37
+ model?: string;
38
+ provider?: VisionProvider;
39
+ usage?: VisionUsage;
40
+ cost?: VisionCost;
41
+ error?: string;
42
+ }
34
43
  interface VisionUsage {
35
44
  promptTokens: number;
36
45
  completionTokens: number;
@@ -93,7 +102,18 @@ declare class VisionNamespace {
93
102
  ocr(request: VisionRequest): Promise<VisionOcrResult>;
94
103
  /** Return structured tags, objects, and category classification. */
95
104
  classify(request: VisionRequest): Promise<VisionClassifyResult>;
105
+ /**
106
+ * Stream a vision analysis. Yields `{ delta }` chunks as text arrives, then
107
+ * a final `{ done: true, model, provider, usage, cost }` chunk with totals.
108
+ *
109
+ * @example
110
+ * for await (const chunk of cencori.vision.analyzeStream({ image: { url } })) {
111
+ * if (chunk.delta) process.stdout.write(chunk.delta);
112
+ * if (chunk.done) console.log(chunk.cost);
113
+ * }
114
+ */
115
+ analyzeStream(request: VisionRequest): AsyncGenerator<VisionStreamChunk, void, unknown>;
96
116
  private post;
97
117
  }
98
118
 
99
- export { type VisionClassification, type VisionClassifyResult, type VisionCost, type VisionDescribeResult, type VisionImage, VisionNamespace, type VisionOcrResult, type VisionProvider, type VisionRequest, type VisionResult, type VisionTask, type VisionUsage };
119
+ export { type VisionClassification, type VisionClassifyResult, type VisionCost, type VisionDescribeResult, type VisionImage, VisionNamespace, type VisionOcrResult, type VisionProvider, type VisionRequest, type VisionResult, type VisionStreamChunk, type VisionTask, type VisionUsage };
@@ -31,6 +31,15 @@ interface VisionRequest {
31
31
  temperature?: number;
32
32
  responseFormat?: 'text' | 'json';
33
33
  }
34
+ interface VisionStreamChunk {
35
+ delta?: string;
36
+ done?: boolean;
37
+ model?: string;
38
+ provider?: VisionProvider;
39
+ usage?: VisionUsage;
40
+ cost?: VisionCost;
41
+ error?: string;
42
+ }
34
43
  interface VisionUsage {
35
44
  promptTokens: number;
36
45
  completionTokens: number;
@@ -93,7 +102,18 @@ declare class VisionNamespace {
93
102
  ocr(request: VisionRequest): Promise<VisionOcrResult>;
94
103
  /** Return structured tags, objects, and category classification. */
95
104
  classify(request: VisionRequest): Promise<VisionClassifyResult>;
105
+ /**
106
+ * Stream a vision analysis. Yields `{ delta }` chunks as text arrives, then
107
+ * a final `{ done: true, model, provider, usage, cost }` chunk with totals.
108
+ *
109
+ * @example
110
+ * for await (const chunk of cencori.vision.analyzeStream({ image: { url } })) {
111
+ * if (chunk.delta) process.stdout.write(chunk.delta);
112
+ * if (chunk.done) console.log(chunk.cost);
113
+ * }
114
+ */
115
+ analyzeStream(request: VisionRequest): AsyncGenerator<VisionStreamChunk, void, unknown>;
96
116
  private post;
97
117
  }
98
118
 
99
- export { type VisionClassification, type VisionClassifyResult, type VisionCost, type VisionDescribeResult, type VisionImage, VisionNamespace, type VisionOcrResult, type VisionProvider, type VisionRequest, type VisionResult, type VisionTask, type VisionUsage };
119
+ export { type VisionClassification, type VisionClassifyResult, type VisionCost, type VisionDescribeResult, type VisionImage, VisionNamespace, type VisionOcrResult, type VisionProvider, type VisionRequest, type VisionResult, type VisionStreamChunk, type VisionTask, type VisionUsage };
@@ -64,6 +64,57 @@ var VisionNamespace = class {
64
64
  async classify(request) {
65
65
  return this.post("/api/ai/vision/classify", request);
66
66
  }
67
+ /**
68
+ * Stream a vision analysis. Yields `{ delta }` chunks as text arrives, then
69
+ * a final `{ done: true, model, provider, usage, cost }` chunk with totals.
70
+ *
71
+ * @example
72
+ * for await (const chunk of cencori.vision.analyzeStream({ image: { url } })) {
73
+ * if (chunk.delta) process.stdout.write(chunk.delta);
74
+ * if (chunk.done) console.log(chunk.cost);
75
+ * }
76
+ */
77
+ async *analyzeStream(request) {
78
+ const body = { ...toBody(request), stream: true };
79
+ const response = await fetch(`${this.config.baseUrl}/api/ai/vision`, {
80
+ method: "POST",
81
+ headers: {
82
+ "CENCORI_API_KEY": this.config.apiKey,
83
+ "Content-Type": "application/json",
84
+ ...this.config.headers
85
+ },
86
+ body: JSON.stringify(body)
87
+ });
88
+ if (!response.ok) {
89
+ const data = await response.json().catch(() => ({}));
90
+ const message = data && typeof data === "object" && "message" in data && typeof data.message === "string" ? data.message : `Vision stream request failed with status ${response.status}`;
91
+ throw new Error(message);
92
+ }
93
+ if (!response.body) throw new Error("Response body is null");
94
+ const reader = response.body.getReader();
95
+ const decoder = new TextDecoder();
96
+ let buffer = "";
97
+ try {
98
+ while (true) {
99
+ const { done, value } = await reader.read();
100
+ if (done) break;
101
+ buffer += decoder.decode(value, { stream: true });
102
+ const lines = buffer.split("\n");
103
+ buffer = lines.pop() ?? "";
104
+ for (const line of lines) {
105
+ if (!line.startsWith("data: ")) continue;
106
+ const data = line.slice(6);
107
+ if (data === "[DONE]") return;
108
+ try {
109
+ yield JSON.parse(data);
110
+ } catch {
111
+ }
112
+ }
113
+ }
114
+ } finally {
115
+ reader.releaseLock();
116
+ }
117
+ }
67
118
  async post(path, request) {
68
119
  const response = await fetch(`${this.config.baseUrl}${path}`, {
69
120
  method: "POST",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/vision/index.ts"],"sourcesContent":["/**\n * Vision API — analyze, describe, OCR, and classify images.\n *\n * @example\n * const result = await cencori.vision.analyze({\n * image: { url: 'https://example.com/photo.jpg' },\n * prompt: 'What breed of dog is this?',\n * });\n *\n * @example\n * const { text } = await cencori.vision.ocr({ image: { base64, mimeType: 'image/png' } });\n */\n\nimport type { CencoriConfig } from '../types';\n\nexport type VisionProvider = 'openai' | 'anthropic' | 'google';\n\nexport type VisionTask = 'analyze' | 'describe' | 'ocr' | 'classify';\n\nexport interface VisionImage {\n /** https:// URL or data: URL. Exactly one of `url` or `base64` must be set. */\n url?: string;\n /** Raw base64 (no data: prefix). Requires `mimeType`. */\n base64?: string;\n /** Image mime type. Required when using `base64`. */\n mimeType?: string;\n}\n\nexport interface VisionRequest {\n image: VisionImage;\n prompt?: string;\n model?: string;\n maxTokens?: number;\n temperature?: number;\n responseFormat?: 'text' | 'json';\n}\n\nexport interface VisionUsage {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n}\n\nexport interface VisionCost {\n providerCostUsd: number;\n cencoriChargeUsd: number;\n markupPercentage: number;\n}\n\nexport interface VisionResult {\n analysis: string;\n model: string;\n provider: VisionProvider;\n usage: VisionUsage;\n cost: VisionCost;\n}\n\nexport interface VisionDescribeResult {\n description: string;\n model: string;\n provider: VisionProvider;\n usage: VisionUsage;\n cost: VisionCost;\n}\n\nexport interface VisionOcrResult {\n text: string;\n model: string;\n provider: VisionProvider;\n usage: VisionUsage;\n cost: VisionCost;\n}\n\nexport interface VisionClassification {\n primary_category?: string;\n tags?: string[];\n objects?: string[];\n safe_for_work?: boolean;\n confidence?: number;\n summary?: string;\n [key: string]: unknown;\n}\n\nexport interface VisionClassifyResult {\n classification: VisionClassification | string;\n raw: string;\n model: string;\n provider: VisionProvider;\n usage: VisionUsage;\n cost: VisionCost;\n}\n\ninterface JsonBody {\n image_url?: string;\n image_base64?: string;\n mime_type?: string;\n prompt?: string;\n model?: string;\n max_tokens?: number;\n temperature?: number;\n response_format?: 'text' | 'json';\n}\n\nfunction toBody(request: VisionRequest): JsonBody {\n const body: JsonBody = {\n prompt: request.prompt,\n model: request.model,\n max_tokens: request.maxTokens,\n temperature: request.temperature,\n response_format: request.responseFormat,\n };\n if (request.image.url) {\n body.image_url = request.image.url;\n } else if (request.image.base64) {\n body.image_base64 = request.image.base64;\n body.mime_type = request.image.mimeType;\n } else {\n throw new Error('vision request requires image.url or image.base64');\n }\n return body;\n}\n\nexport class VisionNamespace {\n private config: Required<CencoriConfig>;\n\n constructor(config: Required<CencoriConfig>) {\n this.config = config;\n }\n\n /**\n * General image analysis — provide your own prompt.\n * Default prompt: \"Describe this image in detail.\"\n */\n async analyze(request: VisionRequest): Promise<VisionResult> {\n return this.post<VisionResult>('/api/ai/vision', request);\n }\n\n /** Describe the image in rich detail. */\n async describe(request: VisionRequest): Promise<VisionDescribeResult> {\n return this.post<VisionDescribeResult>('/api/ai/vision/describe', request);\n }\n\n /** Extract all visible text from the image. */\n async ocr(request: VisionRequest): Promise<VisionOcrResult> {\n return this.post<VisionOcrResult>('/api/ai/vision/ocr', request);\n }\n\n /** Return structured tags, objects, and category classification. */\n async classify(request: VisionRequest): Promise<VisionClassifyResult> {\n return this.post<VisionClassifyResult>('/api/ai/vision/classify', request);\n }\n\n private async post<T>(path: string, request: VisionRequest): Promise<T> {\n const response = await fetch(`${this.config.baseUrl}${path}`, {\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(toBody(request)),\n });\n const data = await response.json();\n if (!response.ok) {\n const message =\n (data && typeof data === 'object' && 'message' in data && typeof data.message === 'string')\n ? data.message\n : `Vision request failed with status ${response.status}`;\n const code =\n (data && typeof data === 'object' && 'error' in data && typeof data.error === 'string')\n ? data.error\n : 'request_failed';\n const err = new Error(message) as Error & { code?: string; details?: unknown };\n err.code = code;\n err.details = data;\n throw err;\n }\n return data as T;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAuGA,SAAS,OAAO,SAAkC;AAC9C,QAAM,OAAiB;AAAA,IACnB,QAAQ,QAAQ;AAAA,IAChB,OAAO,QAAQ;AAAA,IACf,YAAY,QAAQ;AAAA,IACpB,aAAa,QAAQ;AAAA,IACrB,iBAAiB,QAAQ;AAAA,EAC7B;AACA,MAAI,QAAQ,MAAM,KAAK;AACnB,SAAK,YAAY,QAAQ,MAAM;AAAA,EACnC,WAAW,QAAQ,MAAM,QAAQ;AAC7B,SAAK,eAAe,QAAQ,MAAM;AAClC,SAAK,YAAY,QAAQ,MAAM;AAAA,EACnC,OAAO;AACH,UAAM,IAAI,MAAM,mDAAmD;AAAA,EACvE;AACA,SAAO;AACX;AAEO,IAAM,kBAAN,MAAsB;AAAA,EAGzB,YAAY,QAAiC;AACzC,SAAK,SAAS;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,QAAQ,SAA+C;AACzD,WAAO,KAAK,KAAmB,kBAAkB,OAAO;AAAA,EAC5D;AAAA;AAAA,EAGA,MAAM,SAAS,SAAuD;AAClE,WAAO,KAAK,KAA2B,2BAA2B,OAAO;AAAA,EAC7E;AAAA;AAAA,EAGA,MAAM,IAAI,SAAkD;AACxD,WAAO,KAAK,KAAsB,sBAAsB,OAAO;AAAA,EACnE;AAAA;AAAA,EAGA,MAAM,SAAS,SAAuD;AAClE,WAAO,KAAK,KAA2B,2BAA2B,OAAO;AAAA,EAC7E;AAAA,EAEA,MAAc,KAAQ,MAAc,SAAoC;AACpE,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,OAAO,GAAG,IAAI,IAAI;AAAA,MAC1D,QAAQ;AAAA,MACR,SAAS;AAAA,QACL,mBAAmB,KAAK,OAAO;AAAA,QAC/B,gBAAgB;AAAA,QAChB,GAAG,KAAK,OAAO;AAAA,MACnB;AAAA,MACA,MAAM,KAAK,UAAU,OAAO,OAAO,CAAC;AAAA,IACxC,CAAC;AACD,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,QAAI,CAAC,SAAS,IAAI;AACd,YAAM,UACD,QAAQ,OAAO,SAAS,YAAY,aAAa,QAAQ,OAAO,KAAK,YAAY,WAC5E,KAAK,UACL,qCAAqC,SAAS,MAAM;AAC9D,YAAM,OACD,QAAQ,OAAO,SAAS,YAAY,WAAW,QAAQ,OAAO,KAAK,UAAU,WACxE,KAAK,QACL;AACV,YAAM,MAAM,IAAI,MAAM,OAAO;AAC7B,UAAI,OAAO;AACX,UAAI,UAAU;AACd,YAAM;AAAA,IACV;AACA,WAAO;AAAA,EACX;AACJ;","names":[]}
1
+ {"version":3,"sources":["../../src/vision/index.ts"],"sourcesContent":["/**\n * Vision API — analyze, describe, OCR, and classify images.\n *\n * @example\n * const result = await cencori.vision.analyze({\n * image: { url: 'https://example.com/photo.jpg' },\n * prompt: 'What breed of dog is this?',\n * });\n *\n * @example\n * const { text } = await cencori.vision.ocr({ image: { base64, mimeType: 'image/png' } });\n */\n\nimport type { CencoriConfig } from '../types';\n\nexport type VisionProvider = 'openai' | 'anthropic' | 'google';\n\nexport type VisionTask = 'analyze' | 'describe' | 'ocr' | 'classify';\n\nexport interface VisionImage {\n /** https:// URL or data: URL. Exactly one of `url` or `base64` must be set. */\n url?: string;\n /** Raw base64 (no data: prefix). Requires `mimeType`. */\n base64?: string;\n /** Image mime type. Required when using `base64`. */\n mimeType?: string;\n}\n\nexport interface VisionRequest {\n image: VisionImage;\n prompt?: string;\n model?: string;\n maxTokens?: number;\n temperature?: number;\n responseFormat?: 'text' | 'json';\n}\n\nexport interface VisionStreamChunk {\n delta?: string;\n done?: boolean;\n model?: string;\n provider?: VisionProvider;\n usage?: VisionUsage;\n cost?: VisionCost;\n error?: string;\n}\n\nexport interface VisionUsage {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n}\n\nexport interface VisionCost {\n providerCostUsd: number;\n cencoriChargeUsd: number;\n markupPercentage: number;\n}\n\nexport interface VisionResult {\n analysis: string;\n model: string;\n provider: VisionProvider;\n usage: VisionUsage;\n cost: VisionCost;\n}\n\nexport interface VisionDescribeResult {\n description: string;\n model: string;\n provider: VisionProvider;\n usage: VisionUsage;\n cost: VisionCost;\n}\n\nexport interface VisionOcrResult {\n text: string;\n model: string;\n provider: VisionProvider;\n usage: VisionUsage;\n cost: VisionCost;\n}\n\nexport interface VisionClassification {\n primary_category?: string;\n tags?: string[];\n objects?: string[];\n safe_for_work?: boolean;\n confidence?: number;\n summary?: string;\n [key: string]: unknown;\n}\n\nexport interface VisionClassifyResult {\n classification: VisionClassification | string;\n raw: string;\n model: string;\n provider: VisionProvider;\n usage: VisionUsage;\n cost: VisionCost;\n}\n\ninterface JsonBody {\n image_url?: string;\n image_base64?: string;\n mime_type?: string;\n prompt?: string;\n model?: string;\n max_tokens?: number;\n temperature?: number;\n response_format?: 'text' | 'json';\n}\n\nfunction toBody(request: VisionRequest): JsonBody {\n const body: JsonBody = {\n prompt: request.prompt,\n model: request.model,\n max_tokens: request.maxTokens,\n temperature: request.temperature,\n response_format: request.responseFormat,\n };\n if (request.image.url) {\n body.image_url = request.image.url;\n } else if (request.image.base64) {\n body.image_base64 = request.image.base64;\n body.mime_type = request.image.mimeType;\n } else {\n throw new Error('vision request requires image.url or image.base64');\n }\n return body;\n}\n\nexport class VisionNamespace {\n private config: Required<CencoriConfig>;\n\n constructor(config: Required<CencoriConfig>) {\n this.config = config;\n }\n\n /**\n * General image analysis — provide your own prompt.\n * Default prompt: \"Describe this image in detail.\"\n */\n async analyze(request: VisionRequest): Promise<VisionResult> {\n return this.post<VisionResult>('/api/ai/vision', request);\n }\n\n /** Describe the image in rich detail. */\n async describe(request: VisionRequest): Promise<VisionDescribeResult> {\n return this.post<VisionDescribeResult>('/api/ai/vision/describe', request);\n }\n\n /** Extract all visible text from the image. */\n async ocr(request: VisionRequest): Promise<VisionOcrResult> {\n return this.post<VisionOcrResult>('/api/ai/vision/ocr', request);\n }\n\n /** Return structured tags, objects, and category classification. */\n async classify(request: VisionRequest): Promise<VisionClassifyResult> {\n return this.post<VisionClassifyResult>('/api/ai/vision/classify', request);\n }\n\n /**\n * Stream a vision analysis. Yields `{ delta }` chunks as text arrives, then\n * a final `{ done: true, model, provider, usage, cost }` chunk with totals.\n *\n * @example\n * for await (const chunk of cencori.vision.analyzeStream({ image: { url } })) {\n * if (chunk.delta) process.stdout.write(chunk.delta);\n * if (chunk.done) console.log(chunk.cost);\n * }\n */\n async *analyzeStream(request: VisionRequest): AsyncGenerator<VisionStreamChunk, void, unknown> {\n const body = { ...toBody(request), stream: true };\n const response = await fetch(`${this.config.baseUrl}/api/ai/vision`, {\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(body),\n });\n if (!response.ok) {\n const data = await response.json().catch(() => ({}));\n const message =\n (data && typeof data === 'object' && 'message' in data && typeof data.message === 'string')\n ? data.message\n : `Vision stream request failed with status ${response.status}`;\n throw new Error(message);\n }\n if (!response.body) throw new Error('Response body is null');\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n for (const line of lines) {\n if (!line.startsWith('data: ')) continue;\n const data = line.slice(6);\n if (data === '[DONE]') return;\n try {\n yield JSON.parse(data) as VisionStreamChunk;\n } catch {\n // skip malformed frame\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n private async post<T>(path: string, request: VisionRequest): Promise<T> {\n const response = await fetch(`${this.config.baseUrl}${path}`, {\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(toBody(request)),\n });\n const data = await response.json();\n if (!response.ok) {\n const message =\n (data && typeof data === 'object' && 'message' in data && typeof data.message === 'string')\n ? data.message\n : `Vision request failed with status ${response.status}`;\n const code =\n (data && typeof data === 'object' && 'error' in data && typeof data.error === 'string')\n ? data.error\n : 'request_failed';\n const err = new Error(message) as Error & { code?: string; details?: unknown };\n err.code = code;\n err.details = data;\n throw err;\n }\n return data as T;\n }\n}\n"],"mappings":"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","names":[]}
@@ -40,6 +40,57 @@ var VisionNamespace = class {
40
40
  async classify(request) {
41
41
  return this.post("/api/ai/vision/classify", request);
42
42
  }
43
+ /**
44
+ * Stream a vision analysis. Yields `{ delta }` chunks as text arrives, then
45
+ * a final `{ done: true, model, provider, usage, cost }` chunk with totals.
46
+ *
47
+ * @example
48
+ * for await (const chunk of cencori.vision.analyzeStream({ image: { url } })) {
49
+ * if (chunk.delta) process.stdout.write(chunk.delta);
50
+ * if (chunk.done) console.log(chunk.cost);
51
+ * }
52
+ */
53
+ async *analyzeStream(request) {
54
+ const body = { ...toBody(request), stream: true };
55
+ const response = await fetch(`${this.config.baseUrl}/api/ai/vision`, {
56
+ method: "POST",
57
+ headers: {
58
+ "CENCORI_API_KEY": this.config.apiKey,
59
+ "Content-Type": "application/json",
60
+ ...this.config.headers
61
+ },
62
+ body: JSON.stringify(body)
63
+ });
64
+ if (!response.ok) {
65
+ const data = await response.json().catch(() => ({}));
66
+ const message = data && typeof data === "object" && "message" in data && typeof data.message === "string" ? data.message : `Vision stream request failed with status ${response.status}`;
67
+ throw new Error(message);
68
+ }
69
+ if (!response.body) throw new Error("Response body is null");
70
+ const reader = response.body.getReader();
71
+ const decoder = new TextDecoder();
72
+ let buffer = "";
73
+ try {
74
+ while (true) {
75
+ const { done, value } = await reader.read();
76
+ if (done) break;
77
+ buffer += decoder.decode(value, { stream: true });
78
+ const lines = buffer.split("\n");
79
+ buffer = lines.pop() ?? "";
80
+ for (const line of lines) {
81
+ if (!line.startsWith("data: ")) continue;
82
+ const data = line.slice(6);
83
+ if (data === "[DONE]") return;
84
+ try {
85
+ yield JSON.parse(data);
86
+ } catch {
87
+ }
88
+ }
89
+ }
90
+ } finally {
91
+ reader.releaseLock();
92
+ }
93
+ }
43
94
  async post(path, request) {
44
95
  const response = await fetch(`${this.config.baseUrl}${path}`, {
45
96
  method: "POST",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/vision/index.ts"],"sourcesContent":["/**\n * Vision API — analyze, describe, OCR, and classify images.\n *\n * @example\n * const result = await cencori.vision.analyze({\n * image: { url: 'https://example.com/photo.jpg' },\n * prompt: 'What breed of dog is this?',\n * });\n *\n * @example\n * const { text } = await cencori.vision.ocr({ image: { base64, mimeType: 'image/png' } });\n */\n\nimport type { CencoriConfig } from '../types';\n\nexport type VisionProvider = 'openai' | 'anthropic' | 'google';\n\nexport type VisionTask = 'analyze' | 'describe' | 'ocr' | 'classify';\n\nexport interface VisionImage {\n /** https:// URL or data: URL. Exactly one of `url` or `base64` must be set. */\n url?: string;\n /** Raw base64 (no data: prefix). Requires `mimeType`. */\n base64?: string;\n /** Image mime type. Required when using `base64`. */\n mimeType?: string;\n}\n\nexport interface VisionRequest {\n image: VisionImage;\n prompt?: string;\n model?: string;\n maxTokens?: number;\n temperature?: number;\n responseFormat?: 'text' | 'json';\n}\n\nexport interface VisionUsage {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n}\n\nexport interface VisionCost {\n providerCostUsd: number;\n cencoriChargeUsd: number;\n markupPercentage: number;\n}\n\nexport interface VisionResult {\n analysis: string;\n model: string;\n provider: VisionProvider;\n usage: VisionUsage;\n cost: VisionCost;\n}\n\nexport interface VisionDescribeResult {\n description: string;\n model: string;\n provider: VisionProvider;\n usage: VisionUsage;\n cost: VisionCost;\n}\n\nexport interface VisionOcrResult {\n text: string;\n model: string;\n provider: VisionProvider;\n usage: VisionUsage;\n cost: VisionCost;\n}\n\nexport interface VisionClassification {\n primary_category?: string;\n tags?: string[];\n objects?: string[];\n safe_for_work?: boolean;\n confidence?: number;\n summary?: string;\n [key: string]: unknown;\n}\n\nexport interface VisionClassifyResult {\n classification: VisionClassification | string;\n raw: string;\n model: string;\n provider: VisionProvider;\n usage: VisionUsage;\n cost: VisionCost;\n}\n\ninterface JsonBody {\n image_url?: string;\n image_base64?: string;\n mime_type?: string;\n prompt?: string;\n model?: string;\n max_tokens?: number;\n temperature?: number;\n response_format?: 'text' | 'json';\n}\n\nfunction toBody(request: VisionRequest): JsonBody {\n const body: JsonBody = {\n prompt: request.prompt,\n model: request.model,\n max_tokens: request.maxTokens,\n temperature: request.temperature,\n response_format: request.responseFormat,\n };\n if (request.image.url) {\n body.image_url = request.image.url;\n } else if (request.image.base64) {\n body.image_base64 = request.image.base64;\n body.mime_type = request.image.mimeType;\n } else {\n throw new Error('vision request requires image.url or image.base64');\n }\n return body;\n}\n\nexport class VisionNamespace {\n private config: Required<CencoriConfig>;\n\n constructor(config: Required<CencoriConfig>) {\n this.config = config;\n }\n\n /**\n * General image analysis — provide your own prompt.\n * Default prompt: \"Describe this image in detail.\"\n */\n async analyze(request: VisionRequest): Promise<VisionResult> {\n return this.post<VisionResult>('/api/ai/vision', request);\n }\n\n /** Describe the image in rich detail. */\n async describe(request: VisionRequest): Promise<VisionDescribeResult> {\n return this.post<VisionDescribeResult>('/api/ai/vision/describe', request);\n }\n\n /** Extract all visible text from the image. */\n async ocr(request: VisionRequest): Promise<VisionOcrResult> {\n return this.post<VisionOcrResult>('/api/ai/vision/ocr', request);\n }\n\n /** Return structured tags, objects, and category classification. */\n async classify(request: VisionRequest): Promise<VisionClassifyResult> {\n return this.post<VisionClassifyResult>('/api/ai/vision/classify', request);\n }\n\n private async post<T>(path: string, request: VisionRequest): Promise<T> {\n const response = await fetch(`${this.config.baseUrl}${path}`, {\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(toBody(request)),\n });\n const data = await response.json();\n if (!response.ok) {\n const message =\n (data && typeof data === 'object' && 'message' in data && typeof data.message === 'string')\n ? data.message\n : `Vision request failed with status ${response.status}`;\n const code =\n (data && typeof data === 'object' && 'error' in data && typeof data.error === 'string')\n ? data.error\n : 'request_failed';\n const err = new Error(message) as Error & { code?: string; details?: unknown };\n err.code = code;\n err.details = data;\n throw err;\n }\n return data as T;\n }\n}\n"],"mappings":";AAuGA,SAAS,OAAO,SAAkC;AAC9C,QAAM,OAAiB;AAAA,IACnB,QAAQ,QAAQ;AAAA,IAChB,OAAO,QAAQ;AAAA,IACf,YAAY,QAAQ;AAAA,IACpB,aAAa,QAAQ;AAAA,IACrB,iBAAiB,QAAQ;AAAA,EAC7B;AACA,MAAI,QAAQ,MAAM,KAAK;AACnB,SAAK,YAAY,QAAQ,MAAM;AAAA,EACnC,WAAW,QAAQ,MAAM,QAAQ;AAC7B,SAAK,eAAe,QAAQ,MAAM;AAClC,SAAK,YAAY,QAAQ,MAAM;AAAA,EACnC,OAAO;AACH,UAAM,IAAI,MAAM,mDAAmD;AAAA,EACvE;AACA,SAAO;AACX;AAEO,IAAM,kBAAN,MAAsB;AAAA,EAGzB,YAAY,QAAiC;AACzC,SAAK,SAAS;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,QAAQ,SAA+C;AACzD,WAAO,KAAK,KAAmB,kBAAkB,OAAO;AAAA,EAC5D;AAAA;AAAA,EAGA,MAAM,SAAS,SAAuD;AAClE,WAAO,KAAK,KAA2B,2BAA2B,OAAO;AAAA,EAC7E;AAAA;AAAA,EAGA,MAAM,IAAI,SAAkD;AACxD,WAAO,KAAK,KAAsB,sBAAsB,OAAO;AAAA,EACnE;AAAA;AAAA,EAGA,MAAM,SAAS,SAAuD;AAClE,WAAO,KAAK,KAA2B,2BAA2B,OAAO;AAAA,EAC7E;AAAA,EAEA,MAAc,KAAQ,MAAc,SAAoC;AACpE,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,OAAO,GAAG,IAAI,IAAI;AAAA,MAC1D,QAAQ;AAAA,MACR,SAAS;AAAA,QACL,mBAAmB,KAAK,OAAO;AAAA,QAC/B,gBAAgB;AAAA,QAChB,GAAG,KAAK,OAAO;AAAA,MACnB;AAAA,MACA,MAAM,KAAK,UAAU,OAAO,OAAO,CAAC;AAAA,IACxC,CAAC;AACD,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,QAAI,CAAC,SAAS,IAAI;AACd,YAAM,UACD,QAAQ,OAAO,SAAS,YAAY,aAAa,QAAQ,OAAO,KAAK,YAAY,WAC5E,KAAK,UACL,qCAAqC,SAAS,MAAM;AAC9D,YAAM,OACD,QAAQ,OAAO,SAAS,YAAY,WAAW,QAAQ,OAAO,KAAK,UAAU,WACxE,KAAK,QACL;AACV,YAAM,MAAM,IAAI,MAAM,OAAO;AAC7B,UAAI,OAAO;AACX,UAAI,UAAU;AACd,YAAM;AAAA,IACV;AACA,WAAO;AAAA,EACX;AACJ;","names":[]}
1
+ {"version":3,"sources":["../../src/vision/index.ts"],"sourcesContent":["/**\n * Vision API — analyze, describe, OCR, and classify images.\n *\n * @example\n * const result = await cencori.vision.analyze({\n * image: { url: 'https://example.com/photo.jpg' },\n * prompt: 'What breed of dog is this?',\n * });\n *\n * @example\n * const { text } = await cencori.vision.ocr({ image: { base64, mimeType: 'image/png' } });\n */\n\nimport type { CencoriConfig } from '../types';\n\nexport type VisionProvider = 'openai' | 'anthropic' | 'google';\n\nexport type VisionTask = 'analyze' | 'describe' | 'ocr' | 'classify';\n\nexport interface VisionImage {\n /** https:// URL or data: URL. Exactly one of `url` or `base64` must be set. */\n url?: string;\n /** Raw base64 (no data: prefix). Requires `mimeType`. */\n base64?: string;\n /** Image mime type. Required when using `base64`. */\n mimeType?: string;\n}\n\nexport interface VisionRequest {\n image: VisionImage;\n prompt?: string;\n model?: string;\n maxTokens?: number;\n temperature?: number;\n responseFormat?: 'text' | 'json';\n}\n\nexport interface VisionStreamChunk {\n delta?: string;\n done?: boolean;\n model?: string;\n provider?: VisionProvider;\n usage?: VisionUsage;\n cost?: VisionCost;\n error?: string;\n}\n\nexport interface VisionUsage {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n}\n\nexport interface VisionCost {\n providerCostUsd: number;\n cencoriChargeUsd: number;\n markupPercentage: number;\n}\n\nexport interface VisionResult {\n analysis: string;\n model: string;\n provider: VisionProvider;\n usage: VisionUsage;\n cost: VisionCost;\n}\n\nexport interface VisionDescribeResult {\n description: string;\n model: string;\n provider: VisionProvider;\n usage: VisionUsage;\n cost: VisionCost;\n}\n\nexport interface VisionOcrResult {\n text: string;\n model: string;\n provider: VisionProvider;\n usage: VisionUsage;\n cost: VisionCost;\n}\n\nexport interface VisionClassification {\n primary_category?: string;\n tags?: string[];\n objects?: string[];\n safe_for_work?: boolean;\n confidence?: number;\n summary?: string;\n [key: string]: unknown;\n}\n\nexport interface VisionClassifyResult {\n classification: VisionClassification | string;\n raw: string;\n model: string;\n provider: VisionProvider;\n usage: VisionUsage;\n cost: VisionCost;\n}\n\ninterface JsonBody {\n image_url?: string;\n image_base64?: string;\n mime_type?: string;\n prompt?: string;\n model?: string;\n max_tokens?: number;\n temperature?: number;\n response_format?: 'text' | 'json';\n}\n\nfunction toBody(request: VisionRequest): JsonBody {\n const body: JsonBody = {\n prompt: request.prompt,\n model: request.model,\n max_tokens: request.maxTokens,\n temperature: request.temperature,\n response_format: request.responseFormat,\n };\n if (request.image.url) {\n body.image_url = request.image.url;\n } else if (request.image.base64) {\n body.image_base64 = request.image.base64;\n body.mime_type = request.image.mimeType;\n } else {\n throw new Error('vision request requires image.url or image.base64');\n }\n return body;\n}\n\nexport class VisionNamespace {\n private config: Required<CencoriConfig>;\n\n constructor(config: Required<CencoriConfig>) {\n this.config = config;\n }\n\n /**\n * General image analysis — provide your own prompt.\n * Default prompt: \"Describe this image in detail.\"\n */\n async analyze(request: VisionRequest): Promise<VisionResult> {\n return this.post<VisionResult>('/api/ai/vision', request);\n }\n\n /** Describe the image in rich detail. */\n async describe(request: VisionRequest): Promise<VisionDescribeResult> {\n return this.post<VisionDescribeResult>('/api/ai/vision/describe', request);\n }\n\n /** Extract all visible text from the image. */\n async ocr(request: VisionRequest): Promise<VisionOcrResult> {\n return this.post<VisionOcrResult>('/api/ai/vision/ocr', request);\n }\n\n /** Return structured tags, objects, and category classification. */\n async classify(request: VisionRequest): Promise<VisionClassifyResult> {\n return this.post<VisionClassifyResult>('/api/ai/vision/classify', request);\n }\n\n /**\n * Stream a vision analysis. Yields `{ delta }` chunks as text arrives, then\n * a final `{ done: true, model, provider, usage, cost }` chunk with totals.\n *\n * @example\n * for await (const chunk of cencori.vision.analyzeStream({ image: { url } })) {\n * if (chunk.delta) process.stdout.write(chunk.delta);\n * if (chunk.done) console.log(chunk.cost);\n * }\n */\n async *analyzeStream(request: VisionRequest): AsyncGenerator<VisionStreamChunk, void, unknown> {\n const body = { ...toBody(request), stream: true };\n const response = await fetch(`${this.config.baseUrl}/api/ai/vision`, {\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(body),\n });\n if (!response.ok) {\n const data = await response.json().catch(() => ({}));\n const message =\n (data && typeof data === 'object' && 'message' in data && typeof data.message === 'string')\n ? data.message\n : `Vision stream request failed with status ${response.status}`;\n throw new Error(message);\n }\n if (!response.body) throw new Error('Response body is null');\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n for (const line of lines) {\n if (!line.startsWith('data: ')) continue;\n const data = line.slice(6);\n if (data === '[DONE]') return;\n try {\n yield JSON.parse(data) as VisionStreamChunk;\n } catch {\n // skip malformed frame\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n private async post<T>(path: string, request: VisionRequest): Promise<T> {\n const response = await fetch(`${this.config.baseUrl}${path}`, {\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(toBody(request)),\n });\n const data = await response.json();\n if (!response.ok) {\n const message =\n (data && typeof data === 'object' && 'message' in data && typeof data.message === 'string')\n ? data.message\n : `Vision request failed with status ${response.status}`;\n const code =\n (data && typeof data === 'object' && 'error' in data && typeof data.error === 'string')\n ? data.error\n : 'request_failed';\n const err = new Error(message) as Error & { code?: string; details?: unknown };\n err.code = code;\n err.details = data;\n throw err;\n }\n return data as T;\n }\n}\n"],"mappings":";AAiHA,SAAS,OAAO,SAAkC;AAC9C,QAAM,OAAiB;AAAA,IACnB,QAAQ,QAAQ;AAAA,IAChB,OAAO,QAAQ;AAAA,IACf,YAAY,QAAQ;AAAA,IACpB,aAAa,QAAQ;AAAA,IACrB,iBAAiB,QAAQ;AAAA,EAC7B;AACA,MAAI,QAAQ,MAAM,KAAK;AACnB,SAAK,YAAY,QAAQ,MAAM;AAAA,EACnC,WAAW,QAAQ,MAAM,QAAQ;AAC7B,SAAK,eAAe,QAAQ,MAAM;AAClC,SAAK,YAAY,QAAQ,MAAM;AAAA,EACnC,OAAO;AACH,UAAM,IAAI,MAAM,mDAAmD;AAAA,EACvE;AACA,SAAO;AACX;AAEO,IAAM,kBAAN,MAAsB;AAAA,EAGzB,YAAY,QAAiC;AACzC,SAAK,SAAS;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,QAAQ,SAA+C;AACzD,WAAO,KAAK,KAAmB,kBAAkB,OAAO;AAAA,EAC5D;AAAA;AAAA,EAGA,MAAM,SAAS,SAAuD;AAClE,WAAO,KAAK,KAA2B,2BAA2B,OAAO;AAAA,EAC7E;AAAA;AAAA,EAGA,MAAM,IAAI,SAAkD;AACxD,WAAO,KAAK,KAAsB,sBAAsB,OAAO;AAAA,EACnE;AAAA;AAAA,EAGA,MAAM,SAAS,SAAuD;AAClE,WAAO,KAAK,KAA2B,2BAA2B,OAAO;AAAA,EAC7E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,OAAO,cAAc,SAA0E;AAC3F,UAAM,OAAO,EAAE,GAAG,OAAO,OAAO,GAAG,QAAQ,KAAK;AAChD,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,OAAO,kBAAkB;AAAA,MACjE,QAAQ;AAAA,MACR,SAAS;AAAA,QACL,mBAAmB,KAAK,OAAO;AAAA,QAC/B,gBAAgB;AAAA,QAChB,GAAG,KAAK,OAAO;AAAA,MACnB;AAAA,MACA,MAAM,KAAK,UAAU,IAAI;AAAA,IAC7B,CAAC;AACD,QAAI,CAAC,SAAS,IAAI;AACd,YAAM,OAAO,MAAM,SAAS,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AACnD,YAAM,UACD,QAAQ,OAAO,SAAS,YAAY,aAAa,QAAQ,OAAO,KAAK,YAAY,WAC5E,KAAK,UACL,4CAA4C,SAAS,MAAM;AACrE,YAAM,IAAI,MAAM,OAAO;AAAA,IAC3B;AACA,QAAI,CAAC,SAAS,KAAM,OAAM,IAAI,MAAM,uBAAuB;AAE3D,UAAM,SAAS,SAAS,KAAK,UAAU;AACvC,UAAM,UAAU,IAAI,YAAY;AAChC,QAAI,SAAS;AACb,QAAI;AACA,aAAO,MAAM;AACT,cAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,YAAI,KAAM;AACV,kBAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAChD,cAAM,QAAQ,OAAO,MAAM,IAAI;AAC/B,iBAAS,MAAM,IAAI,KAAK;AACxB,mBAAW,QAAQ,OAAO;AACtB,cAAI,CAAC,KAAK,WAAW,QAAQ,EAAG;AAChC,gBAAM,OAAO,KAAK,MAAM,CAAC;AACzB,cAAI,SAAS,SAAU;AACvB,cAAI;AACA,kBAAM,KAAK,MAAM,IAAI;AAAA,UACzB,QAAQ;AAAA,UAER;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ,UAAE;AACE,aAAO,YAAY;AAAA,IACvB;AAAA,EACJ;AAAA,EAEA,MAAc,KAAQ,MAAc,SAAoC;AACpE,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,OAAO,GAAG,IAAI,IAAI;AAAA,MAC1D,QAAQ;AAAA,MACR,SAAS;AAAA,QACL,mBAAmB,KAAK,OAAO;AAAA,QAC/B,gBAAgB;AAAA,QAChB,GAAG,KAAK,OAAO;AAAA,MACnB;AAAA,MACA,MAAM,KAAK,UAAU,OAAO,OAAO,CAAC;AAAA,IACxC,CAAC;AACD,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,QAAI,CAAC,SAAS,IAAI;AACd,YAAM,UACD,QAAQ,OAAO,SAAS,YAAY,aAAa,QAAQ,OAAO,KAAK,YAAY,WAC5E,KAAK,UACL,qCAAqC,SAAS,MAAM;AAC9D,YAAM,OACD,QAAQ,OAAO,SAAS,YAAY,WAAW,QAAQ,OAAO,KAAK,UAAU,WACxE,KAAK,QACL;AACV,YAAM,MAAM,IAAI,MAAM,OAAO;AAC7B,UAAI,OAAO;AACX,UAAI,UAAU;AACd,YAAM;AAAA,IACV;AACA,WAAO;AAAA,EACX;AACJ;","names":[]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "cencori",
4
- "version": "1.3.0",
4
+ "version": "1.3.1",
5
5
  "description": "Cencori - The unified infrastructure layer for AI applications. One SDK for AI Gateway, Compute, Workflow, and Storage.",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.mjs",