graphor 0.4.2 → 0.5.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 CHANGED
@@ -1,403 +1,427 @@
1
- # Graphor Prd TypeScript API Library
1
+ # Graphor TypeScript SDK
2
2
 
3
- [![NPM version](<https://img.shields.io/npm/v/graphor.svg?label=npm%20(stable)>)](https://npmjs.org/package/graphor) ![npm bundle size](https://img.shields.io/bundlephobia/minzip/graphor)
3
+ [![NPM version](https://img.shields.io/npm/v/graphor.svg?label=npm%20(stable))](https://npmjs.org/package/graphor)
4
+ [![TypeScript](https://img.shields.io/badge/TypeScript-4.9+-blue.svg)](https://www.typescriptlang.org/)
4
5
 
5
- This library provides convenient access to the Graphor Prd REST API from server-side TypeScript or JavaScript.
6
+ The official TypeScript SDK for the [Graphor](https://graphorlm.com) API. Build intelligent document applications with ease.
6
7
 
7
- The full API of this library can be found in [api.md](api.md).
8
-
9
- It is generated with [Stainless](https://www.stainless.com/).
8
+ **Features:**
9
+ - 📄 **Document Ingestion** — Upload files, web pages, GitHub repos, and YouTube videos
10
+ - 💬 **Document Chat** — Ask questions with conversational memory
11
+ - 📊 **Structured Extraction** — Extract data using JSON Schema
12
+ - 🔍 **Semantic Search** — Retrieve relevant chunks for custom RAG pipelines
13
+ - 🔒 **Type Safety** — Complete TypeScript definitions for all params and responses
14
+ - 🌐 **Multi-Runtime** — Works in Node.js, Deno, Bun, and browsers
10
15
 
11
16
  ## MCP Server
12
17
 
13
- Use the Graphor Prd MCP Server to enable AI assistants to interact with this API, allowing them to explore endpoints, make test requests, and use documentation to help integrate this SDK into your application.
18
+ Use the Graphor MCP Server to enable AI assistants to interact with this API, allowing them to explore endpoints, make test requests, and use documentation to help integrate this SDK into your application.
14
19
 
15
- [![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=graphor-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsImdyYXBob3ItbWNwIl0sImVudiI6eyJHUkFQSE9SX1BSRF9BUElfS0VZIjoiTXkgQVBJIEtleSJ9fQ)
16
- [![Install in VS Code](https://img.shields.io/badge/_-Add_to_VS_Code-blue?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHBhdGggZmlsbD0iI0VFRSIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMzAuMjM1IDM5Ljg4NGEyLjQ5MSAyLjQ5MSAwIDAgMS0xLjc4MS0uNzNMMTIuNyAyNC43OGwtMy40NiAyLjYyNC0zLjQwNiAyLjU4MmExLjY2NSAxLjY2NSAwIDAgMS0xLjA4Mi4zMzggMS42NjQgMS42NjQgMCAwIDEtMS4wNDYtLjQzMWwtMi4yLTJhMS42NjYgMS42NjYgMCAwIDEgMC0yLjQ2M0w3LjQ1OCAyMCA0LjY3IDE3LjQ1MyAxLjUwNyAxNC41N2ExLjY2NSAxLjY2NSAwIDAgMSAwLTIuNDYzbDIuMi0yYTEuNjY1IDEuNjY1IDAgMCAxIDIuMTMtLjA5N2w2Ljg2MyA1LjIwOUwyOC40NTIuODQ0YTIuNDg4IDIuNDg4IDAgMCAxIDEuODQxLS43MjljLjM1MS4wMDkuNjk5LjA5MSAxLjAxOS4yNDVsOC4yMzYgMy45NjFhMi41IDIuNSAwIDAgMSAxLjQxNSAyLjI1M3YuMDk5LS4wNDVWMzMuMzd2LS4wNDUuMDk1YTIuNTAxIDIuNTAxIDAgMCAxLTEuNDE2IDIuMjU3bC04LjIzNSAzLjk2MWEyLjQ5MiAyLjQ5MiAwIDAgMS0xLjA3Ny4yNDZabS43MTYtMjguOTQ3LTExLjk0OCA5LjA2MiAxMS45NTIgOS4wNjUtLjAwNC0xOC4xMjdaIi8+PC9zdmc+)](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22graphor-mcp%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22graphor-mcp%22%5D%2C%22env%22%3A%7B%22GRAPHOR_PRD_API_KEY%22%3A%22My%20API%20Key%22%7D%7D)
20
+ [![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=graphor-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsImdyYXBob3ItbWNwIl0sImVudiI6eyJHUkFQSE9SX0FQSV9LRVkiOiJNeSBBUEkgS2V5In19)
21
+ [![Install in VS Code](https://img.shields.io/badge/_-Add_to_VS_Code-blue?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHBhdGggZmlsbD0iI0VFRSIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMzAuMjM1IDM5Ljg4NGEyLjQ5MSAyLjQ5MSAwIDAgMS0xLjc4MS0uNzNMMTIuNyAyNC43OGwtMy40NiAyLjYyNC0zLjQwNiAyLjU4MmExLjY2NSAxLjY2NSAwIDAgMS0xLjA4Mi4zMzggMS42NjQgMS42NjQgMCAwIDEtMS4wNDYtLjQzMWwtMi4yLTJhMS42NjYgMS42NjYgMCAwIDEgMC0yLjQ2M0w3LjQ1OCAyMCA0LjY3IDE3LjQ1MyAxLjUwNyAxNC41N2ExLjY2NSAxLjY2NSAwIDAgMSAwLTIuNDYzbDIuMi0yYTEuNjY1IDEuNjY1IDAgMCAxIDIuMTMtLjA5N2w2Ljg2MyA1LjIwOUwyOC40NTIuODQ0YTIuNDg4IDIuNDg4IDAgMCAxIDEuODQxLS43MjljLjM1MS4wMDkuNjk5LjA5MSAxLjAxOS4yNDVsOC4yMzYgMy45NjFhMi41IDIuNSAwIDAgMSAxLjQxNSAyLjI1M3YuMDk5LS4wNDVWMzMuMzd2LS4wNDUuMDk1YTIuNTAxIDIuNTAxIDAgMCAxLTEuNDE2IDIuMjU3bC04LjIzNSAzLjk2MWEyLjQ5MiAyLjQ5MiAwIDAgMS0xLjA3Ny4yNDZabS43MTYtMjguOTQ3LTExLjk0OCA5LjA2MiAxMS45NTIgOS4wNjUtLjAwNC0xOC4xMjdaIi8+PC9zdmc+)](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22graphor-mcp%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22graphor-mcp%22%5D%2C%22env%22%3A%7B%22GRAPHOR_API_KEY%22%3A%22My%20API%20Key%22%7D%7D)
17
22
 
18
23
  > Note: You may need to set environment variables in your MCP client.
19
24
 
25
+ ## Documentation
26
+
27
+ 📚 **Full documentation**: [docs.graphorlm.com/sdk/overview](https://docs.graphorlm.com/sdk/overview)
28
+
20
29
  ## Installation
21
30
 
22
- ```sh
31
+ ```bash
23
32
  npm install graphor
24
33
  ```
25
34
 
26
- ## Usage
35
+ Or with your preferred package manager:
27
36
 
28
- The full API of this library can be found in [api.md](api.md).
37
+ ```bash
38
+ yarn add graphor
39
+ pnpm add graphor
40
+ ```
29
41
 
30
- <!-- prettier-ignore -->
31
- ```js
32
- import GraphorPrd from 'graphor';
42
+ ## Quick Start
33
43
 
34
- const client = new GraphorPrd({
35
- apiKey: process.env['GRAPHOR_PRD_API_KEY'], // This is the default and can be omitted
36
- });
44
+ ```typescript
45
+ import Graphor from 'graphor';
46
+ import fs from 'fs';
47
+
48
+ const client = new Graphor(); // Uses GRAPHOR_API_KEY env var
37
49
 
38
- const publicSource = await client.sources.upload({ file: fs.createReadStream('path/to/file') });
50
+ // Upload a document
51
+ const source = await client.sources.upload({ file: fs.createReadStream('document.pdf') });
52
+ console.log(`Uploaded: ${source.file_name}`);
39
53
 
40
- console.log(publicSource.project_id);
54
+ // Ask questions about your documents
55
+ const response = await client.sources.ask({ question: 'What are the main topics?' });
56
+ console.log(`Answer: ${response.answer}`);
41
57
  ```
42
58
 
43
- ### Request & Response types
59
+ ## Authentication
44
60
 
45
- This library includes TypeScript definitions for all request params and response fields. You may import and use them like so:
61
+ Set your API key as an environment variable (recommended):
46
62
 
47
- <!-- prettier-ignore -->
48
- ```ts
49
- import GraphorPrd from 'graphor';
63
+ ```bash
64
+ export GRAPHOR_API_KEY="grlm_your_api_key_here"
65
+ ```
50
66
 
51
- const client = new GraphorPrd({
52
- apiKey: process.env['GRAPHOR_PRD_API_KEY'], // This is the default and can be omitted
53
- });
67
+ ```typescript
68
+ import Graphor from 'graphor';
54
69
 
55
- const params: GraphorPrd.SourceUploadParams = { file: fs.createReadStream('path/to/file') };
56
- const publicSource: GraphorPrd.PublicSource = await client.sources.upload(params);
70
+ const client = new Graphor(); // Automatically uses GRAPHOR_API_KEY
57
71
  ```
58
72
 
59
- Documentation for each method, request param, and response field are available in docstrings and will appear on hover in most modern editors.
73
+ Or pass it directly:
60
74
 
61
- ## File uploads
75
+ ```typescript
76
+ const client = new Graphor({ apiKey: 'grlm_your_api_key_here' });
77
+ ```
62
78
 
63
- Request parameters that correspond to file uploads can be passed in many different forms:
79
+ ## Core Features
80
+
81
+ ### 📄 Upload Documents
64
82
 
65
- - `File` (or an object with the same structure)
66
- - a `fetch` `Response` (or an object with the same structure)
67
- - an `fs.ReadStream`
68
- - the return value of our `toFile` helper
83
+ Upload files, web pages, GitHub repositories, or YouTube videos:
69
84
 
70
- ```ts
85
+ ```typescript
86
+ import Graphor from 'graphor';
71
87
  import fs from 'fs';
72
- import GraphorPrd, { toFile } from 'graphor';
73
88
 
74
- const client = new GraphorPrd();
89
+ const client = new Graphor();
75
90
 
76
- // If you have access to Node `fs` we recommend using `fs.createReadStream()`:
77
- await client.sources.upload({ file: fs.createReadStream('/path/to/file') });
91
+ // Upload a local file
92
+ const source = await client.sources.upload({ file: fs.createReadStream('report.pdf') });
78
93
 
79
- // Or if you have the web `File` API you can pass a `File` instance:
80
- await client.sources.upload({ file: new File(['my bytes'], 'file') });
94
+ // Upload from URL
95
+ const urlSource = await client.sources.uploadUrl({ url: 'https://example.com/article' });
81
96
 
82
- // You can also pass a `fetch` `Response`:
83
- await client.sources.upload({ file: await fetch('https://somesite/file') });
84
-
85
- // Finally, if none of the above are convenient, you can use our `toFile` helper:
86
- await client.sources.upload({ file: await toFile(Buffer.from('my bytes'), 'file') });
87
- await client.sources.upload({ file: await toFile(new Uint8Array([0, 1, 2]), 'file') });
88
- ```
97
+ // Upload from GitHub
98
+ const githubSource = await client.sources.uploadGithub({ url: 'https://github.com/org/repo' });
89
99
 
90
- ## Handling errors
91
-
92
- When the library is unable to connect to the API,
93
- or if the API returns a non-success status code (i.e., 4xx or 5xx response),
94
- a subclass of `APIError` will be thrown:
95
-
96
- <!-- prettier-ignore -->
97
- ```ts
98
- const publicSource = await client.sources
99
- .upload({ file: fs.createReadStream('path/to/file') })
100
- .catch(async (err) => {
101
- if (err instanceof GraphorPrd.APIError) {
102
- console.log(err.status); // 400
103
- console.log(err.name); // BadRequestError
104
- console.log(err.headers); // {server: 'nginx', ...}
105
- } else {
106
- throw err;
107
- }
108
- });
100
+ // Upload from YouTube
101
+ const youtubeSource = await client.sources.uploadYoutube({ url: 'https://youtube.com/watch?v=...' });
109
102
  ```
110
103
 
111
- Error codes are as follows:
112
-
113
- | Status Code | Error Type |
114
- | ----------- | -------------------------- |
115
- | 400 | `BadRequestError` |
116
- | 401 | `AuthenticationError` |
117
- | 403 | `PermissionDeniedError` |
118
- | 404 | `NotFoundError` |
119
- | 422 | `UnprocessableEntityError` |
120
- | 429 | `RateLimitError` |
121
- | >=500 | `InternalServerError` |
122
- | N/A | `APIConnectionError` |
104
+ **Supported formats:** PDF, DOCX, TXT, MD, HTML, CSV, XLSX, PNG, JPG, MP3, MP4, and more.
123
105
 
124
- ### Retries
106
+ 📖 [Full upload documentation](https://docs.graphorlm.com/sdk/sources/upload)
125
107
 
126
- Certain errors will be automatically retried 2 times by default, with a short exponential backoff.
127
- Connection errors (for example, due to a network connectivity problem), 408 Request Timeout, 409 Conflict,
128
- 429 Rate Limit, and >=500 Internal errors will all be retried by default.
108
+ ### ⚙️ Process Documents
129
109
 
130
- You can use the `maxRetries` option to configure or disable this:
131
-
132
- <!-- prettier-ignore -->
133
- ```js
134
- // Configure the default for all requests:
135
- const client = new GraphorPrd({
136
- maxRetries: 0, // default is 2
137
- });
110
+ Reprocess documents with different OCR/parsing methods:
138
111
 
139
- // Or, configure per-request:
140
- await client.sources.upload({ file: fs.createReadStream('path/to/file') }, {
141
- maxRetries: 5,
112
+ ```typescript
113
+ // Reprocess with high-resolution parsing
114
+ const source = await client.sources.parse({
115
+ file_name: 'document.pdf',
116
+ partition_method: 'hi_res' // Options: basic, hi_res, hi_res_ft, mai, graphorlm
142
117
  });
143
118
  ```
144
119
 
145
- ### Timeouts
120
+ 📖 [Full processing documentation](https://docs.graphorlm.com/sdk/sources/process)
121
+
122
+ ### 💬 Chat with Documents
146
123
 
147
- Requests time out after 1 minute by default. You can configure this with a `timeout` option:
124
+ Ask questions about your documents with conversational memory:
148
125
 
149
- <!-- prettier-ignore -->
150
- ```ts
151
- // Configure the default for all requests:
152
- const client = new GraphorPrd({
153
- timeout: 20 * 1000, // 20 seconds (default is 1 minute)
126
+ ```typescript
127
+ // Ask a question
128
+ const response = await client.sources.ask({
129
+ question: 'What are the key findings?'
154
130
  });
131
+ console.log(response.answer);
155
132
 
156
- // Override per-request:
157
- await client.sources.upload({ file: fs.createReadStream('path/to/file') }, {
158
- timeout: 5 * 1000,
133
+ // Follow-up question (maintains context)
134
+ const followUp = await client.sources.ask({
135
+ question: 'Can you elaborate on the first point?',
136
+ conversation_id: response.conversation_id
159
137
  });
160
- ```
138
+ console.log(followUp.answer);
161
139
 
162
- On timeout, an `APIConnectionTimeoutError` is thrown.
140
+ // Scope to specific documents
141
+ const scopedResponse = await client.sources.ask({
142
+ question: 'Compare these two reports',
143
+ file_names: ['report-2023.pdf', 'report-2024.pdf']
144
+ });
145
+ ```
163
146
 
164
- Note that requests which time out will be [retried twice by default](#retries).
147
+ 📖 [Full chat documentation](https://docs.graphorlm.com/sdk/chat)
148
+
149
+ ### 📊 Extract Structured Data
150
+
151
+ Extract structured information using JSON Schema:
152
+
153
+ ```typescript
154
+ const result = await client.sources.extract({
155
+ file_names: ['invoice.pdf'],
156
+ user_instruction: 'Extract invoice details',
157
+ output_schema: {
158
+ type: 'object',
159
+ properties: {
160
+ invoice_number: { type: 'string' },
161
+ total_amount: { type: 'number' },
162
+ line_items: {
163
+ type: 'array',
164
+ items: {
165
+ type: 'object',
166
+ properties: {
167
+ description: { type: 'string' },
168
+ amount: { type: 'number' }
169
+ }
170
+ }
171
+ }
172
+ }
173
+ }
174
+ });
165
175
 
166
- ## Advanced Usage
176
+ console.log(result.structured_output);
177
+ // { invoice_number: "INV-001", total_amount: 1500.00, line_items: [...] }
178
+ ```
167
179
 
168
- ### Accessing raw Response data (e.g., headers)
180
+ 📖 [Full extraction documentation](https://docs.graphorlm.com/sdk/extract)
169
181
 
170
- The "raw" `Response` returned by `fetch()` can be accessed through the `.asResponse()` method on the `APIPromise` type that all methods return.
171
- This method returns as soon as the headers for a successful response are received and does not consume the response body, so you are free to write custom parsing or streaming logic.
182
+ ### 🔍 Retrieve Chunks (Prebuilt RAG)
172
183
 
173
- You can also use the `.withResponse()` method to get the raw `Response` along with the parsed data.
174
- Unlike `.asResponse()` this method consumes the body, returning once it is parsed.
184
+ Build custom RAG pipelines with semantic search:
175
185
 
176
- <!-- prettier-ignore -->
177
- ```ts
178
- const client = new GraphorPrd();
186
+ ```typescript
187
+ // Retrieve relevant chunks
188
+ const result = await client.sources.retrieveChunks({
189
+ query: 'What are the payment terms?'
190
+ });
179
191
 
180
- const response = await client.sources
181
- .upload({ file: fs.createReadStream('path/to/file') })
182
- .asResponse();
183
- console.log(response.headers.get('X-My-Header'));
184
- console.log(response.statusText); // access the underlying Response object
192
+ for (const chunk of result.chunks) {
193
+ console.log(`[${chunk.file_name}, Page ${chunk.page_number}]`);
194
+ console.log(`Score: ${chunk.score.toFixed(2)}`);
195
+ console.log(chunk.text);
196
+ console.log('---');
197
+ }
185
198
 
186
- const { data: publicSource, response: raw } = await client.sources
187
- .upload({ file: fs.createReadStream('path/to/file') })
188
- .withResponse();
189
- console.log(raw.headers.get('X-My-Header'));
190
- console.log(publicSource.project_id);
199
+ // Use with your preferred LLM
200
+ const context = result.chunks.map(c => c.text).join('\n');
201
+ // Pass context to OpenAI, Anthropic, etc.
191
202
  ```
192
203
 
193
- ### Logging
194
-
195
- > [!IMPORTANT]
196
- > All log messages are intended for debugging only. The format and content of log messages
197
- > may change between releases.
204
+ 📖 [Full RAG documentation](https://docs.graphorlm.com/sdk/prebuilt-rag)
198
205
 
199
- #### Log levels
206
+ ### 📋 Manage Sources
200
207
 
201
- The log level can be configured in two ways:
208
+ List, inspect, and delete documents:
202
209
 
203
- 1. Via the `GRAPHOR_PRD_LOG` environment variable
204
- 2. Using the `logLevel` client option (overrides the environment variable if set)
210
+ ```typescript
211
+ // List all sources
212
+ const sources = await client.sources.list();
213
+ for (const source of sources) {
214
+ console.log(`${source.file_name}: ${source.status}`);
215
+ }
205
216
 
206
- ```ts
207
- import GraphorPrd from 'graphor';
208
-
209
- const client = new GraphorPrd({
210
- logLevel: 'debug', // Show all log messages
217
+ // Get document elements
218
+ const elements = await client.sources.loadElements({
219
+ file_name: 'document.pdf',
220
+ page: 1,
221
+ page_size: 50
211
222
  });
212
- ```
213
223
 
214
- Available log levels, from most to least verbose:
224
+ // Delete a source
225
+ const result = await client.sources.delete({ file_name: 'document.pdf' });
226
+ ```
215
227
 
216
- - `'debug'` - Show debug messages, info, warnings, and errors
217
- - `'info'` - Show info messages, warnings, and errors
218
- - `'warn'` - Show warnings and errors (default)
219
- - `'error'` - Show only errors
220
- - `'off'` - Disable all logging
228
+ ## File Uploads
221
229
 
222
- At the `'debug'` level, all HTTP requests and responses are logged, including headers and bodies.
223
- Some authentication-related headers are redacted, but sensitive data in request and response bodies
224
- may still be visible.
230
+ Request parameters that correspond to file uploads can be passed in many different forms:
225
231
 
226
- #### Custom logger
232
+ ```typescript
233
+ import fs from 'fs';
234
+ import Graphor, { toFile } from 'graphor';
227
235
 
228
- By default, this library logs to `globalThis.console`. You can also provide a custom logger.
229
- Most logging libraries are supported, including [pino](https://www.npmjs.com/package/pino), [winston](https://www.npmjs.com/package/winston), [bunyan](https://www.npmjs.com/package/bunyan), [consola](https://www.npmjs.com/package/consola), [signale](https://www.npmjs.com/package/signale), and [@std/log](https://jsr.io/@std/log). If your logger doesn't work, please open an issue.
236
+ const client = new Graphor();
230
237
 
231
- When providing a custom logger, the `logLevel` option still controls which messages are emitted, messages
232
- below the configured level will not be sent to your logger.
238
+ // Using fs.createReadStream (Node.js)
239
+ await client.sources.upload({ file: fs.createReadStream('/path/to/file') });
233
240
 
234
- ```ts
235
- import GraphorPrd from 'graphor';
236
- import pino from 'pino';
241
+ // Using File API (browsers)
242
+ await client.sources.upload({ file: new File(['my bytes'], 'file') });
237
243
 
238
- const logger = pino();
244
+ // Using fetch Response
245
+ await client.sources.upload({ file: await fetch('https://somesite/file') });
239
246
 
240
- const client = new GraphorPrd({
241
- logger: logger.child({ name: 'GraphorPrd' }),
242
- logLevel: 'debug', // Send all messages to pino, allowing it to filter
243
- });
247
+ // Using toFile helper
248
+ await client.sources.upload({ file: await toFile(Buffer.from('my bytes'), 'file') });
244
249
  ```
245
250
 
246
- ### Making custom/undocumented requests
247
-
248
- This library is typed for convenient access to the documented API. If you need to access undocumented
249
- endpoints, params, or response properties, the library can still be used.
250
-
251
- #### Undocumented endpoints
252
-
253
- To make requests to undocumented endpoints, you can use `client.get`, `client.post`, and other HTTP verbs.
254
- Options on the client, such as retries, will be respected when making these requests.
255
-
256
- ```ts
257
- await client.post('/some/path', {
258
- body: { some_prop: 'foo' },
259
- query: { some_query_arg: 'bar' },
260
- });
251
+ ## Error Handling
252
+
253
+ ```typescript
254
+ import Graphor from 'graphor';
255
+
256
+ const client = new Graphor();
257
+
258
+ try {
259
+ const response = await client.sources.ask({ question: 'What is this about?' });
260
+ } catch (err) {
261
+ if (err instanceof Graphor.BadRequestError) {
262
+ console.log('Bad request');
263
+ } else if (err instanceof Graphor.AuthenticationError) {
264
+ console.log('Invalid API key');
265
+ } else if (err instanceof Graphor.NotFoundError) {
266
+ console.log('Resource not found');
267
+ } else if (err instanceof Graphor.RateLimitError) {
268
+ console.log('Rate limited - back off and retry');
269
+ } else if (err instanceof Graphor.APIConnectionError) {
270
+ console.log('Network error');
271
+ } else if (err instanceof Graphor.APIError) {
272
+ console.log(`API error: ${err.status}`);
273
+ } else {
274
+ throw err;
275
+ }
276
+ }
261
277
  ```
262
278
 
263
- #### Undocumented request params
264
-
265
- To make requests using undocumented parameters, you may use `// @ts-expect-error` on the undocumented
266
- parameter. This library doesn't validate at runtime that the request matches the type, so any extra values you
267
- send will be sent as-is.
268
-
269
- ```ts
270
- client.sources.upload({
271
- // ...
272
- // @ts-expect-error baz is not yet public
273
- baz: 'undocumented option',
274
- });
275
- ```
279
+ | Status Code | Error Type |
280
+ |-------------|------------|
281
+ | 400 | `BadRequestError` |
282
+ | 401 | `AuthenticationError` |
283
+ | 403 | `PermissionDeniedError` |
284
+ | 404 | `NotFoundError` |
285
+ | 422 | `UnprocessableEntityError` |
286
+ | 429 | `RateLimitError` |
287
+ | ≥500 | `InternalServerError` |
288
+ | N/A | `APIConnectionError` |
276
289
 
277
- For requests with the `GET` verb, any extra params will be in the query, all other requests will send the
278
- extra param in the body.
290
+ ## Configuration
279
291
 
280
- If you want to explicitly send an extra argument, you can do so with the `query`, `body`, and `headers` request
281
- options.
292
+ ### Retries
282
293
 
283
- #### Undocumented response properties
294
+ Requests are automatically retried twice with exponential backoff:
284
295
 
285
- To access undocumented response properties, you may access the response object with `// @ts-expect-error` on
286
- the response object, or cast the response object to the requisite type. Like the request params, we do not
287
- validate or strip extra properties from the response from the API.
296
+ ```typescript
297
+ // Configure default retries
298
+ const client = new Graphor({ maxRetries: 5 });
288
299
 
289
- ### Customizing the fetch client
300
+ // Or per-request
301
+ await client.sources.ask({ question: '...' }, { maxRetries: 3 });
302
+ ```
290
303
 
291
- By default, this library expects a global `fetch` function is defined.
304
+ ### Timeouts
292
305
 
293
- If you want to use a different `fetch` function, you can either polyfill the global:
306
+ Default timeout is 60 seconds:
294
307
 
295
- ```ts
296
- import fetch from 'my-fetch';
308
+ ```typescript
309
+ // Configure default timeout (in milliseconds)
310
+ const client = new Graphor({ timeout: 120 * 1000 });
297
311
 
298
- globalThis.fetch = fetch;
312
+ // Or per-request
313
+ await client.sources.parse(
314
+ { file_name: 'large-document.pdf', partition_method: 'graphorlm' },
315
+ { timeout: 300 * 1000 }
316
+ );
299
317
  ```
300
318
 
301
- Or pass it to the client:
302
-
303
- ```ts
304
- import GraphorPrd from 'graphor';
305
- import fetch from 'my-fetch';
319
+ ## Complete Example
306
320
 
307
- const client = new GraphorPrd({ fetch });
308
- ```
309
-
310
- ### Fetch options
321
+ ```typescript
322
+ import Graphor from 'graphor';
323
+ import fs from 'fs';
311
324
 
312
- If you want to set custom `fetch` options without overriding the `fetch` function, you can provide a `fetchOptions` object when instantiating the client or making a request. (Request-specific options override client options.)
325
+ const client = new Graphor();
313
326
 
314
- ```ts
315
- import GraphorPrd from 'graphor';
327
+ // 1. Upload a document
328
+ const source = await client.sources.upload({ file: fs.createReadStream('contract.pdf') });
329
+ console.log(`✅ Uploaded: ${source.file_name}`);
316
330
 
317
- const client = new GraphorPrd({
318
- fetchOptions: {
319
- // `RequestInit` options
320
- },
331
+ // 2. Process with advanced parsing
332
+ const processed = await client.sources.parse({
333
+ file_name: source.file_name,
334
+ partition_method: 'hi_res'
321
335
  });
322
- ```
323
-
324
- #### Configuring proxies
336
+ console.log(`✅ Processed: ${processed.status}`);
325
337
 
326
- To modify proxy behavior, you can provide custom `fetchOptions` that add runtime-specific proxy
327
- options to requests:
328
-
329
- <img src="https://raw.githubusercontent.com/stainless-api/sdk-assets/refs/heads/main/node.svg" align="top" width="18" height="21"> **Node** <sup>[[docs](https://github.com/nodejs/undici/blob/main/docs/docs/api/ProxyAgent.md#example---proxyagent-with-fetch)]</sup>
330
-
331
- ```ts
332
- import GraphorPrd from 'graphor';
333
- import * as undici from 'undici';
338
+ // 3. Ask questions
339
+ const response = await client.sources.ask({
340
+ question: 'What are the key terms of this contract?',
341
+ file_names: [source.file_name]
342
+ });
343
+ console.log(`📝 Answer: ${response.answer}`);
344
+
345
+ // 4. Extract structured data
346
+ const extracted = await client.sources.extract({
347
+ file_names: [source.file_name],
348
+ user_instruction: 'Extract contract details',
349
+ output_schema: {
350
+ type: 'object',
351
+ properties: {
352
+ parties: { type: 'array', items: { type: 'string' } },
353
+ effective_date: { type: 'string' },
354
+ termination_date: { type: 'string' },
355
+ total_value: { type: 'number' }
356
+ }
357
+ }
358
+ });
359
+ console.log(`📊 Extracted: ${JSON.stringify(extracted.structured_output)}`);
334
360
 
335
- const proxyAgent = new undici.ProxyAgent('http://localhost:8888');
336
- const client = new GraphorPrd({
337
- fetchOptions: {
338
- dispatcher: proxyAgent,
339
- },
361
+ // 5. Build custom RAG
362
+ const chunks = await client.sources.retrieveChunks({
363
+ query: 'payment obligations',
364
+ file_names: [source.file_name]
340
365
  });
366
+ console.log(`🔍 Found ${chunks.total} relevant chunks`);
341
367
  ```
342
368
 
343
- <img src="https://raw.githubusercontent.com/stainless-api/sdk-assets/refs/heads/main/bun.svg" align="top" width="18" height="21"> **Bun** <sup>[[docs](https://bun.sh/guides/http/proxy)]</sup>
369
+ ## API Reference
344
370
 
345
- ```ts
346
- import GraphorPrd from 'graphor';
371
+ ### Sources
347
372
 
348
- const client = new GraphorPrd({
349
- fetchOptions: {
350
- proxy: 'http://localhost:8888',
351
- },
352
- });
353
- ```
354
-
355
- <img src="https://raw.githubusercontent.com/stainless-api/sdk-assets/refs/heads/main/deno.svg" align="top" width="18" height="21"> **Deno** <sup>[[docs](https://docs.deno.com/api/deno/~/Deno.createHttpClient)]</sup>
373
+ | Method | Description | Docs |
374
+ |--------|-------------|------|
375
+ | `sources.upload()` | Upload a local file | [📖](https://docs.graphorlm.com/sdk/sources/upload#upload-a-file) |
376
+ | `sources.uploadUrl()` | Upload from web URL | [📖](https://docs.graphorlm.com/sdk/sources/upload#upload-from-url) |
377
+ | `sources.uploadGithub()` | Upload from GitHub | [📖](https://docs.graphorlm.com/sdk/sources/upload#upload-from-github) |
378
+ | `sources.uploadYoutube()` | Upload from YouTube | [📖](https://docs.graphorlm.com/sdk/sources/upload#upload-from-youtube) |
379
+ | `sources.parse()` | Reprocess with different method | [📖](https://docs.graphorlm.com/sdk/sources/process) |
380
+ | `sources.list()` | List all sources | [📖](https://docs.graphorlm.com/sdk/sources/list) |
381
+ | `sources.delete()` | Delete a source | [📖](https://docs.graphorlm.com/sdk/sources/delete) |
382
+ | `sources.loadElements()` | Get parsed elements | [📖](https://docs.graphorlm.com/sdk/sources/list-elements) |
356
383
 
357
- ```ts
358
- import GraphorPrd from 'npm:graphor';
384
+ ### Chat & AI
359
385
 
360
- const httpClient = Deno.createHttpClient({ proxy: { url: 'http://localhost:8888' } });
361
- const client = new GraphorPrd({
362
- fetchOptions: {
363
- client: httpClient,
364
- },
365
- });
366
- ```
386
+ | Method | Description | Docs |
387
+ |--------|-------------|------|
388
+ | `sources.ask()` | Ask questions about documents | [📖](https://docs.graphorlm.com/sdk/chat) |
389
+ | `sources.extract()` | Extract structured data | [📖](https://docs.graphorlm.com/sdk/extract) |
390
+ | `sources.retrieveChunks()` | Retrieve chunks for RAG | [📖](https://docs.graphorlm.com/sdk/prebuilt-rag) |
367
391
 
368
- ## Frequently Asked Questions
392
+ ## TypeScript Support
369
393
 
370
- ## Semantic versioning
394
+ This library includes complete TypeScript definitions for all request params and response fields:
371
395
 
372
- This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions:
396
+ ```typescript
397
+ import Graphor from 'graphor';
373
398
 
374
- 1. Changes that only affect static types, without breaking runtime behavior.
375
- 2. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals.)_
376
- 3. Changes that we do not expect to impact the vast majority of users in practice.
399
+ const client = new Graphor();
377
400
 
378
- We take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience.
401
+ // Type-safe params and responses
402
+ const params: Graphor.SourceUploadParams = { file: fs.createReadStream('path/to/file') };
403
+ const source: Graphor.PublicSource = await client.sources.upload(params);
404
+ ```
379
405
 
380
- We are keen for your feedback; please open an [issue](https://www.github.com/synapseops/graphor-typescript-sdk/issues) with questions, bugs, or suggestions.
406
+ Documentation for each method, request param, and response field are available in docstrings and will appear on hover in most modern editors.
381
407
 
382
408
  ## Requirements
383
409
 
384
- TypeScript >= 4.9 is supported.
410
+ - TypeScript >= 4.9
411
+ - Node.js 20+ (LTS)
412
+ - Also works in: Deno v1.28+, Bun 1.0+, Cloudflare Workers, Vercel Edge Runtime, and modern browsers
385
413
 
386
- The following runtimes are supported:
414
+ ## Contributing
387
415
 
388
- - Web browsers (Up-to-date Chrome, Firefox, Safari, Edge, and more)
389
- - Node.js 20 LTS or later ([non-EOL](https://endoflife.date/nodejs)) versions.
390
- - Deno v1.28.0 or higher.
391
- - Bun 1.0 or later.
392
- - Cloudflare Workers.
393
- - Vercel Edge Runtime.
394
- - Jest 28 or greater with the `"node"` environment (`"jsdom"` is not supported at this time).
395
- - Nitro v2.6 or greater.
416
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
396
417
 
397
- Note that React Native is not supported at this time.
418
+ ## License
398
419
 
399
- If you are interested in other runtime environments, please open or upvote an issue on GitHub.
420
+ MIT License - see [LICENSE](./LICENSE) for details.
400
421
 
401
- ## Contributing
422
+ ## Links
402
423
 
403
- See [the contributing documentation](./CONTRIBUTING.md).
424
+ - 📚 [Documentation](https://docs.graphorlm.com/sdk/overview)
425
+ - 🐛 [Issue Tracker](https://github.com/synapseops/graphor-typescript-sdk/issues)
426
+ - 📦 [NPM](https://www.npmjs.com/package/graphor)
427
+ - 🏠 [Graphor](https://graphorlm.com)