@okrapdf/runtime 0.7.2 → 0.7.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,9 +1,6 @@
1
1
  # @okrapdf/runtime
2
2
 
3
- Upload a PDF, get an API. Pages, entities, search, AI completion, structured output — all from one URL.
4
-
5
- [![npm](https://img.shields.io/npm/v/@okrapdf/runtime)](https://www.npmjs.com/package/@okrapdf/runtime)
6
- [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
3
+ Small session-first SDK on top of the OkraPDF HTTP API.
7
4
 
8
5
  ## Install
9
6
 
@@ -11,27 +8,35 @@ Upload a PDF, get an API. Pages, entities, search, AI completion, structured out
11
8
  npm install @okrapdf/runtime
12
9
  ```
13
10
 
11
+ ## SDK Surface
12
+
13
+ Only two runtime entry points:
14
+
15
+ - `createOkra(...)` for document sessions
16
+ - `doc(...)` for deterministic document URLs
17
+
14
18
  ## Quick Start
15
19
 
16
20
  ```ts
17
- import { OkraClient } from '@okrapdf/runtime';
21
+ import { createOkra } from '@okrapdf/runtime';
18
22
 
19
- const okra = new OkraClient({ apiKey: process.env.OKRA_API_KEY });
23
+ const okra = createOkra({ apiKey: process.env.OKRA_API_KEY });
20
24
 
21
- // Upload and wait
22
- const doc = await okra.upload('./report.pdf');
23
- await okra.wait(doc.id);
25
+ const session = await okra.sessions.create('./report.pdf', {
26
+ wait: true,
27
+ model: 'kimi-k2p5',
28
+ });
24
29
 
25
- // Read pages
26
- const pages = await okra.pages(doc.id);
30
+ const { answer } = await session.prompt('What is total revenue?');
31
+ console.log(answer);
27
32
 
28
- // Ask questions
29
- const { answer } = await okra.generate(doc.id, 'What was Q3 revenue?');
33
+ const stream = session.stream('Summarize in 3 bullets');
34
+ for await (const event of stream) {
35
+ if (event.type === 'text_delta') process.stdout.write(event.text);
36
+ }
30
37
  ```
31
38
 
32
- ## Structured Output
33
-
34
- Pass a Zod schema, get typed data back.
39
+ ## Structured Output (Zod)
35
40
 
36
41
  ```ts
37
42
  import { z } from 'zod';
@@ -39,221 +44,140 @@ import { z } from 'zod';
39
44
  const Invoice = z.object({
40
45
  vendor: z.string(),
41
46
  total: z.number(),
42
- lineItems: z.array(z.object({
43
- description: z.string(),
44
- amount: z.number(),
45
- })),
46
47
  });
47
48
 
48
- const result = await okra.generate(doc.id, 'Extract invoice fields', {
49
+ const result = await session.prompt('Extract invoice fields', {
49
50
  schema: Invoice,
50
51
  });
51
- console.log(result.data.vendor); // fully typed
52
- ```
53
-
54
- ## OpenAI-Compatible Endpoint
55
-
56
- Every document becomes an OpenAI-compatible model. Works with any AI SDK.
57
-
58
- ```ts
59
- import { createOpenAI } from '@ai-sdk/openai';
60
- import { generateText, generateObject } from 'ai';
61
-
62
- const provider = createOpenAI({
63
- baseURL: okra.modelEndpoint(doc.id),
64
- apiKey: 'okra_...',
65
- });
66
-
67
- // Vercel AI SDK
68
- const { text } = await generateText({
69
- model: provider('default'),
70
- prompt: 'What was revenue?',
71
- });
72
52
 
73
- // Structured output
74
- const { object } = await generateObject({
75
- model: provider('default'),
76
- schema: Invoice,
77
- prompt: 'Extract invoice fields',
78
- });
53
+ console.log(result.data?.vendor, result.data?.total);
79
54
  ```
80
55
 
81
- Also works with OpenAI SDK directly:
56
+ ## Share Links (Redacted Viewer vs Full Admin)
82
57
 
83
58
  ```ts
84
- import OpenAI from 'openai';
85
-
86
- const openai = new OpenAI({
87
- baseURL: okra.modelEndpoint(doc.id),
88
- apiKey: 'okra_...',
59
+ const viewer = await session.shareLink({
60
+ role: 'viewer',
61
+ expiresInMs: 24 * 60 * 60 * 1000,
89
62
  });
90
63
 
91
- const chat = await openai.chat.completions.create({
92
- model: 'default',
93
- messages: [{ role: 'user', content: 'Summarize' }],
64
+ const admin = await session.shareLink({
65
+ role: 'admin',
66
+ expiresInMs: 24 * 60 * 60 * 1000,
94
67
  });
95
- ```
96
-
97
- ## Streaming
98
68
 
99
- ```ts
100
- for await (const event of okra.stream(doc.id, 'Summarize this document')) {
101
- if (event.type === 'text_delta') process.stdout.write(event.text);
102
- if (event.type === 'done') console.log('\nCost:', event.costUsd);
103
- }
69
+ console.log(viewer.links.markdown, viewer.links.pdf);
70
+ console.log(admin.links.markdown, admin.links.pdf);
104
71
  ```
105
72
 
106
- ## Multi-Document
73
+ ## Deterministic URL Builder
107
74
 
108
75
  ```ts
109
- // Fan-out query across multiple documents
110
- const result = await okra.generate(
111
- ['doc_a', 'doc_b', 'doc_c'],
112
- 'Compare revenue across all filings',
113
- );
114
- ```
115
-
116
- ## URL Builder
117
-
118
- Cloudinary-style — every property is a URL.
119
-
120
- ```tsx
121
76
  import { doc } from '@okrapdf/runtime';
122
77
 
123
- const d = doc('doc_7fK3x', { fileName: 'annual-report.pdf' });
78
+ const d = doc(session.id, { fileName: 'report.pdf' });
124
79
 
125
- <Image src={d.thumbnail.url()} alt="Report cover" />
126
- <Image src={d.pages[3].image.url()} />
127
- <a href={d.entities.tables[0].url({ format: 'csv' })}>Download CSV</a>
80
+ console.log(d.thumbnail.url());
81
+ console.log(d.pages[1].image.url());
82
+ console.log(d.entities.tables[0].url({ format: 'csv' }));
128
83
  ```
129
84
 
130
- When `fileName` is provided, URLs become mime-explicit aliases:
131
- `/.../annual-report_ab12cd.json`, `.../annual-report_ab12cd.png`, `.../annual-report_ab12cd.md`.
85
+ ## curl Contract
132
86
 
133
- `d.thumbnail.url()` follows the same grammar: `/v1/documents/{id}/pages/1/{artifact}.png`.
87
+ The SDK maps directly to these endpoints.
134
88
 
135
- ### Browser Usage (No Node Imports)
89
+ ### 1) Upload URL source
136
90
 
137
- Use the URL-builder-only entrypoint in browser code:
138
-
139
- ```ts
140
- import { doc } from '@okrapdf/runtime/doc';
91
+ ```bash
92
+ curl -X POST "https://api.okrapdf.com/document/ocr-demo/upload-url" \
93
+ -H "Authorization: Bearer $OKRA_API_KEY" \
94
+ -H "Content-Type: application/json" \
95
+ -d '{
96
+ "url": "https://example.com/report.pdf",
97
+ "visibility": "private",
98
+ "redact": {
99
+ "pii": {
100
+ "preset": "hipaa",
101
+ "patterns": ["SSN", "EMAIL", "PHONE_US"]
102
+ }
103
+ }
104
+ }'
141
105
  ```
142
106
 
143
- Or use a CDN module/global:
107
+ ### 2) Wait for readiness
144
108
 
145
- ```html
146
- <script type="module">
147
- import { doc } from 'https://cdn.jsdelivr.net/npm/@okrapdf/runtime/dist/browser.js';
148
- const d = doc('ocr-7fK3x');
149
- console.log(d.pages[1].markdown.url());
150
- </script>
151
- ```
152
-
153
- ```html
154
- <script type="module" src="https://cdn.jsdelivr.net/npm/@okrapdf/runtime/dist/browser.js"></script>
155
- <script>
156
- const d = window.OkraRuntime.doc('ocr-7fK3x');
157
- console.log(d.thumbnail.url());
158
- </script>
109
+ ```bash
110
+ curl "https://api.okrapdf.com/document/ocr-demo/status" \
111
+ -H "Authorization: Bearer $OKRA_API_KEY"
159
112
  ```
160
113
 
161
- ## Provider Transformations
162
-
163
- Same document, different extraction providers — visible in the URL. Like Cloudinary's `/w_300/image.jpg`, OkraPDF uses `/t_{provider}/` to select the extraction source.
164
-
165
- ```ts
166
- import { doc } from '@okrapdf/runtime';
167
-
168
- const d = doc('doc_7fK3x', { provider: 'llamaparse' });
169
-
170
- d.pages[1].markdown.url()
171
- // → /v1/documents/doc_7fK3x/t_llamaparse/pages/1/markdown
172
-
173
- d.entities.tables.url({ format: 'csv' })
174
- // → /v1/documents/doc_7fK3x/t_llamaparse/entities/tables?format=csv
175
- ```
114
+ Poll until `phase` is `complete` (or `awaiting_review`).
176
115
 
177
- Compare providers side-by-side:
116
+ ### 3) Ask a question
178
117
 
179
- ```ts
180
- const d = doc('doc_7fK3x');
181
-
182
- // Same page, different providers, different output formats
183
- d.pages[1].url() // default provider
184
- d.url({ provider: 'googleocr', format: 'json' }) // Google DocAI → JSON blocks
185
- d.url({ provider: 'llamaparse', format: 'markdown' }) // LlamaParse → markdown
186
- d.url({ provider: 'unstructured', format: 'html' }) // Unstructured → HTML (canonical)
187
- d.url({ provider: 'docling', format: 'markdown' }) // Docling → markdown
118
+ ```bash
119
+ curl -X POST "https://api.okrapdf.com/document/ocr-demo/completion" \
120
+ -H "Authorization: Bearer $OKRA_API_KEY" \
121
+ -H "Content-Type: application/json" \
122
+ -d '{
123
+ "prompt": "What is total revenue?",
124
+ "model": "kimi-k2p5"
125
+ }'
188
126
  ```
189
127
 
190
- ## Provider Abstraction
191
-
192
- AI SDK-style vendor switching:
128
+ ### 4) Stream tokens
193
129
 
194
- ```ts
195
- import { createOkra } from '@okrapdf/runtime';
196
-
197
- const okra = createOkra({
198
- apiKey: 'okra_...',
199
- providers: { azureDocAI, llamaparse },
200
- extraction: { ocr: 'azureDocAI', enhance: 'llamaparse' },
201
- });
130
+ ```bash
131
+ curl -N -X POST "https://api.okrapdf.com/document/ocr-demo/completion" \
132
+ -H "Authorization: Bearer $OKRA_API_KEY" \
133
+ -H "Content-Type: application/json" \
134
+ -d '{
135
+ "prompt": "Summarize in 3 bullets",
136
+ "stream": true,
137
+ "model": "kimi-k2p5"
138
+ }'
202
139
  ```
203
140
 
204
- ## curl Equivalents
141
+ ### 5) Create scoped share links
205
142
 
206
143
  ```bash
207
- # Upload
208
- curl -X POST https://api.okrapdf.com/document/my-doc/upload \
209
- -H "Authorization: Bearer okra_..." \
210
- -H "Content-Type: application/pdf" \
211
- --data-binary @report.pdf
212
-
213
- # Status
214
- curl https://api.okrapdf.com/document/my-doc/status \
215
- -H "Authorization: Bearer okra_..."
216
-
217
- # Pages
218
- curl https://api.okrapdf.com/document/my-doc/pages \
219
- -H "Authorization: Bearer okra_..."
220
-
221
- # Completion
222
- curl -X POST https://api.okrapdf.com/document/my-doc/completion \
223
- -H "Authorization: Bearer okra_..." \
144
+ curl -X POST "https://api.okrapdf.com/document/ocr-demo/share-link" \
145
+ -H "Authorization: Bearer $OKRA_API_KEY" \
224
146
  -H "Content-Type: application/json" \
225
- -d '{"prompt": "What was revenue?"}'
147
+ -d '{
148
+ "role": "viewer",
149
+ "expiresInMs": 86400000
150
+ }'
226
151
  ```
227
152
 
228
- ## Full API
153
+ Use `role: "admin"` for full-access links.
229
154
 
230
- ```
231
- upload(path | url | buffer) Upload a document
232
- wait(id) Poll until extraction complete
233
- status(id) Check processing status
234
- pages(id) Get all pages as markdown
235
- page(id, num) Get single page
236
- entities(id, { type }) Get extracted entities (tables, figures, etc.)
237
- query(id, sql) Run SQL against document SQLite
238
- generate(id, prompt) AI Q&A (non-streaming)
239
- generate(id, prompt, { schema }) Structured output with Zod/JSON schema
240
- stream(id, prompt) Streaming completion
241
- modelEndpoint(id) OpenAI-compatible base URL
242
- publish(id) Make document publicly accessible
243
- shareLink(id, options) Generate share link with permissions
244
- deploy(ids) Create multi-document agent
245
- ```
246
-
247
- ## Self-Host
155
+ ## Public API
248
156
 
249
157
  ```ts
250
- import { handleRequest } from '@okrapdf/runtime/worker';
251
-
252
- export default { fetch: handleRequest(env) };
158
+ createOkra({ apiKey, baseUrl?, sharedSecret?, fetch? }) => okra
159
+
160
+ okra.sessions.create(sourceOrDocId, { wait?, model?, upload?, waitOptions? }) => session
161
+ okra.sessions.from(docId, { model? }) => session
162
+
163
+ session.id
164
+ session.model
165
+ session.modelEndpoint
166
+ session.state()
167
+ session.setModel(model)
168
+ session.status()
169
+ session.wait()
170
+ session.pages()
171
+ session.page(n)
172
+ session.entities()
173
+ session.query(sql)
174
+ session.prompt(query)
175
+ session.prompt(query, { schema })
176
+ session.stream(query)
177
+ session.publish()
178
+ session.shareLink({ role, expiresInMs, maxViews, label })
253
179
  ```
254
180
 
255
- Same SDK, same code. Only `baseUrl` changes.
256
-
257
181
  ## License
258
182
 
259
183
  MIT
package/dist/client.d.ts CHANGED
@@ -1,11 +1,15 @@
1
- import type { CompletionEvent, CompletionOptions, DeployOptions, DeployResult, DocumentStatus, EntitiesResponse, GenerateOptions, GenerateResult, OkraOptions, Page, PublishResult, QueryResult, ShareLinkOptions, ShareLinkResult, StructuredSchema, UploadOptions, UploadResult, WaitOptions } from './types.js';
1
+ import type { CreateOkraOptions, CompletionEvent, CompletionOptions, DeployOptions, DeployResult, DocumentStatus, EntitiesResponse, GenerateOptions, GenerateResult, OkraJob, OkraOptions, OkraRuntime, Page, PublishResult, QueryResult, ShareLinkOptions, ShareLinkResult, SessionAttachOptions, SessionCreateOptions, OkraSession, StructuredSchema, UploadInput, UploadOptions, WaitOptions } from './types.js';
2
2
  export declare class OkraClient {
3
3
  private readonly baseUrl;
4
4
  private readonly apiKey?;
5
5
  private readonly sharedSecret?;
6
6
  private readonly fetchImpl;
7
+ readonly sessions: {
8
+ create: (sourceOrDocId: UploadInput, options?: SessionCreateOptions) => Promise<OkraSession>;
9
+ from: (documentId: string, options?: SessionAttachOptions) => OkraSession;
10
+ };
7
11
  constructor(options: OkraOptions);
8
- upload(input: string | ArrayBuffer | Uint8Array, options?: UploadOptions): Promise<UploadResult>;
12
+ upload(input: UploadInput, options?: UploadOptions): Promise<OkraJob>;
9
13
  status(documentId: string, signal?: AbortSignal): Promise<DocumentStatus>;
10
14
  wait(documentId: string, options?: WaitOptions): Promise<DocumentStatus>;
11
15
  pages(documentId: string, options?: {
@@ -37,4 +41,5 @@ export declare class OkraClient {
37
41
  private requestJson;
38
42
  private parseBody;
39
43
  }
44
+ export declare function createOkra(options: CreateOkraOptions): OkraRuntime;
40
45
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}