crw-sdk 0.22.0 → 0.23.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 +4 -2
- package/dist/cjs/client.js +15 -7
- package/dist/esm/client.d.ts +5 -1
- package/dist/esm/client.js +15 -7
- package/dist/esm/types.d.ts +6 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -61,11 +61,13 @@ CRW_LOCAL=1 node app.js
|
|
|
61
61
|
¹ Local search needs a SearXNG URL configured on the engine.
|
|
62
62
|
|
|
63
63
|
```ts
|
|
64
|
-
// Structured extraction:
|
|
65
|
-
const
|
|
64
|
+
// Structured extraction (async job → per-URL results array):
|
|
65
|
+
const results = await crw.extract({
|
|
66
66
|
urls: ["https://example.com"],
|
|
67
67
|
schema: { type: "object", properties: { title: { type: "string" } } },
|
|
68
68
|
});
|
|
69
|
+
// results: [{ url, status, data, error, llmUsage }]
|
|
70
|
+
for (const r of results) if (r.status === "completed") console.log(r.url, r.data);
|
|
69
71
|
|
|
70
72
|
// Parse a PDF:
|
|
71
73
|
import { readFileSync } from "node:fs";
|
package/dist/cjs/client.js
CHANGED
|
@@ -170,19 +170,27 @@ class CrwClient {
|
|
|
170
170
|
Object.assign(args, rest);
|
|
171
171
|
return this.localTransport().toolCall("crw_parse_file", args);
|
|
172
172
|
}
|
|
173
|
-
/**
|
|
173
|
+
/**
|
|
174
|
+
* Native multi-URL structured extraction (HTTP mode only). Starts an async
|
|
175
|
+
* `/v1/extract` job and polls until complete, returning a per-URL results
|
|
176
|
+
* array (`[{ url, status, data, error, llmUsage }]`) in request order.
|
|
177
|
+
*/
|
|
174
178
|
async extract(opts) {
|
|
175
179
|
if (!this.apiUrl)
|
|
176
180
|
throw new errors_js_1.CrwError(httpOnlyHint("extract", "LLM extract job endpoint"));
|
|
177
|
-
const { urls, prompt, schema,
|
|
181
|
+
const { urls, prompt, schema, llmApiKey, llmProvider, llmModel, pollInterval = 2, timeout = 120 } = opts;
|
|
178
182
|
const body = { urls: [...urls] };
|
|
179
183
|
if (prompt !== undefined)
|
|
180
184
|
body.prompt = prompt;
|
|
181
185
|
if (schema !== undefined)
|
|
182
186
|
body.schema = schema;
|
|
183
|
-
if (
|
|
184
|
-
body.
|
|
185
|
-
|
|
187
|
+
if (llmApiKey !== undefined)
|
|
188
|
+
body.llmApiKey = llmApiKey;
|
|
189
|
+
if (llmProvider !== undefined)
|
|
190
|
+
body.llmProvider = llmProvider;
|
|
191
|
+
if (llmModel !== undefined)
|
|
192
|
+
body.llmModel = llmModel;
|
|
193
|
+
const start = await this.httpRequest("POST", "/v1/extract", body, { raw: true });
|
|
186
194
|
const jobId = start.id;
|
|
187
195
|
if (!jobId)
|
|
188
196
|
throw new errors_js_1.CrwError(`extract did not return job ID: ${JSON.stringify(start)}`);
|
|
@@ -190,9 +198,9 @@ class CrwClient {
|
|
|
190
198
|
for (;;) {
|
|
191
199
|
if (Date.now() > deadline)
|
|
192
200
|
throw new errors_js_1.CrwTimeoutError(`Extract ${jobId} timed out after ${timeout}s`);
|
|
193
|
-
const status = await this.httpRequest("GET", `/
|
|
201
|
+
const status = await this.httpRequest("GET", `/v1/extract/${jobId}`, undefined, { raw: true, checkSuccess: false });
|
|
194
202
|
if (status.status === "completed")
|
|
195
|
-
return status.
|
|
203
|
+
return status.results ?? [];
|
|
196
204
|
if (status.status === "failed")
|
|
197
205
|
throw new errors_js_1.CrwError(`Extract failed: ${status.error ?? "unknown"}`);
|
|
198
206
|
await sleep(pollInterval * 1000);
|
package/dist/esm/client.d.ts
CHANGED
|
@@ -37,7 +37,11 @@ export declare class CrwClient {
|
|
|
37
37
|
* Parse a document (PDF) into markdown / structured JSON. Works in both modes.
|
|
38
38
|
*/
|
|
39
39
|
parseFile(content: Uint8Array, opts?: ParseFileOptions): Promise<ParseResult>;
|
|
40
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* Native multi-URL structured extraction (HTTP mode only). Starts an async
|
|
42
|
+
* `/v1/extract` job and polls until complete, returning a per-URL results
|
|
43
|
+
* array (`[{ url, status, data, error, llmUsage }]`) in request order.
|
|
44
|
+
*/
|
|
41
45
|
extract(opts: ExtractOptions): Promise<ExtractResult>;
|
|
42
46
|
/** Scrape many URLs in one async batch job (HTTP mode only). */
|
|
43
47
|
batchScrape(urls: string[], opts?: BatchScrapeOptions): Promise<BatchResult>;
|
package/dist/esm/client.js
CHANGED
|
@@ -167,19 +167,27 @@ export class CrwClient {
|
|
|
167
167
|
Object.assign(args, rest);
|
|
168
168
|
return this.localTransport().toolCall("crw_parse_file", args);
|
|
169
169
|
}
|
|
170
|
-
/**
|
|
170
|
+
/**
|
|
171
|
+
* Native multi-URL structured extraction (HTTP mode only). Starts an async
|
|
172
|
+
* `/v1/extract` job and polls until complete, returning a per-URL results
|
|
173
|
+
* array (`[{ url, status, data, error, llmUsage }]`) in request order.
|
|
174
|
+
*/
|
|
171
175
|
async extract(opts) {
|
|
172
176
|
if (!this.apiUrl)
|
|
173
177
|
throw new CrwError(httpOnlyHint("extract", "LLM extract job endpoint"));
|
|
174
|
-
const { urls, prompt, schema,
|
|
178
|
+
const { urls, prompt, schema, llmApiKey, llmProvider, llmModel, pollInterval = 2, timeout = 120 } = opts;
|
|
175
179
|
const body = { urls: [...urls] };
|
|
176
180
|
if (prompt !== undefined)
|
|
177
181
|
body.prompt = prompt;
|
|
178
182
|
if (schema !== undefined)
|
|
179
183
|
body.schema = schema;
|
|
180
|
-
if (
|
|
181
|
-
body.
|
|
182
|
-
|
|
184
|
+
if (llmApiKey !== undefined)
|
|
185
|
+
body.llmApiKey = llmApiKey;
|
|
186
|
+
if (llmProvider !== undefined)
|
|
187
|
+
body.llmProvider = llmProvider;
|
|
188
|
+
if (llmModel !== undefined)
|
|
189
|
+
body.llmModel = llmModel;
|
|
190
|
+
const start = await this.httpRequest("POST", "/v1/extract", body, { raw: true });
|
|
183
191
|
const jobId = start.id;
|
|
184
192
|
if (!jobId)
|
|
185
193
|
throw new CrwError(`extract did not return job ID: ${JSON.stringify(start)}`);
|
|
@@ -187,9 +195,9 @@ export class CrwClient {
|
|
|
187
195
|
for (;;) {
|
|
188
196
|
if (Date.now() > deadline)
|
|
189
197
|
throw new CrwTimeoutError(`Extract ${jobId} timed out after ${timeout}s`);
|
|
190
|
-
const status = await this.httpRequest("GET", `/
|
|
198
|
+
const status = await this.httpRequest("GET", `/v1/extract/${jobId}`, undefined, { raw: true, checkSuccess: false });
|
|
191
199
|
if (status.status === "completed")
|
|
192
|
-
return status.
|
|
200
|
+
return status.results ?? [];
|
|
193
201
|
if (status.status === "failed")
|
|
194
202
|
throw new CrwError(`Extract failed: ${status.error ?? "unknown"}`);
|
|
195
203
|
await sleep(pollInterval * 1000);
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -60,7 +60,10 @@ export interface ExtractOptions {
|
|
|
60
60
|
urls: string[];
|
|
61
61
|
prompt?: string;
|
|
62
62
|
schema?: Json;
|
|
63
|
-
|
|
63
|
+
/** BYOK: use your own LLM key/provider/model instead of the server's. */
|
|
64
|
+
llmApiKey?: string;
|
|
65
|
+
llmProvider?: string;
|
|
66
|
+
llmModel?: string;
|
|
64
67
|
pollInterval?: number;
|
|
65
68
|
timeout?: number;
|
|
66
69
|
}
|
|
@@ -80,7 +83,8 @@ export type ScrapeResult = Json;
|
|
|
80
83
|
export type CrawlResult = Json[];
|
|
81
84
|
export type SearchResult = Json | Json[];
|
|
82
85
|
export type ParseResult = Json;
|
|
83
|
-
|
|
86
|
+
/** Native `/v1/extract` returns one result object per URL, in request order. */
|
|
87
|
+
export type ExtractResult = Json[];
|
|
84
88
|
export type BatchResult = Json[];
|
|
85
89
|
export type Capabilities = Json;
|
|
86
90
|
export type DiffResult = Json;
|
package/package.json
CHANGED