cencori 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -0
- package/dist/documents/index.d.mts +94 -0
- package/dist/documents/index.d.ts +94 -0
- package/dist/documents/index.js +88 -0
- package/dist/documents/index.js.map +1 -0
- package/dist/documents/index.mjs +63 -0
- package/dist/documents/index.mjs.map +1 -0
- package/dist/index.d.mts +24 -2
- package/dist/index.d.ts +24 -2
- package/dist/index.js +125 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +124 -0
- package/dist/index.mjs.map +1 -1
- package/dist/vision/index.d.mts +25 -2
- package/dist/vision/index.d.ts +25 -2
- package/dist/vision/index.js +62 -0
- package/dist/vision/index.js.map +1 -1
- package/dist/vision/index.mjs +62 -0
- package/dist/vision/index.mjs.map +1 -1
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -130,6 +130,46 @@ const response = await cencori.ai.embeddings({
|
|
|
130
130
|
console.log(response.embeddings[0]); // [0.1, 0.2, ...]
|
|
131
131
|
```
|
|
132
132
|
|
|
133
|
+
### Vision (Image Understanding)
|
|
134
|
+
|
|
135
|
+
Analyze, describe, OCR, and classify images. Routes across OpenAI, Anthropic, and Google vision-capable models.
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
// General analysis with a custom prompt
|
|
139
|
+
const result = await cencori.vision.analyze({
|
|
140
|
+
image: { url: 'https://example.com/photo.jpg' },
|
|
141
|
+
prompt: 'What breed of dog is this?'
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
// OCR from a local file
|
|
145
|
+
import fs from 'node:fs';
|
|
146
|
+
const buf = fs.readFileSync('receipt.png');
|
|
147
|
+
const { text } = await cencori.vision.ocr({
|
|
148
|
+
image: { base64: buf.toString('base64'), mimeType: 'image/png' }
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
// Structured classification
|
|
152
|
+
const { classification } = await cencori.vision.classify({
|
|
153
|
+
image: { url: 'https://example.com/product.jpg' }
|
|
154
|
+
});
|
|
155
|
+
// classification: { primary_category, tags, objects, safe_for_work, ... }
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Drop-in React uploader for your own product (`cencori/react`):
|
|
159
|
+
|
|
160
|
+
```tsx
|
|
161
|
+
import { VisionUploader } from 'cencori/react';
|
|
162
|
+
|
|
163
|
+
<VisionUploader
|
|
164
|
+
endpoint="https://cencori.com/api/ai/vision"
|
|
165
|
+
apiKey={process.env.NEXT_PUBLIC_CENCORI_KEY}
|
|
166
|
+
task="describe"
|
|
167
|
+
onResult={(r) => console.log(r)}
|
|
168
|
+
/>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Full API in [docs](https://cencori.com/docs/ai/endpoints/vision).
|
|
172
|
+
|
|
133
173
|
### Image Generation
|
|
134
174
|
|
|
135
175
|
Generate images from text prompts using multiple providers:
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { C as CencoriConfig } from '../types-kh1whvNH.mjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Documents API — extract text from PDFs and images, summarize, and query.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* const { text, pageCount } = await cencori.documents.extract({
|
|
8
|
+
* document: { url: 'https://example.com/contract.pdf' },
|
|
9
|
+
* });
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* const { summary } = await cencori.documents.summarize({
|
|
13
|
+
* document: { base64, mimeType: 'application/pdf' },
|
|
14
|
+
* });
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* const { answer } = await cencori.documents.query({
|
|
18
|
+
* document: { url: 'https://example.com/report.pdf' },
|
|
19
|
+
* question: 'What is the total revenue for Q3?',
|
|
20
|
+
* });
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
type DocumentExtractMethod = 'pdf_text' | 'vision_ocr';
|
|
24
|
+
type DocumentKind = 'pdf' | 'image';
|
|
25
|
+
interface DocumentInput {
|
|
26
|
+
url?: string;
|
|
27
|
+
base64?: string;
|
|
28
|
+
mimeType?: string;
|
|
29
|
+
filename?: string;
|
|
30
|
+
}
|
|
31
|
+
interface DocumentRequest {
|
|
32
|
+
document: DocumentInput;
|
|
33
|
+
prompt?: string;
|
|
34
|
+
model?: string;
|
|
35
|
+
maxTokens?: number;
|
|
36
|
+
temperature?: number;
|
|
37
|
+
}
|
|
38
|
+
interface DocumentQueryRequest extends DocumentRequest {
|
|
39
|
+
question: string;
|
|
40
|
+
}
|
|
41
|
+
interface DocumentUsage {
|
|
42
|
+
promptTokens: number;
|
|
43
|
+
completionTokens: number;
|
|
44
|
+
totalTokens: number;
|
|
45
|
+
}
|
|
46
|
+
interface DocumentCost {
|
|
47
|
+
providerCostUsd: number;
|
|
48
|
+
cencoriChargeUsd: number;
|
|
49
|
+
markupPercentage: number;
|
|
50
|
+
}
|
|
51
|
+
interface DocumentExtractResult {
|
|
52
|
+
text: string;
|
|
53
|
+
pageCount: number;
|
|
54
|
+
kind: DocumentKind;
|
|
55
|
+
method: DocumentExtractMethod;
|
|
56
|
+
model?: string;
|
|
57
|
+
provider?: string;
|
|
58
|
+
metadata?: Record<string, unknown>;
|
|
59
|
+
usage?: DocumentUsage;
|
|
60
|
+
cost?: DocumentCost;
|
|
61
|
+
}
|
|
62
|
+
interface DocumentSummarizeResult {
|
|
63
|
+
summary: string;
|
|
64
|
+
text: string;
|
|
65
|
+
pageCount: number;
|
|
66
|
+
model: string;
|
|
67
|
+
provider: string;
|
|
68
|
+
extractMethod: DocumentExtractMethod;
|
|
69
|
+
usage: DocumentUsage;
|
|
70
|
+
cost: DocumentCost;
|
|
71
|
+
}
|
|
72
|
+
interface DocumentQueryResult {
|
|
73
|
+
answer: string;
|
|
74
|
+
question: string;
|
|
75
|
+
pageCount: number;
|
|
76
|
+
model: string;
|
|
77
|
+
provider: string;
|
|
78
|
+
extractMethod: DocumentExtractMethod;
|
|
79
|
+
usage: DocumentUsage;
|
|
80
|
+
cost: DocumentCost;
|
|
81
|
+
}
|
|
82
|
+
declare class DocumentsNamespace {
|
|
83
|
+
private config;
|
|
84
|
+
constructor(config: Required<CencoriConfig>);
|
|
85
|
+
/** Extract text from a PDF (native, no LLM) or image (via Vision OCR). */
|
|
86
|
+
extract(request: DocumentRequest): Promise<DocumentExtractResult>;
|
|
87
|
+
/** Extract then summarize the document with a chat model. */
|
|
88
|
+
summarize(request: DocumentRequest): Promise<DocumentSummarizeResult>;
|
|
89
|
+
/** Extract then answer a question about the document. */
|
|
90
|
+
query(request: DocumentQueryRequest): Promise<DocumentQueryResult>;
|
|
91
|
+
private post;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export { type DocumentCost, type DocumentExtractMethod, type DocumentExtractResult, type DocumentInput, type DocumentKind, type DocumentQueryRequest, type DocumentQueryResult, type DocumentRequest, type DocumentSummarizeResult, type DocumentUsage, DocumentsNamespace };
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { C as CencoriConfig } from '../types-kh1whvNH.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Documents API — extract text from PDFs and images, summarize, and query.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* const { text, pageCount } = await cencori.documents.extract({
|
|
8
|
+
* document: { url: 'https://example.com/contract.pdf' },
|
|
9
|
+
* });
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* const { summary } = await cencori.documents.summarize({
|
|
13
|
+
* document: { base64, mimeType: 'application/pdf' },
|
|
14
|
+
* });
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* const { answer } = await cencori.documents.query({
|
|
18
|
+
* document: { url: 'https://example.com/report.pdf' },
|
|
19
|
+
* question: 'What is the total revenue for Q3?',
|
|
20
|
+
* });
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
type DocumentExtractMethod = 'pdf_text' | 'vision_ocr';
|
|
24
|
+
type DocumentKind = 'pdf' | 'image';
|
|
25
|
+
interface DocumentInput {
|
|
26
|
+
url?: string;
|
|
27
|
+
base64?: string;
|
|
28
|
+
mimeType?: string;
|
|
29
|
+
filename?: string;
|
|
30
|
+
}
|
|
31
|
+
interface DocumentRequest {
|
|
32
|
+
document: DocumentInput;
|
|
33
|
+
prompt?: string;
|
|
34
|
+
model?: string;
|
|
35
|
+
maxTokens?: number;
|
|
36
|
+
temperature?: number;
|
|
37
|
+
}
|
|
38
|
+
interface DocumentQueryRequest extends DocumentRequest {
|
|
39
|
+
question: string;
|
|
40
|
+
}
|
|
41
|
+
interface DocumentUsage {
|
|
42
|
+
promptTokens: number;
|
|
43
|
+
completionTokens: number;
|
|
44
|
+
totalTokens: number;
|
|
45
|
+
}
|
|
46
|
+
interface DocumentCost {
|
|
47
|
+
providerCostUsd: number;
|
|
48
|
+
cencoriChargeUsd: number;
|
|
49
|
+
markupPercentage: number;
|
|
50
|
+
}
|
|
51
|
+
interface DocumentExtractResult {
|
|
52
|
+
text: string;
|
|
53
|
+
pageCount: number;
|
|
54
|
+
kind: DocumentKind;
|
|
55
|
+
method: DocumentExtractMethod;
|
|
56
|
+
model?: string;
|
|
57
|
+
provider?: string;
|
|
58
|
+
metadata?: Record<string, unknown>;
|
|
59
|
+
usage?: DocumentUsage;
|
|
60
|
+
cost?: DocumentCost;
|
|
61
|
+
}
|
|
62
|
+
interface DocumentSummarizeResult {
|
|
63
|
+
summary: string;
|
|
64
|
+
text: string;
|
|
65
|
+
pageCount: number;
|
|
66
|
+
model: string;
|
|
67
|
+
provider: string;
|
|
68
|
+
extractMethod: DocumentExtractMethod;
|
|
69
|
+
usage: DocumentUsage;
|
|
70
|
+
cost: DocumentCost;
|
|
71
|
+
}
|
|
72
|
+
interface DocumentQueryResult {
|
|
73
|
+
answer: string;
|
|
74
|
+
question: string;
|
|
75
|
+
pageCount: number;
|
|
76
|
+
model: string;
|
|
77
|
+
provider: string;
|
|
78
|
+
extractMethod: DocumentExtractMethod;
|
|
79
|
+
usage: DocumentUsage;
|
|
80
|
+
cost: DocumentCost;
|
|
81
|
+
}
|
|
82
|
+
declare class DocumentsNamespace {
|
|
83
|
+
private config;
|
|
84
|
+
constructor(config: Required<CencoriConfig>);
|
|
85
|
+
/** Extract text from a PDF (native, no LLM) or image (via Vision OCR). */
|
|
86
|
+
extract(request: DocumentRequest): Promise<DocumentExtractResult>;
|
|
87
|
+
/** Extract then summarize the document with a chat model. */
|
|
88
|
+
summarize(request: DocumentRequest): Promise<DocumentSummarizeResult>;
|
|
89
|
+
/** Extract then answer a question about the document. */
|
|
90
|
+
query(request: DocumentQueryRequest): Promise<DocumentQueryResult>;
|
|
91
|
+
private post;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export { type DocumentCost, type DocumentExtractMethod, type DocumentExtractResult, type DocumentInput, type DocumentKind, type DocumentQueryRequest, type DocumentQueryResult, type DocumentRequest, type DocumentSummarizeResult, type DocumentUsage, DocumentsNamespace };
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/documents/index.ts
|
|
21
|
+
var documents_exports = {};
|
|
22
|
+
__export(documents_exports, {
|
|
23
|
+
DocumentsNamespace: () => DocumentsNamespace
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(documents_exports);
|
|
26
|
+
function toBody(request, extra = {}) {
|
|
27
|
+
const body = {
|
|
28
|
+
prompt: request.prompt,
|
|
29
|
+
model: request.model,
|
|
30
|
+
max_tokens: request.maxTokens,
|
|
31
|
+
temperature: request.temperature,
|
|
32
|
+
...extra
|
|
33
|
+
};
|
|
34
|
+
if (request.document.url) {
|
|
35
|
+
body.document_url = request.document.url;
|
|
36
|
+
} else if (request.document.base64) {
|
|
37
|
+
body.document_base64 = request.document.base64;
|
|
38
|
+
body.mime_type = request.document.mimeType;
|
|
39
|
+
body.filename = request.document.filename;
|
|
40
|
+
} else {
|
|
41
|
+
throw new Error("documents request requires document.url or document.base64");
|
|
42
|
+
}
|
|
43
|
+
return body;
|
|
44
|
+
}
|
|
45
|
+
var DocumentsNamespace = class {
|
|
46
|
+
constructor(config) {
|
|
47
|
+
this.config = config;
|
|
48
|
+
}
|
|
49
|
+
/** Extract text from a PDF (native, no LLM) or image (via Vision OCR). */
|
|
50
|
+
async extract(request) {
|
|
51
|
+
return this.post("/api/ai/documents/extract", toBody(request));
|
|
52
|
+
}
|
|
53
|
+
/** Extract then summarize the document with a chat model. */
|
|
54
|
+
async summarize(request) {
|
|
55
|
+
return this.post("/api/ai/documents/summarize", toBody(request));
|
|
56
|
+
}
|
|
57
|
+
/** Extract then answer a question about the document. */
|
|
58
|
+
async query(request) {
|
|
59
|
+
if (!request.question) throw new Error("documents.query requires a `question`");
|
|
60
|
+
return this.post("/api/ai/documents/query", toBody(request, { question: request.question }));
|
|
61
|
+
}
|
|
62
|
+
async post(path, body) {
|
|
63
|
+
const response = await fetch(`${this.config.baseUrl}${path}`, {
|
|
64
|
+
method: "POST",
|
|
65
|
+
headers: {
|
|
66
|
+
"CENCORI_API_KEY": this.config.apiKey,
|
|
67
|
+
"Content-Type": "application/json",
|
|
68
|
+
...this.config.headers
|
|
69
|
+
},
|
|
70
|
+
body: JSON.stringify(body)
|
|
71
|
+
});
|
|
72
|
+
const data = await response.json();
|
|
73
|
+
if (!response.ok) {
|
|
74
|
+
const message = data && typeof data === "object" && "message" in data && typeof data.message === "string" ? data.message : `Documents request failed with status ${response.status}`;
|
|
75
|
+
const code = data && typeof data === "object" && "error" in data && typeof data.error === "string" ? data.error : "request_failed";
|
|
76
|
+
const err = new Error(message);
|
|
77
|
+
err.code = code;
|
|
78
|
+
err.details = data;
|
|
79
|
+
throw err;
|
|
80
|
+
}
|
|
81
|
+
return data;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
85
|
+
0 && (module.exports = {
|
|
86
|
+
DocumentsNamespace
|
|
87
|
+
});
|
|
88
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/documents/index.ts"],"sourcesContent":["/**\n * Documents API — extract text from PDFs and images, summarize, and query.\n *\n * @example\n * const { text, pageCount } = await cencori.documents.extract({\n * document: { url: 'https://example.com/contract.pdf' },\n * });\n *\n * @example\n * const { summary } = await cencori.documents.summarize({\n * document: { base64, mimeType: 'application/pdf' },\n * });\n *\n * @example\n * const { answer } = await cencori.documents.query({\n * document: { url: 'https://example.com/report.pdf' },\n * question: 'What is the total revenue for Q3?',\n * });\n */\n\nimport type { CencoriConfig } from '../types';\n\nexport type DocumentExtractMethod = 'pdf_text' | 'vision_ocr';\nexport type DocumentKind = 'pdf' | 'image';\n\nexport interface DocumentInput {\n url?: string;\n base64?: string;\n mimeType?: string;\n filename?: string;\n}\n\nexport interface DocumentRequest {\n document: DocumentInput;\n prompt?: string;\n model?: string;\n maxTokens?: number;\n temperature?: number;\n}\n\nexport interface DocumentQueryRequest extends DocumentRequest {\n question: string;\n}\n\nexport interface DocumentUsage {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n}\n\nexport interface DocumentCost {\n providerCostUsd: number;\n cencoriChargeUsd: number;\n markupPercentage: number;\n}\n\nexport interface DocumentExtractResult {\n text: string;\n pageCount: number;\n kind: DocumentKind;\n method: DocumentExtractMethod;\n model?: string;\n provider?: string;\n metadata?: Record<string, unknown>;\n usage?: DocumentUsage;\n cost?: DocumentCost;\n}\n\nexport interface DocumentSummarizeResult {\n summary: string;\n text: string;\n pageCount: number;\n model: string;\n provider: string;\n extractMethod: DocumentExtractMethod;\n usage: DocumentUsage;\n cost: DocumentCost;\n}\n\nexport interface DocumentQueryResult {\n answer: string;\n question: string;\n pageCount: number;\n model: string;\n provider: string;\n extractMethod: DocumentExtractMethod;\n usage: DocumentUsage;\n cost: DocumentCost;\n}\n\ninterface JsonBody {\n document_url?: string;\n document_base64?: string;\n mime_type?: string;\n filename?: string;\n prompt?: string;\n model?: string;\n max_tokens?: number;\n temperature?: number;\n question?: string;\n}\n\nfunction toBody(request: DocumentRequest, extra: Partial<JsonBody> = {}): JsonBody {\n const body: JsonBody = {\n prompt: request.prompt,\n model: request.model,\n max_tokens: request.maxTokens,\n temperature: request.temperature,\n ...extra,\n };\n if (request.document.url) {\n body.document_url = request.document.url;\n } else if (request.document.base64) {\n body.document_base64 = request.document.base64;\n body.mime_type = request.document.mimeType;\n body.filename = request.document.filename;\n } else {\n throw new Error('documents request requires document.url or document.base64');\n }\n return body;\n}\n\nexport class DocumentsNamespace {\n private config: Required<CencoriConfig>;\n\n constructor(config: Required<CencoriConfig>) {\n this.config = config;\n }\n\n /** Extract text from a PDF (native, no LLM) or image (via Vision OCR). */\n async extract(request: DocumentRequest): Promise<DocumentExtractResult> {\n return this.post<DocumentExtractResult>('/api/ai/documents/extract', toBody(request));\n }\n\n /** Extract then summarize the document with a chat model. */\n async summarize(request: DocumentRequest): Promise<DocumentSummarizeResult> {\n return this.post<DocumentSummarizeResult>('/api/ai/documents/summarize', toBody(request));\n }\n\n /** Extract then answer a question about the document. */\n async query(request: DocumentQueryRequest): Promise<DocumentQueryResult> {\n if (!request.question) throw new Error('documents.query requires a `question`');\n return this.post<DocumentQueryResult>('/api/ai/documents/query', toBody(request, { question: request.question }));\n }\n\n private async post<T>(path: string, body: JsonBody): 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(body),\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 : `Documents 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;AAsGA,SAAS,OAAO,SAA0B,QAA2B,CAAC,GAAa;AAC/E,QAAM,OAAiB;AAAA,IACnB,QAAQ,QAAQ;AAAA,IAChB,OAAO,QAAQ;AAAA,IACf,YAAY,QAAQ;AAAA,IACpB,aAAa,QAAQ;AAAA,IACrB,GAAG;AAAA,EACP;AACA,MAAI,QAAQ,SAAS,KAAK;AACtB,SAAK,eAAe,QAAQ,SAAS;AAAA,EACzC,WAAW,QAAQ,SAAS,QAAQ;AAChC,SAAK,kBAAkB,QAAQ,SAAS;AACxC,SAAK,YAAY,QAAQ,SAAS;AAClC,SAAK,WAAW,QAAQ,SAAS;AAAA,EACrC,OAAO;AACH,UAAM,IAAI,MAAM,4DAA4D;AAAA,EAChF;AACA,SAAO;AACX;AAEO,IAAM,qBAAN,MAAyB;AAAA,EAG5B,YAAY,QAAiC;AACzC,SAAK,SAAS;AAAA,EAClB;AAAA;AAAA,EAGA,MAAM,QAAQ,SAA0D;AACpE,WAAO,KAAK,KAA4B,6BAA6B,OAAO,OAAO,CAAC;AAAA,EACxF;AAAA;AAAA,EAGA,MAAM,UAAU,SAA4D;AACxE,WAAO,KAAK,KAA8B,+BAA+B,OAAO,OAAO,CAAC;AAAA,EAC5F;AAAA;AAAA,EAGA,MAAM,MAAM,SAA6D;AACrE,QAAI,CAAC,QAAQ,SAAU,OAAM,IAAI,MAAM,uCAAuC;AAC9E,WAAO,KAAK,KAA0B,2BAA2B,OAAO,SAAS,EAAE,UAAU,QAAQ,SAAS,CAAC,CAAC;AAAA,EACpH;AAAA,EAEA,MAAc,KAAQ,MAAc,MAA4B;AAC5D,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,IAAI;AAAA,IAC7B,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,wCAAwC,SAAS,MAAM;AACjE,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":[]}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// src/documents/index.ts
|
|
2
|
+
function toBody(request, extra = {}) {
|
|
3
|
+
const body = {
|
|
4
|
+
prompt: request.prompt,
|
|
5
|
+
model: request.model,
|
|
6
|
+
max_tokens: request.maxTokens,
|
|
7
|
+
temperature: request.temperature,
|
|
8
|
+
...extra
|
|
9
|
+
};
|
|
10
|
+
if (request.document.url) {
|
|
11
|
+
body.document_url = request.document.url;
|
|
12
|
+
} else if (request.document.base64) {
|
|
13
|
+
body.document_base64 = request.document.base64;
|
|
14
|
+
body.mime_type = request.document.mimeType;
|
|
15
|
+
body.filename = request.document.filename;
|
|
16
|
+
} else {
|
|
17
|
+
throw new Error("documents request requires document.url or document.base64");
|
|
18
|
+
}
|
|
19
|
+
return body;
|
|
20
|
+
}
|
|
21
|
+
var DocumentsNamespace = class {
|
|
22
|
+
constructor(config) {
|
|
23
|
+
this.config = config;
|
|
24
|
+
}
|
|
25
|
+
/** Extract text from a PDF (native, no LLM) or image (via Vision OCR). */
|
|
26
|
+
async extract(request) {
|
|
27
|
+
return this.post("/api/ai/documents/extract", toBody(request));
|
|
28
|
+
}
|
|
29
|
+
/** Extract then summarize the document with a chat model. */
|
|
30
|
+
async summarize(request) {
|
|
31
|
+
return this.post("/api/ai/documents/summarize", toBody(request));
|
|
32
|
+
}
|
|
33
|
+
/** Extract then answer a question about the document. */
|
|
34
|
+
async query(request) {
|
|
35
|
+
if (!request.question) throw new Error("documents.query requires a `question`");
|
|
36
|
+
return this.post("/api/ai/documents/query", toBody(request, { question: request.question }));
|
|
37
|
+
}
|
|
38
|
+
async post(path, body) {
|
|
39
|
+
const response = await fetch(`${this.config.baseUrl}${path}`, {
|
|
40
|
+
method: "POST",
|
|
41
|
+
headers: {
|
|
42
|
+
"CENCORI_API_KEY": this.config.apiKey,
|
|
43
|
+
"Content-Type": "application/json",
|
|
44
|
+
...this.config.headers
|
|
45
|
+
},
|
|
46
|
+
body: JSON.stringify(body)
|
|
47
|
+
});
|
|
48
|
+
const data = await response.json();
|
|
49
|
+
if (!response.ok) {
|
|
50
|
+
const message = data && typeof data === "object" && "message" in data && typeof data.message === "string" ? data.message : `Documents request failed with status ${response.status}`;
|
|
51
|
+
const code = data && typeof data === "object" && "error" in data && typeof data.error === "string" ? data.error : "request_failed";
|
|
52
|
+
const err = new Error(message);
|
|
53
|
+
err.code = code;
|
|
54
|
+
err.details = data;
|
|
55
|
+
throw err;
|
|
56
|
+
}
|
|
57
|
+
return data;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
export {
|
|
61
|
+
DocumentsNamespace
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/documents/index.ts"],"sourcesContent":["/**\n * Documents API — extract text from PDFs and images, summarize, and query.\n *\n * @example\n * const { text, pageCount } = await cencori.documents.extract({\n * document: { url: 'https://example.com/contract.pdf' },\n * });\n *\n * @example\n * const { summary } = await cencori.documents.summarize({\n * document: { base64, mimeType: 'application/pdf' },\n * });\n *\n * @example\n * const { answer } = await cencori.documents.query({\n * document: { url: 'https://example.com/report.pdf' },\n * question: 'What is the total revenue for Q3?',\n * });\n */\n\nimport type { CencoriConfig } from '../types';\n\nexport type DocumentExtractMethod = 'pdf_text' | 'vision_ocr';\nexport type DocumentKind = 'pdf' | 'image';\n\nexport interface DocumentInput {\n url?: string;\n base64?: string;\n mimeType?: string;\n filename?: string;\n}\n\nexport interface DocumentRequest {\n document: DocumentInput;\n prompt?: string;\n model?: string;\n maxTokens?: number;\n temperature?: number;\n}\n\nexport interface DocumentQueryRequest extends DocumentRequest {\n question: string;\n}\n\nexport interface DocumentUsage {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n}\n\nexport interface DocumentCost {\n providerCostUsd: number;\n cencoriChargeUsd: number;\n markupPercentage: number;\n}\n\nexport interface DocumentExtractResult {\n text: string;\n pageCount: number;\n kind: DocumentKind;\n method: DocumentExtractMethod;\n model?: string;\n provider?: string;\n metadata?: Record<string, unknown>;\n usage?: DocumentUsage;\n cost?: DocumentCost;\n}\n\nexport interface DocumentSummarizeResult {\n summary: string;\n text: string;\n pageCount: number;\n model: string;\n provider: string;\n extractMethod: DocumentExtractMethod;\n usage: DocumentUsage;\n cost: DocumentCost;\n}\n\nexport interface DocumentQueryResult {\n answer: string;\n question: string;\n pageCount: number;\n model: string;\n provider: string;\n extractMethod: DocumentExtractMethod;\n usage: DocumentUsage;\n cost: DocumentCost;\n}\n\ninterface JsonBody {\n document_url?: string;\n document_base64?: string;\n mime_type?: string;\n filename?: string;\n prompt?: string;\n model?: string;\n max_tokens?: number;\n temperature?: number;\n question?: string;\n}\n\nfunction toBody(request: DocumentRequest, extra: Partial<JsonBody> = {}): JsonBody {\n const body: JsonBody = {\n prompt: request.prompt,\n model: request.model,\n max_tokens: request.maxTokens,\n temperature: request.temperature,\n ...extra,\n };\n if (request.document.url) {\n body.document_url = request.document.url;\n } else if (request.document.base64) {\n body.document_base64 = request.document.base64;\n body.mime_type = request.document.mimeType;\n body.filename = request.document.filename;\n } else {\n throw new Error('documents request requires document.url or document.base64');\n }\n return body;\n}\n\nexport class DocumentsNamespace {\n private config: Required<CencoriConfig>;\n\n constructor(config: Required<CencoriConfig>) {\n this.config = config;\n }\n\n /** Extract text from a PDF (native, no LLM) or image (via Vision OCR). */\n async extract(request: DocumentRequest): Promise<DocumentExtractResult> {\n return this.post<DocumentExtractResult>('/api/ai/documents/extract', toBody(request));\n }\n\n /** Extract then summarize the document with a chat model. */\n async summarize(request: DocumentRequest): Promise<DocumentSummarizeResult> {\n return this.post<DocumentSummarizeResult>('/api/ai/documents/summarize', toBody(request));\n }\n\n /** Extract then answer a question about the document. */\n async query(request: DocumentQueryRequest): Promise<DocumentQueryResult> {\n if (!request.question) throw new Error('documents.query requires a `question`');\n return this.post<DocumentQueryResult>('/api/ai/documents/query', toBody(request, { question: request.question }));\n }\n\n private async post<T>(path: string, body: JsonBody): 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(body),\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 : `Documents 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":";AAsGA,SAAS,OAAO,SAA0B,QAA2B,CAAC,GAAa;AAC/E,QAAM,OAAiB;AAAA,IACnB,QAAQ,QAAQ;AAAA,IAChB,OAAO,QAAQ;AAAA,IACf,YAAY,QAAQ;AAAA,IACpB,aAAa,QAAQ;AAAA,IACrB,GAAG;AAAA,EACP;AACA,MAAI,QAAQ,SAAS,KAAK;AACtB,SAAK,eAAe,QAAQ,SAAS;AAAA,EACzC,WAAW,QAAQ,SAAS,QAAQ;AAChC,SAAK,kBAAkB,QAAQ,SAAS;AACxC,SAAK,YAAY,QAAQ,SAAS;AAClC,SAAK,WAAW,QAAQ,SAAS;AAAA,EACrC,OAAO;AACH,UAAM,IAAI,MAAM,4DAA4D;AAAA,EAChF;AACA,SAAO;AACX;AAEO,IAAM,qBAAN,MAAyB;AAAA,EAG5B,YAAY,QAAiC;AACzC,SAAK,SAAS;AAAA,EAClB;AAAA;AAAA,EAGA,MAAM,QAAQ,SAA0D;AACpE,WAAO,KAAK,KAA4B,6BAA6B,OAAO,OAAO,CAAC;AAAA,EACxF;AAAA;AAAA,EAGA,MAAM,UAAU,SAA4D;AACxE,WAAO,KAAK,KAA8B,+BAA+B,OAAO,OAAO,CAAC;AAAA,EAC5F;AAAA;AAAA,EAGA,MAAM,MAAM,SAA6D;AACrE,QAAI,CAAC,QAAQ,SAAU,OAAM,IAAI,MAAM,uCAAuC;AAC9E,WAAO,KAAK,KAA0B,2BAA2B,OAAO,SAAS,EAAE,UAAU,QAAQ,SAAS,CAAC,CAAC;AAAA,EACpH;AAAA,EAEA,MAAc,KAAQ,MAAc,MAA4B;AAC5D,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,IAAI;AAAA,IAC7B,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,wCAAwC,SAAS,MAAM;AACjE,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/dist/index.d.mts
CHANGED
|
@@ -3,7 +3,9 @@ export { j as ChatMessage, a as ChatRequest, b as ChatResponse, o as CodeInterpr
|
|
|
3
3
|
import { AINamespace } from './ai/index.mjs';
|
|
4
4
|
export { StreamChunk } from './ai/index.mjs';
|
|
5
5
|
import { VisionNamespace } from './vision/index.mjs';
|
|
6
|
-
export { VisionClassification, VisionClassifyResult, VisionCost, VisionDescribeResult, VisionImage, VisionOcrResult, VisionProvider, VisionRequest, VisionResult, VisionTask, VisionUsage } from './vision/index.mjs';
|
|
6
|
+
export { VisionClassification, VisionClassifyResult, VisionCost, VisionDescribeResult, VisionImage, VisionOcrResult, VisionProvider, VisionRequest, VisionResult, VisionStreamChunk, VisionTask, VisionUsage } from './vision/index.mjs';
|
|
7
|
+
import { DocumentsNamespace } from './documents/index.mjs';
|
|
8
|
+
export { DocumentCost, DocumentExtractMethod, DocumentExtractResult, DocumentInput, DocumentKind, DocumentQueryRequest, DocumentQueryResult, DocumentRequest, DocumentSummarizeResult, DocumentUsage } from './documents/index.mjs';
|
|
7
9
|
import { ComputeNamespace } from './compute/index.mjs';
|
|
8
10
|
import { WorkflowNamespace } from './workflow/index.mjs';
|
|
9
11
|
import { StorageNamespace } from './storage/index.mjs';
|
|
@@ -229,6 +231,26 @@ declare class Cencori {
|
|
|
229
231
|
* });
|
|
230
232
|
*/
|
|
231
233
|
readonly vision: VisionNamespace;
|
|
234
|
+
/**
|
|
235
|
+
* Documents - Extract text from PDFs and images, summarize, and query
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* const { text } = await cencori.documents.extract({
|
|
239
|
+
* document: { url: 'https://example.com/contract.pdf' }
|
|
240
|
+
* });
|
|
241
|
+
*
|
|
242
|
+
* @example
|
|
243
|
+
* const { summary } = await cencori.documents.summarize({
|
|
244
|
+
* document: { url: 'https://example.com/report.pdf' }
|
|
245
|
+
* });
|
|
246
|
+
*
|
|
247
|
+
* @example
|
|
248
|
+
* const { answer } = await cencori.documents.query({
|
|
249
|
+
* document: { url },
|
|
250
|
+
* question: 'What is the total revenue for Q3?',
|
|
251
|
+
* });
|
|
252
|
+
*/
|
|
253
|
+
readonly documents: DocumentsNamespace;
|
|
232
254
|
/**
|
|
233
255
|
* Agents - Create and manage AI agents programmatically.
|
|
234
256
|
*
|
|
@@ -369,4 +391,4 @@ declare class SafetyError extends CencoriError {
|
|
|
369
391
|
*/
|
|
370
392
|
declare function fetchWithRetry(url: string, options: RequestInit, maxRetries?: number): Promise<Response>;
|
|
371
393
|
|
|
372
|
-
export { AINamespace, type Agent, type AgentConfig, type AgentKey, type AgentListItem, AgentsNamespace, AuthenticationError, Cencori, CencoriConfig, CencoriError, ComputeNamespace, type CreateAgentKeyParams, type CreateAgentParams, type CreateSessionParams, MemoryClient, type PaginatedResponse, RateLimitError, RequestOptions, SafetyError, type Session, type SessionEvent, type SessionListParams, SessionsNamespace, StorageNamespace, TelemetryClient, type TurnParams, type UpdateAgentParams, VisionNamespace, WorkflowNamespace, Cencori as default, fetchWithRetry };
|
|
394
|
+
export { AINamespace, type Agent, type AgentConfig, type AgentKey, type AgentListItem, AgentsNamespace, AuthenticationError, Cencori, CencoriConfig, CencoriError, ComputeNamespace, type CreateAgentKeyParams, type CreateAgentParams, type CreateSessionParams, DocumentsNamespace, MemoryClient, type PaginatedResponse, RateLimitError, RequestOptions, SafetyError, type Session, type SessionEvent, type SessionListParams, SessionsNamespace, StorageNamespace, TelemetryClient, type TurnParams, type UpdateAgentParams, VisionNamespace, WorkflowNamespace, Cencori as default, fetchWithRetry };
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,9 @@ export { j as ChatMessage, a as ChatRequest, b as ChatResponse, o as CodeInterpr
|
|
|
3
3
|
import { AINamespace } from './ai/index.js';
|
|
4
4
|
export { StreamChunk } from './ai/index.js';
|
|
5
5
|
import { VisionNamespace } from './vision/index.js';
|
|
6
|
-
export { VisionClassification, VisionClassifyResult, VisionCost, VisionDescribeResult, VisionImage, VisionOcrResult, VisionProvider, VisionRequest, VisionResult, VisionTask, VisionUsage } from './vision/index.js';
|
|
6
|
+
export { VisionClassification, VisionClassifyResult, VisionCost, VisionDescribeResult, VisionImage, VisionOcrResult, VisionProvider, VisionRequest, VisionResult, VisionStreamChunk, VisionTask, VisionUsage } from './vision/index.js';
|
|
7
|
+
import { DocumentsNamespace } from './documents/index.js';
|
|
8
|
+
export { DocumentCost, DocumentExtractMethod, DocumentExtractResult, DocumentInput, DocumentKind, DocumentQueryRequest, DocumentQueryResult, DocumentRequest, DocumentSummarizeResult, DocumentUsage } from './documents/index.js';
|
|
7
9
|
import { ComputeNamespace } from './compute/index.js';
|
|
8
10
|
import { WorkflowNamespace } from './workflow/index.js';
|
|
9
11
|
import { StorageNamespace } from './storage/index.js';
|
|
@@ -229,6 +231,26 @@ declare class Cencori {
|
|
|
229
231
|
* });
|
|
230
232
|
*/
|
|
231
233
|
readonly vision: VisionNamespace;
|
|
234
|
+
/**
|
|
235
|
+
* Documents - Extract text from PDFs and images, summarize, and query
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* const { text } = await cencori.documents.extract({
|
|
239
|
+
* document: { url: 'https://example.com/contract.pdf' }
|
|
240
|
+
* });
|
|
241
|
+
*
|
|
242
|
+
* @example
|
|
243
|
+
* const { summary } = await cencori.documents.summarize({
|
|
244
|
+
* document: { url: 'https://example.com/report.pdf' }
|
|
245
|
+
* });
|
|
246
|
+
*
|
|
247
|
+
* @example
|
|
248
|
+
* const { answer } = await cencori.documents.query({
|
|
249
|
+
* document: { url },
|
|
250
|
+
* question: 'What is the total revenue for Q3?',
|
|
251
|
+
* });
|
|
252
|
+
*/
|
|
253
|
+
readonly documents: DocumentsNamespace;
|
|
232
254
|
/**
|
|
233
255
|
* Agents - Create and manage AI agents programmatically.
|
|
234
256
|
*
|
|
@@ -369,4 +391,4 @@ declare class SafetyError extends CencoriError {
|
|
|
369
391
|
*/
|
|
370
392
|
declare function fetchWithRetry(url: string, options: RequestInit, maxRetries?: number): Promise<Response>;
|
|
371
393
|
|
|
372
|
-
export { AINamespace, type Agent, type AgentConfig, type AgentKey, type AgentListItem, AgentsNamespace, AuthenticationError, Cencori, CencoriConfig, CencoriError, ComputeNamespace, type CreateAgentKeyParams, type CreateAgentParams, type CreateSessionParams, MemoryClient, type PaginatedResponse, RateLimitError, RequestOptions, SafetyError, type Session, type SessionEvent, type SessionListParams, SessionsNamespace, StorageNamespace, TelemetryClient, type TurnParams, type UpdateAgentParams, VisionNamespace, WorkflowNamespace, Cencori as default, fetchWithRetry };
|
|
394
|
+
export { AINamespace, type Agent, type AgentConfig, type AgentKey, type AgentListItem, AgentsNamespace, AuthenticationError, Cencori, CencoriConfig, CencoriError, ComputeNamespace, type CreateAgentKeyParams, type CreateAgentParams, type CreateSessionParams, DocumentsNamespace, MemoryClient, type PaginatedResponse, RateLimitError, RequestOptions, SafetyError, type Session, type SessionEvent, type SessionListParams, SessionsNamespace, StorageNamespace, TelemetryClient, type TurnParams, type UpdateAgentParams, VisionNamespace, WorkflowNamespace, Cencori as default, fetchWithRetry };
|
package/dist/index.js
CHANGED
|
@@ -26,6 +26,7 @@ __export(src_exports, {
|
|
|
26
26
|
Cencori: () => Cencori,
|
|
27
27
|
CencoriError: () => CencoriError,
|
|
28
28
|
ComputeNamespace: () => ComputeNamespace,
|
|
29
|
+
DocumentsNamespace: () => DocumentsNamespace,
|
|
29
30
|
MemoryClient: () => MemoryClient,
|
|
30
31
|
RateLimitError: () => RateLimitError,
|
|
31
32
|
SafetyError: () => SafetyError,
|
|
@@ -643,6 +644,17 @@ function toBody(request) {
|
|
|
643
644
|
temperature: request.temperature,
|
|
644
645
|
response_format: request.responseFormat
|
|
645
646
|
};
|
|
647
|
+
if (request.images && request.images.length > 0) {
|
|
648
|
+
body.images = request.images.map((img) => {
|
|
649
|
+
if (img.url) return { url: img.url };
|
|
650
|
+
if (img.base64) return { base64: img.base64, mime_type: img.mimeType };
|
|
651
|
+
throw new Error("Each entry in images requires url or base64");
|
|
652
|
+
});
|
|
653
|
+
return body;
|
|
654
|
+
}
|
|
655
|
+
if (!request.image) {
|
|
656
|
+
throw new Error("vision request requires `image` or `images[]`");
|
|
657
|
+
}
|
|
646
658
|
if (request.image.url) {
|
|
647
659
|
body.image_url = request.image.url;
|
|
648
660
|
} else if (request.image.base64) {
|
|
@@ -676,6 +688,57 @@ var VisionNamespace = class {
|
|
|
676
688
|
async classify(request) {
|
|
677
689
|
return this.post("/api/ai/vision/classify", request);
|
|
678
690
|
}
|
|
691
|
+
/**
|
|
692
|
+
* Stream a vision analysis. Yields `{ delta }` chunks as text arrives, then
|
|
693
|
+
* a final `{ done: true, model, provider, usage, cost }` chunk with totals.
|
|
694
|
+
*
|
|
695
|
+
* @example
|
|
696
|
+
* for await (const chunk of cencori.vision.analyzeStream({ image: { url } })) {
|
|
697
|
+
* if (chunk.delta) process.stdout.write(chunk.delta);
|
|
698
|
+
* if (chunk.done) console.log(chunk.cost);
|
|
699
|
+
* }
|
|
700
|
+
*/
|
|
701
|
+
async *analyzeStream(request) {
|
|
702
|
+
const body = { ...toBody(request), stream: true };
|
|
703
|
+
const response = await fetch(`${this.config.baseUrl}/api/ai/vision`, {
|
|
704
|
+
method: "POST",
|
|
705
|
+
headers: {
|
|
706
|
+
"CENCORI_API_KEY": this.config.apiKey,
|
|
707
|
+
"Content-Type": "application/json",
|
|
708
|
+
...this.config.headers
|
|
709
|
+
},
|
|
710
|
+
body: JSON.stringify(body)
|
|
711
|
+
});
|
|
712
|
+
if (!response.ok) {
|
|
713
|
+
const data = await response.json().catch(() => ({}));
|
|
714
|
+
const message = data && typeof data === "object" && "message" in data && typeof data.message === "string" ? data.message : `Vision stream request failed with status ${response.status}`;
|
|
715
|
+
throw new Error(message);
|
|
716
|
+
}
|
|
717
|
+
if (!response.body) throw new Error("Response body is null");
|
|
718
|
+
const reader = response.body.getReader();
|
|
719
|
+
const decoder = new TextDecoder();
|
|
720
|
+
let buffer = "";
|
|
721
|
+
try {
|
|
722
|
+
while (true) {
|
|
723
|
+
const { done, value } = await reader.read();
|
|
724
|
+
if (done) break;
|
|
725
|
+
buffer += decoder.decode(value, { stream: true });
|
|
726
|
+
const lines = buffer.split("\n");
|
|
727
|
+
buffer = lines.pop() ?? "";
|
|
728
|
+
for (const line of lines) {
|
|
729
|
+
if (!line.startsWith("data: ")) continue;
|
|
730
|
+
const data = line.slice(6);
|
|
731
|
+
if (data === "[DONE]") return;
|
|
732
|
+
try {
|
|
733
|
+
yield JSON.parse(data);
|
|
734
|
+
} catch {
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
} finally {
|
|
739
|
+
reader.releaseLock();
|
|
740
|
+
}
|
|
741
|
+
}
|
|
679
742
|
async post(path, request) {
|
|
680
743
|
const response = await fetch(`${this.config.baseUrl}${path}`, {
|
|
681
744
|
method: "POST",
|
|
@@ -699,6 +762,66 @@ var VisionNamespace = class {
|
|
|
699
762
|
}
|
|
700
763
|
};
|
|
701
764
|
|
|
765
|
+
// src/documents/index.ts
|
|
766
|
+
function toBody2(request, extra = {}) {
|
|
767
|
+
const body = {
|
|
768
|
+
prompt: request.prompt,
|
|
769
|
+
model: request.model,
|
|
770
|
+
max_tokens: request.maxTokens,
|
|
771
|
+
temperature: request.temperature,
|
|
772
|
+
...extra
|
|
773
|
+
};
|
|
774
|
+
if (request.document.url) {
|
|
775
|
+
body.document_url = request.document.url;
|
|
776
|
+
} else if (request.document.base64) {
|
|
777
|
+
body.document_base64 = request.document.base64;
|
|
778
|
+
body.mime_type = request.document.mimeType;
|
|
779
|
+
body.filename = request.document.filename;
|
|
780
|
+
} else {
|
|
781
|
+
throw new Error("documents request requires document.url or document.base64");
|
|
782
|
+
}
|
|
783
|
+
return body;
|
|
784
|
+
}
|
|
785
|
+
var DocumentsNamespace = class {
|
|
786
|
+
constructor(config) {
|
|
787
|
+
this.config = config;
|
|
788
|
+
}
|
|
789
|
+
/** Extract text from a PDF (native, no LLM) or image (via Vision OCR). */
|
|
790
|
+
async extract(request) {
|
|
791
|
+
return this.post("/api/ai/documents/extract", toBody2(request));
|
|
792
|
+
}
|
|
793
|
+
/** Extract then summarize the document with a chat model. */
|
|
794
|
+
async summarize(request) {
|
|
795
|
+
return this.post("/api/ai/documents/summarize", toBody2(request));
|
|
796
|
+
}
|
|
797
|
+
/** Extract then answer a question about the document. */
|
|
798
|
+
async query(request) {
|
|
799
|
+
if (!request.question) throw new Error("documents.query requires a `question`");
|
|
800
|
+
return this.post("/api/ai/documents/query", toBody2(request, { question: request.question }));
|
|
801
|
+
}
|
|
802
|
+
async post(path, body) {
|
|
803
|
+
const response = await fetch(`${this.config.baseUrl}${path}`, {
|
|
804
|
+
method: "POST",
|
|
805
|
+
headers: {
|
|
806
|
+
"CENCORI_API_KEY": this.config.apiKey,
|
|
807
|
+
"Content-Type": "application/json",
|
|
808
|
+
...this.config.headers
|
|
809
|
+
},
|
|
810
|
+
body: JSON.stringify(body)
|
|
811
|
+
});
|
|
812
|
+
const data = await response.json();
|
|
813
|
+
if (!response.ok) {
|
|
814
|
+
const message = data && typeof data === "object" && "message" in data && typeof data.message === "string" ? data.message : `Documents request failed with status ${response.status}`;
|
|
815
|
+
const code = data && typeof data === "object" && "error" in data && typeof data.error === "string" ? data.error : "request_failed";
|
|
816
|
+
const err = new Error(message);
|
|
817
|
+
err.code = code;
|
|
818
|
+
err.details = data;
|
|
819
|
+
throw err;
|
|
820
|
+
}
|
|
821
|
+
return data;
|
|
822
|
+
}
|
|
823
|
+
};
|
|
824
|
+
|
|
702
825
|
// src/sessions/index.ts
|
|
703
826
|
var SessionsNamespace = class {
|
|
704
827
|
constructor(config) {
|
|
@@ -1223,6 +1346,7 @@ var Cencori = class {
|
|
|
1223
1346
|
};
|
|
1224
1347
|
this.ai = new AINamespace(this.config);
|
|
1225
1348
|
this.vision = new VisionNamespace(this.config);
|
|
1349
|
+
this.documents = new DocumentsNamespace(this.config);
|
|
1226
1350
|
this.agents = new AgentsNamespace(this.config);
|
|
1227
1351
|
this.compute = new ComputeNamespace();
|
|
1228
1352
|
this.workflow = new WorkflowNamespace();
|
|
@@ -1650,6 +1774,7 @@ cencori.chat = cencori;
|
|
|
1650
1774
|
Cencori,
|
|
1651
1775
|
CencoriError,
|
|
1652
1776
|
ComputeNamespace,
|
|
1777
|
+
DocumentsNamespace,
|
|
1653
1778
|
MemoryClient,
|
|
1654
1779
|
RateLimitError,
|
|
1655
1780
|
SafetyError,
|