cencori 1.3.1 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -170,6 +170,31 @@ import { VisionUploader } from 'cencori/react';
170
170
 
171
171
  Full API in [docs](https://cencori.com/docs/ai/endpoints/vision).
172
172
 
173
+ ### Documents (PDF & Image Extraction)
174
+
175
+ Extract text from PDFs and images, summarize documents, and answer questions about them. Text-based PDFs use native parsing — no LLM tokens, free.
176
+
177
+ ```typescript
178
+ // Extract text — native PDF parsing, free
179
+ const { text, method } = await cencori.documents.extract({
180
+ document: { url: 'https://example.com/contract.pdf' },
181
+ });
182
+ console.log(method); // 'pdf_text' means free
183
+
184
+ // Summarize
185
+ const { summary } = await cencori.documents.summarize({
186
+ document: { url: 'https://example.com/report.pdf' },
187
+ });
188
+
189
+ // Q&A — strict "Not found" if the answer isn't in the doc
190
+ const { answer } = await cencori.documents.query({
191
+ document: { url: 'https://example.com/contract.pdf' },
192
+ question: 'What is the termination clause?',
193
+ });
194
+ ```
195
+
196
+ Full API in [docs](https://cencori.com/docs/ai/endpoints/documents). See the [Contract Analyzer tutorial](https://cencori.com/docs/guides/build-a-contract-analyzer) for an end-to-end example.
197
+
173
198
  ### Image Generation
174
199
 
175
200
  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
@@ -4,6 +4,10 @@ import { AINamespace } from './ai/index.mjs';
4
4
  export { StreamChunk } from './ai/index.mjs';
5
5
  import { VisionNamespace } from './vision/index.mjs';
6
6
  export { VisionClassification, VisionClassifyResult, VisionCost, VisionDescribeResult, VisionImage, VisionOcrResult, VisionProvider, VisionRequest, VisionResult, VisionStreamChunk, VisionTask, VisionUsage } from './vision/index.mjs';
7
+ import { VoiceNamespace } from './voice/index.mjs';
8
+ export { AudioFormat, AudioInput, STTProvider, SpeakRequest, SpeakResult, TTSProvider, TranscribeRequest, TranscribeResult, TranscriptFormat, TranscriptSegment, TranscriptWord, VoiceModelInfo } from './voice/index.mjs';
9
+ import { DocumentsNamespace } from './documents/index.mjs';
10
+ export { DocumentCost, DocumentExtractMethod, DocumentExtractResult, DocumentInput, DocumentKind, DocumentQueryRequest, DocumentQueryResult, DocumentRequest, DocumentSummarizeResult, DocumentUsage } from './documents/index.mjs';
7
11
  import { ComputeNamespace } from './compute/index.mjs';
8
12
  import { WorkflowNamespace } from './workflow/index.mjs';
9
13
  import { StorageNamespace } from './storage/index.mjs';
@@ -178,6 +182,118 @@ declare class SessionsNamespace {
178
182
  }>;
179
183
  }
180
184
 
185
+ /**
186
+ * Cencori Chat namespace — OpenAI-compatible chat completions with
187
+ * gateway-level memory.
188
+ *
189
+ * The magic path: one line makes chat stateful.
190
+ *
191
+ * @example
192
+ * ```typescript
193
+ * const response = await cencori.chat.completions.create({
194
+ * model: 'gpt-4o',
195
+ * messages: [{ role: 'user', content: 'What did we agree about pricing?' }],
196
+ * memory: { userId: session.user.id },
197
+ * });
198
+ * console.log(response.choices[0].message.content);
199
+ * console.log(response.memory?.retrieved); // facts injected into this reply
200
+ * ```
201
+ */
202
+
203
+ interface ChatMemoryOptions {
204
+ userId?: string;
205
+ sessionId?: string;
206
+ scope?: 'session' | 'user';
207
+ retrieve?: boolean;
208
+ write?: boolean;
209
+ topK?: number;
210
+ threshold?: number;
211
+ namespace?: string;
212
+ extract?: {
213
+ model?: string;
214
+ prompt?: string;
215
+ minImportance?: number;
216
+ };
217
+ }
218
+ interface ChatCompletionMessage {
219
+ role: 'system' | 'user' | 'assistant' | 'tool';
220
+ content: string;
221
+ }
222
+ interface ChatCompletionCreateParams {
223
+ model: string;
224
+ messages: ChatCompletionMessage[];
225
+ temperature?: number;
226
+ max_tokens?: number;
227
+ user?: string;
228
+ memory?: ChatMemoryOptions;
229
+ tools?: unknown[];
230
+ tool_choice?: unknown;
231
+ prompt?: {
232
+ name: string;
233
+ variables?: Record<string, string>;
234
+ };
235
+ }
236
+ interface ChatCompletionResponse {
237
+ id: string;
238
+ object: string;
239
+ created: number;
240
+ model: string;
241
+ choices: Array<{
242
+ index: number;
243
+ message: {
244
+ role: string;
245
+ content: string;
246
+ tool_calls?: unknown[];
247
+ };
248
+ finish_reason: string;
249
+ }>;
250
+ usage?: {
251
+ prompt_tokens: number;
252
+ completion_tokens: number;
253
+ total_tokens: number;
254
+ };
255
+ memory?: {
256
+ retrieved: Array<{
257
+ id: string;
258
+ score: number;
259
+ content: string;
260
+ }>;
261
+ written: Array<{
262
+ id: string;
263
+ content: string;
264
+ }>;
265
+ write_status: 'pending' | 'disabled';
266
+ };
267
+ }
268
+ interface ChatCompletionChunk {
269
+ delta: string;
270
+ raw: Record<string, unknown>;
271
+ }
272
+ interface ChatCompletionStream extends AsyncIterable<ChatCompletionChunk> {
273
+ /** Number of memories injected into this request (from X-Cencori-Memory-Retrieved). */
274
+ memoriesRetrieved: number;
275
+ }
276
+ declare class Completions {
277
+ private config;
278
+ constructor(config: Required<CencoriConfig>);
279
+ private endpoint;
280
+ private headers;
281
+ /**
282
+ * Create a chat completion. Include `memory: { userId }` to retrieve
283
+ * relevant facts before the model call and persist new ones after it.
284
+ */
285
+ create(params: ChatCompletionCreateParams): Promise<ChatCompletionResponse>;
286
+ /**
287
+ * Stream a chat completion (SSE). Memory writeback still runs after the
288
+ * stream completes; `memoriesRetrieved` reports the injected count.
289
+ */
290
+ stream(params: ChatCompletionCreateParams): Promise<ChatCompletionStream>;
291
+ }
292
+ declare class ChatNamespace {
293
+ readonly completions: Completions;
294
+ constructor(config: Required<CencoriConfig>);
295
+ }
296
+
181
297
  /**
182
298
  * Cencori - Unified AI Infrastructure SDK
183
299
  *
@@ -214,6 +330,18 @@ declare class Cencori {
214
330
  * await cencori.ai.chat({ model: 'gpt-4o', messages: [...] });
215
331
  */
216
332
  readonly ai: AINamespace;
333
+ /**
334
+ * Chat - OpenAI-compatible chat completions with gateway memory.
335
+ * One line makes chat stateful.
336
+ *
337
+ * @example
338
+ * const response = await cencori.chat.completions.create({
339
+ * model: 'gpt-4o',
340
+ * messages: [{ role: 'user', content: 'What did we agree about pricing?' }],
341
+ * memory: { userId: session.user.id },
342
+ * });
343
+ */
344
+ readonly chat: ChatNamespace;
217
345
  /**
218
346
  * Vision - Analyze, describe, OCR, and classify images
219
347
  *
@@ -229,6 +357,48 @@ declare class Cencori {
229
357
  * });
230
358
  */
231
359
  readonly vision: VisionNamespace;
360
+ /**
361
+ * Voice - Text-to-speech and speech-to-text across providers
362
+ *
363
+ * @example
364
+ * const { audio } = await cencori.voice.speak({
365
+ * input: 'Hello from Cencori.',
366
+ * model: 'aura-asteria-en', // Deepgram; provider inferred from model
367
+ * });
368
+ *
369
+ * @example
370
+ * const { text } = await cencori.voice.transcribe({
371
+ * audio: fileBytes,
372
+ * model: 'nova-3',
373
+ * });
374
+ *
375
+ * @example
376
+ * const { segments } = await cencori.voice.diarize({
377
+ * audio: fileBytes,
378
+ * model: 'assemblyai-universal',
379
+ * });
380
+ */
381
+ readonly voice: VoiceNamespace;
382
+ /**
383
+ * Documents - Extract text from PDFs and images, summarize, and query
384
+ *
385
+ * @example
386
+ * const { text } = await cencori.documents.extract({
387
+ * document: { url: 'https://example.com/contract.pdf' }
388
+ * });
389
+ *
390
+ * @example
391
+ * const { summary } = await cencori.documents.summarize({
392
+ * document: { url: 'https://example.com/report.pdf' }
393
+ * });
394
+ *
395
+ * @example
396
+ * const { answer } = await cencori.documents.query({
397
+ * document: { url },
398
+ * question: 'What is the total revenue for Q3?',
399
+ * });
400
+ */
401
+ readonly documents: DocumentsNamespace;
232
402
  /**
233
403
  * Agents - Create and manage AI agents programmatically.
234
404
  *
@@ -369,4 +539,4 @@ declare class SafetyError extends CencoriError {
369
539
  */
370
540
  declare function fetchWithRetry(url: string, options: RequestInit, maxRetries?: number): Promise<Response>;
371
541
 
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 };
542
+ export { AINamespace, type Agent, type AgentConfig, type AgentKey, type AgentListItem, AgentsNamespace, AuthenticationError, Cencori, CencoriConfig, CencoriError, type ChatCompletionChunk, type ChatCompletionCreateParams, type ChatCompletionResponse, type ChatCompletionStream, type ChatMemoryOptions, ChatNamespace, 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, VoiceNamespace, WorkflowNamespace, Cencori as default, fetchWithRetry };