@tiny-fish/sdk 0.0.3 → 0.0.6
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 +498 -2
- package/dist/_utils/client.d.ts +16 -9
- package/dist/_utils/client.d.ts.map +1 -1
- package/dist/_utils/client.js +105 -41
- package/dist/_utils/client.js.map +1 -1
- package/dist/agent/index.d.ts +3 -3
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +5 -2
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/types.d.ts +8 -3
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/browser/index.d.ts +18 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +21 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/types.d.ts +13 -0
- package/dist/browser/types.d.ts.map +1 -0
- package/dist/browser/types.js +5 -0
- package/dist/browser/types.js.map +1 -0
- package/dist/client.d.ts +6 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +9 -0
- package/dist/client.js.map +1 -1
- package/dist/fetch/index.d.ts +10 -0
- package/dist/fetch/index.d.ts.map +1 -0
- package/dist/fetch/index.js +29 -0
- package/dist/fetch/index.js.map +1 -0
- package/dist/fetch/types.d.ts +58 -0
- package/dist/fetch/types.d.ts.map +1 -0
- package/dist/fetch/types.js +11 -0
- package/dist/fetch/types.js.map +1 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/search/index.d.ts +14 -0
- package/dist/search/index.d.ts.map +1 -0
- package/dist/search/index.js +24 -0
- package/dist/search/index.js.map +1 -0
- package/dist/search/types.d.ts +26 -0
- package/dist/search/types.d.ts.map +1 -0
- package/dist/search/types.js +5 -0
- package/dist/search/types.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,5 +1,501 @@
|
|
|
1
1
|
# TinyFish TypeScript SDK
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The official TypeScript SDK for [TinyFish](https://agent.tinyfish.ai)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
For SDK design conventions and how new API surfaces should be added, see [ARCHITECTURE.md](ARCHITECTURE.md).
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @tiny-fish/sdk
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Requires Node.js 18+. Also works with Bun and Deno.
|
|
14
|
+
|
|
15
|
+
## Get your API key
|
|
16
|
+
|
|
17
|
+
Sign up and grab your key at [agent.tinyfish.ai/api-keys](https://agent.tinyfish.ai/api-keys).
|
|
18
|
+
|
|
19
|
+
## Quickstart
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { TinyFish } from "@tiny-fish/sdk";
|
|
23
|
+
|
|
24
|
+
const client = new TinyFish({ apiKey: "your-api-key" });
|
|
25
|
+
|
|
26
|
+
const stream = await client.agent.stream(
|
|
27
|
+
{
|
|
28
|
+
goal: "What is the current Bitcoin price?",
|
|
29
|
+
url: "https://www.coinbase.com/price/bitcoin",
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
onProgress: (e) => console.log(` > ${e.purpose}`),
|
|
33
|
+
onComplete: (e) => console.log(e.result),
|
|
34
|
+
},
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
for await (const event of stream) {
|
|
38
|
+
// Callbacks fire automatically during iteration
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Need per-request cancellation without changing the client-wide timeout? Pass an `AbortSignal` as the optional second argument:
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
const controller = new AbortController();
|
|
46
|
+
|
|
47
|
+
const stream = await client.agent.stream(
|
|
48
|
+
{
|
|
49
|
+
goal: "Extract the top 5 headlines",
|
|
50
|
+
url: "https://news.ycombinator.com",
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
signal: controller.signal,
|
|
54
|
+
},
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
controller.abort();
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Or set the `TINYFISH_API_KEY` environment variable and omit `apiKey`:
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
const client = new TinyFish();
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
> All methods are async and return promises. There is no synchronous client — JavaScript is async-native.
|
|
67
|
+
|
|
68
|
+
## Methods
|
|
69
|
+
|
|
70
|
+
| Method | Description | Returns | Blocks? |
|
|
71
|
+
|--------|-------------|---------|---------|
|
|
72
|
+
| [`agent.stream()`](#agentstream--real-time-events) | Stream live SSE events as the agent works | `AgentStream` | No |
|
|
73
|
+
| [`agent.run()`](#agentrun--block-until-done) | Run an automation, wait for the result | `AgentRunResponse` | Yes |
|
|
74
|
+
| [`agent.queue()`](#agentqueue--fire-and-forget) | Start an automation, return immediately | `AgentRunAsyncResponse` | No |
|
|
75
|
+
| [`browser.sessions.create()`](#browsersessionscreate--create-a-browser-session) | Create a remote browser session | `BrowserSession` | — |
|
|
76
|
+
| [`fetch.getContents()`](#fetchgetcontents--fetch-and-extract-content) | Fetch URLs and return extracted content | `FetchResponse` | — |
|
|
77
|
+
| [`runs.get()`](#runsget--retrieve-a-single-run) | Retrieve a single run by ID | `Run` | — |
|
|
78
|
+
| [`runs.list()`](#runslist--list-and-filter-runs) | List runs with filtering, sorting, pagination | `RunListResponse` | — |
|
|
79
|
+
| [`search.query()`](#searchquery--run-a-web-search) | Run a web search query | `SearchQueryResponse` | — |
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
### `agent.stream()` — real-time events
|
|
84
|
+
|
|
85
|
+
Opens a Server-Sent Events stream. You get live progress updates as the agent works, plus a URL for a live browser preview. This is the recommended integration method.
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
import { TinyFish } from "@tiny-fish/sdk";
|
|
89
|
+
|
|
90
|
+
const client = new TinyFish();
|
|
91
|
+
|
|
92
|
+
const stream = await client.agent.stream(
|
|
93
|
+
{
|
|
94
|
+
goal: "Extract the top 5 headlines",
|
|
95
|
+
url: "https://news.ycombinator.com",
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
onStarted: (e) => console.log(`Started: ${e.run_id}`),
|
|
99
|
+
onStreamingUrl: (e) => console.log(`Watch: ${e.streaming_url}`),
|
|
100
|
+
onProgress: (e) => console.log(` > ${e.purpose}`),
|
|
101
|
+
onComplete: (e) => console.log(`Done: ${e.status}`),
|
|
102
|
+
},
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
for await (const event of stream) {
|
|
106
|
+
// Callbacks fire automatically during iteration.
|
|
107
|
+
// You can also inspect events directly:
|
|
108
|
+
if (event.type === "COMPLETE") {
|
|
109
|
+
console.log(event.result);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Returns `AgentStream`** — an async iterable you iterate with `for await`. Events arrive in order: `STARTED` → `STREAMING_URL` → `PROGRESS` (repeated) → `COMPLETE`.
|
|
115
|
+
|
|
116
|
+
Call `stream.close()` to abort early and stop yielding events.
|
|
117
|
+
|
|
118
|
+
The second argument also accepts `signal` for request-scoped cancellation:
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
const controller = new AbortController();
|
|
122
|
+
|
|
123
|
+
const stream = await client.agent.stream(
|
|
124
|
+
{
|
|
125
|
+
goal: "Extract the top 5 headlines",
|
|
126
|
+
url: "https://news.ycombinator.com",
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
signal: controller.signal,
|
|
130
|
+
onProgress: (e) => console.log(e.purpose),
|
|
131
|
+
},
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
controller.abort();
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
See the [Streaming Guide](docs/streaming-guide.md) for the full event lifecycle, event types, and advanced patterns.
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
### `agent.run()` — block until done
|
|
142
|
+
|
|
143
|
+
Sends the automation and waits for it to finish. Returns the full result in one shot.
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
import { TinyFish, RunStatus, BrowserProfile, ProxyCountryCode } from "@tiny-fish/sdk";
|
|
147
|
+
import type { ProxyConfig } from "@tiny-fish/sdk";
|
|
148
|
+
|
|
149
|
+
const client = new TinyFish();
|
|
150
|
+
|
|
151
|
+
const response = await client.agent.run({
|
|
152
|
+
goal: "Extract the top 5 headlines", // required — what to do on the page
|
|
153
|
+
url: "https://news.ycombinator.com", // required — URL to open
|
|
154
|
+
browser_profile: BrowserProfile.STEALTH, // optional — "lite" (default) or "stealth"
|
|
155
|
+
proxy_config: { // optional — proxy settings
|
|
156
|
+
enabled: true,
|
|
157
|
+
country_code: ProxyCountryCode.US, // optional — US, GB, CA, DE, FR, JP, AU
|
|
158
|
+
},
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
if (response.status === RunStatus.COMPLETED) {
|
|
162
|
+
console.log(response.result);
|
|
163
|
+
} else {
|
|
164
|
+
console.log(`Failed: ${response.error?.message}`);
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Like `stream()`, `run()` accepts an optional second argument with `signal`:
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
const controller = new AbortController();
|
|
172
|
+
|
|
173
|
+
const response = await client.agent.run(
|
|
174
|
+
{
|
|
175
|
+
goal: "Extract the top 5 headlines",
|
|
176
|
+
url: "https://news.ycombinator.com",
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
signal: controller.signal,
|
|
180
|
+
},
|
|
181
|
+
);
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**Returns `AgentRunResponse`:**
|
|
185
|
+
|
|
186
|
+
| Field | Type | Description |
|
|
187
|
+
|-------|------|-------------|
|
|
188
|
+
| `status` | `RunStatus` | `COMPLETED`, `FAILED`, etc. |
|
|
189
|
+
| `run_id` | `string \| null` | Unique run identifier |
|
|
190
|
+
| `result` | `Record<string, unknown> \| null` | Extracted data (`null` if failed) |
|
|
191
|
+
| `error` | `RunError \| null` | Error details (`null` if succeeded) |
|
|
192
|
+
| `num_of_steps` | `number` | Number of steps the agent took |
|
|
193
|
+
| `started_at` | `string \| null` | ISO 8601 timestamp when the run started |
|
|
194
|
+
| `finished_at` | `string \| null` | ISO 8601 timestamp when the run finished |
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
### `agent.queue()` — fire and forget
|
|
199
|
+
|
|
200
|
+
Starts the automation in the background and returns a `run_id` immediately. Poll with `runs.get()` when you're ready for the result.
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
import { TinyFish, RunStatus } from "@tiny-fish/sdk";
|
|
204
|
+
|
|
205
|
+
const client = new TinyFish();
|
|
206
|
+
|
|
207
|
+
const queued = await client.agent.queue({
|
|
208
|
+
goal: "Extract the top 5 headlines",
|
|
209
|
+
url: "https://news.ycombinator.com",
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
if (queued.error) {
|
|
213
|
+
console.error(`Failed to queue: ${queued.error.message}`);
|
|
214
|
+
process.exit(1);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
console.log(`Run started: ${queued.run_id}`);
|
|
218
|
+
|
|
219
|
+
// Poll for completion
|
|
220
|
+
while (true) {
|
|
221
|
+
const run = await client.runs.get(queued.run_id);
|
|
222
|
+
if (run.status === RunStatus.COMPLETED || run.status === RunStatus.FAILED) {
|
|
223
|
+
console.log(run.result);
|
|
224
|
+
break;
|
|
225
|
+
}
|
|
226
|
+
await new Promise((r) => setTimeout(r, 5000));
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
`queue()` also accepts an optional `{ signal }` second argument when you want to cancel just that enqueue request.
|
|
231
|
+
|
|
232
|
+
**Returns `AgentRunAsyncResponse`** — a discriminated union. Check `error` to narrow the type:
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
const response = await client.agent.queue({ goal, url });
|
|
236
|
+
if (response.error) {
|
|
237
|
+
// response.run_id is null here
|
|
238
|
+
console.error(response.error.message);
|
|
239
|
+
} else {
|
|
240
|
+
// response.run_id is string here
|
|
241
|
+
const run = await client.runs.get(response.run_id);
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
| Field | Type | Description |
|
|
246
|
+
|-------|------|-------------|
|
|
247
|
+
| `run_id` | `string \| null` | Run ID to poll with `runs.get()` |
|
|
248
|
+
| `error` | `RunError \| null` | Error if queuing itself failed |
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
### `browser.sessions.create()` — create a browser session
|
|
253
|
+
|
|
254
|
+
Create a remote browser session and get back the connection details for direct CDP control. Pass a `url` to hint routing and start the session on a target page, or omit it to start at `about:blank`.
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
import { TinyFish } from "@tiny-fish/sdk";
|
|
258
|
+
|
|
259
|
+
const client = new TinyFish();
|
|
260
|
+
|
|
261
|
+
const session = await client.browser.sessions.create({
|
|
262
|
+
url: "https://example.com",
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
console.log(session.session_id);
|
|
266
|
+
console.log(session.cdp_url);
|
|
267
|
+
console.log(session.base_url);
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
**Returns `BrowserSession`:**
|
|
271
|
+
|
|
272
|
+
| Field | Type | Description |
|
|
273
|
+
|-------|------|-------------|
|
|
274
|
+
| `session_id` | `string` | Unique browser session identifier |
|
|
275
|
+
| `cdp_url` | `string` | CDP WebSocket URL for connecting to the browser |
|
|
276
|
+
| `base_url` | `string` | HTTPS base URL for the browser session |
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
### `fetch.getContents()` — fetch and extract content
|
|
281
|
+
|
|
282
|
+
Fetch one or more URLs and return clean extracted content in markdown, html, or json form.
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
import { FetchFormat, TinyFish } from "@tiny-fish/sdk";
|
|
286
|
+
|
|
287
|
+
const client = new TinyFish();
|
|
288
|
+
|
|
289
|
+
const response = await client.fetch.getContents({
|
|
290
|
+
urls: ["https://example.com"],
|
|
291
|
+
format: FetchFormat.Markdown,
|
|
292
|
+
links: true,
|
|
293
|
+
image_links: false,
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
console.log(response.results);
|
|
297
|
+
console.log(response.errors);
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
**Returns `FetchResponse`:**
|
|
301
|
+
|
|
302
|
+
| Field | Type | Description |
|
|
303
|
+
|-------|------|-------------|
|
|
304
|
+
| `results` | `FetchResult[]` | Successfully fetched URLs and extracted content |
|
|
305
|
+
| `errors` | `FetchError[]` | URLs that failed to fetch |
|
|
306
|
+
|
|
307
|
+
`FetchResult.text` is:
|
|
308
|
+
|
|
309
|
+
- `string` for `markdown` and `html`
|
|
310
|
+
- `Record<string, unknown>` for `json`
|
|
311
|
+
- `null` if extraction failed for that item
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
### `runs.get()` — retrieve a single run
|
|
316
|
+
|
|
317
|
+
Fetch the full details of a run by its ID.
|
|
318
|
+
|
|
319
|
+
```typescript
|
|
320
|
+
const run = await client.runs.get("run_abc123");
|
|
321
|
+
|
|
322
|
+
console.log(run.status); // PENDING, RUNNING, COMPLETED, FAILED, CANCELLED
|
|
323
|
+
console.log(run.result);
|
|
324
|
+
console.log(run.goal);
|
|
325
|
+
console.log(run.streaming_url); // live browser URL (while RUNNING)
|
|
326
|
+
console.log(run.browser_config); // proxy/browser settings that were used
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
**Returns `Run`:**
|
|
330
|
+
|
|
331
|
+
| Field | Type | Description |
|
|
332
|
+
|-------|------|-------------|
|
|
333
|
+
| `run_id` | `string` | Unique identifier |
|
|
334
|
+
| `status` | `RunStatus` | `PENDING`, `RUNNING`, `COMPLETED`, `FAILED`, `CANCELLED` |
|
|
335
|
+
| `goal` | `string` | The goal that was given |
|
|
336
|
+
| `result` | `Record<string, unknown> \| null` | Extracted data (`null` if not completed) |
|
|
337
|
+
| `error` | `RunError \| null` | Error details (`null` if succeeded) |
|
|
338
|
+
| `streaming_url` | `string \| null` | Live browser URL (available while running) |
|
|
339
|
+
| `browser_config` | `BrowserConfig \| null` | Proxy/browser settings used |
|
|
340
|
+
| `created_at` | `string` | ISO 8601 timestamp when the run was created |
|
|
341
|
+
| `started_at` | `string \| null` | ISO 8601 timestamp when execution started |
|
|
342
|
+
| `finished_at` | `string \| null` | ISO 8601 timestamp when execution finished |
|
|
343
|
+
| `num_of_steps` | `number` | Number of steps the agent took |
|
|
344
|
+
|
|
345
|
+
**Throws:** `SDKError` if `run_id` is empty. `NotFoundError` if no run exists with that ID.
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
### `runs.list()` — list and filter runs
|
|
350
|
+
|
|
351
|
+
List runs with optional filtering, sorting, and cursor-based pagination. All parameters are optional.
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
import { RunStatus, SortDirection } from "@tiny-fish/sdk";
|
|
355
|
+
|
|
356
|
+
const response = await client.runs.list({
|
|
357
|
+
status: RunStatus.COMPLETED, // optional — filter by status
|
|
358
|
+
goal: "headlines", // optional — filter by goal text
|
|
359
|
+
created_after: "2025-01-01T00:00:00Z", // optional — ISO 8601 lower bound
|
|
360
|
+
created_before: "2025-12-31T23:59:59Z", // optional — ISO 8601 upper bound
|
|
361
|
+
sort_direction: SortDirection.DESC, // optional — "asc" or "desc"
|
|
362
|
+
limit: 10, // optional — max runs per page
|
|
363
|
+
cursor: undefined, // optional — pagination cursor from previous response
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
for (const run of response.data) {
|
|
367
|
+
console.log(`${run.run_id} | ${run.goal}`);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// Pagination
|
|
371
|
+
if (response.pagination.has_more) {
|
|
372
|
+
const nextPage = await client.runs.list({ cursor: response.pagination.next_cursor! });
|
|
373
|
+
}
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
**Returns `RunListResponse`:**
|
|
377
|
+
|
|
378
|
+
| Field | Type | Description |
|
|
379
|
+
|-------|------|-------------|
|
|
380
|
+
| `data` | `Run[]` | List of runs |
|
|
381
|
+
| `pagination.total` | `number` | Total runs matching filters |
|
|
382
|
+
| `pagination.has_more` | `boolean` | Whether more pages exist |
|
|
383
|
+
| `pagination.next_cursor` | `string \| null` | Pass to `cursor` for the next page |
|
|
384
|
+
|
|
385
|
+
See the [Pagination Guide](docs/pagination-guide.md) for full pagination loop examples.
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
### `search.query()` — run a web search
|
|
390
|
+
|
|
391
|
+
Run a typed search query through the TinyFish Search API.
|
|
392
|
+
|
|
393
|
+
```typescript
|
|
394
|
+
import { TinyFish } from "@tiny-fish/sdk";
|
|
395
|
+
|
|
396
|
+
const client = new TinyFish();
|
|
397
|
+
|
|
398
|
+
const response = await client.search.query({
|
|
399
|
+
query: "tinyfish sdk",
|
|
400
|
+
location: "US",
|
|
401
|
+
language: "en",
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
console.log(response.query);
|
|
405
|
+
console.log(response.total_results);
|
|
406
|
+
console.log(response.results[0]?.title);
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
**Returns `SearchQueryResponse`:**
|
|
410
|
+
|
|
411
|
+
| Field | Type | Description |
|
|
412
|
+
|-------|------|-------------|
|
|
413
|
+
| `query` | `string` | The query that was executed |
|
|
414
|
+
| `results` | `SearchResult[]` | Search results returned by the backend |
|
|
415
|
+
| `total_results` | `number` | Total number of results returned |
|
|
416
|
+
|
|
417
|
+
**Throws:** `SDKError` if `query` is empty. Standard API errors are handled by the shared SDK error hierarchy.
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
## Configuration
|
|
422
|
+
|
|
423
|
+
### Client options
|
|
424
|
+
|
|
425
|
+
```typescript
|
|
426
|
+
const client = new TinyFish({
|
|
427
|
+
apiKey: "your-api-key", // optional — or set TINYFISH_API_KEY env var
|
|
428
|
+
baseURL: "https://agent.tinyfish.ai", // optional — default shown
|
|
429
|
+
timeout: 600_000, // optional — milliseconds (default: 600,000 = 10 min)
|
|
430
|
+
maxRetries: 2, // optional — retry attempts (default: 2)
|
|
431
|
+
});
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
The SDK retries `408`, `429`, and `5xx` errors automatically with exponential backoff (0.5s base, max 8s wait).
|
|
435
|
+
|
|
436
|
+
### Browser profiles
|
|
437
|
+
|
|
438
|
+
Control the browser environment with `browser_profile`:
|
|
439
|
+
|
|
440
|
+
- **`lite`** (default) — fast, lightweight. Good for most sites.
|
|
441
|
+
- **`stealth`** — anti-detection mode. Use for sites with bot protection.
|
|
442
|
+
|
|
443
|
+
```typescript
|
|
444
|
+
import { BrowserProfile } from "@tiny-fish/sdk";
|
|
445
|
+
|
|
446
|
+
const response = await client.agent.run({
|
|
447
|
+
goal: "...",
|
|
448
|
+
url: "...",
|
|
449
|
+
browser_profile: BrowserProfile.STEALTH,
|
|
450
|
+
});
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
### Proxy configuration
|
|
454
|
+
|
|
455
|
+
Route requests through a proxy, optionally pinned to a country:
|
|
456
|
+
|
|
457
|
+
```typescript
|
|
458
|
+
import { ProxyCountryCode } from "@tiny-fish/sdk";
|
|
459
|
+
|
|
460
|
+
const response = await client.agent.run({
|
|
461
|
+
goal: "...",
|
|
462
|
+
url: "...",
|
|
463
|
+
proxy_config: { enabled: true, country_code: ProxyCountryCode.US },
|
|
464
|
+
});
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
Available countries: `US`, `GB`, `CA`, `DE`, `FR`, `JP`, `AU`.
|
|
468
|
+
|
|
469
|
+
See the [Proxy & Browser Profiles Guide](docs/proxy-and-browser-profiles.md) for more details.
|
|
470
|
+
|
|
471
|
+
## Error handling
|
|
472
|
+
|
|
473
|
+
```typescript
|
|
474
|
+
import { TinyFish, AuthenticationError, RateLimitError, SDKError } from "@tiny-fish/sdk";
|
|
475
|
+
|
|
476
|
+
const client = new TinyFish();
|
|
477
|
+
|
|
478
|
+
try {
|
|
479
|
+
const response = await client.agent.run({ goal: "...", url: "..." });
|
|
480
|
+
} catch (error) {
|
|
481
|
+
if (error instanceof AuthenticationError) {
|
|
482
|
+
console.log("Invalid API key");
|
|
483
|
+
} else if (error instanceof RateLimitError) {
|
|
484
|
+
console.log("Rate limited (retries exhausted)");
|
|
485
|
+
} else if (error instanceof SDKError) {
|
|
486
|
+
console.log("Something else went wrong");
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
The SDK automatically retries transient errors (`408`, `429`, `5xx`) up to `maxRetries` times with exponential backoff. Non-retryable errors (`401`, `400`, `404`) throw immediately.
|
|
492
|
+
|
|
493
|
+
For the full exception hierarchy and internal architecture, see [docs/internal/exceptions-and-errors-guide.md](docs/internal/exceptions-and-errors-guide.md).
|
|
494
|
+
|
|
495
|
+
## Guides
|
|
496
|
+
|
|
497
|
+
- [Streaming Guide](docs/streaming-guide.md) — event lifecycle, callbacks vs iteration, event type reference
|
|
498
|
+
- [Proxy & Browser Profiles](docs/proxy-and-browser-profiles.md) — stealth mode, proxy countries
|
|
499
|
+
- [Pagination Guide](docs/pagination-guide.md) — filtering, sorting, cursor-based pagination
|
|
500
|
+
- [Exceptions & Error Handling (internal)](docs/internal/exceptions-and-errors-guide.md) — layer-by-layer architecture
|
|
501
|
+
- [Testing Guide](tests/testing-guide.md) — running and writing tests
|
package/dist/_utils/client.d.ts
CHANGED
|
@@ -7,6 +7,15 @@ export interface ClientOptions {
|
|
|
7
7
|
timeout?: number;
|
|
8
8
|
maxRetries?: number;
|
|
9
9
|
}
|
|
10
|
+
interface RequestOptions {
|
|
11
|
+
signal?: AbortSignal | undefined;
|
|
12
|
+
}
|
|
13
|
+
interface GetRequestOptions extends RequestOptions {
|
|
14
|
+
params?: Record<string, string | number | boolean | undefined>;
|
|
15
|
+
}
|
|
16
|
+
interface PostRequestOptions extends RequestOptions {
|
|
17
|
+
json?: unknown;
|
|
18
|
+
}
|
|
10
19
|
export declare class BaseClient {
|
|
11
20
|
private readonly _apiKey;
|
|
12
21
|
readonly baseURL: string;
|
|
@@ -18,6 +27,9 @@ export declare class BaseClient {
|
|
|
18
27
|
*/
|
|
19
28
|
toJSON(): Record<string, unknown>;
|
|
20
29
|
protected _buildHeaders(): Record<string, string>;
|
|
30
|
+
/** Inject api_integration from TF_API_INTEGRATION env var into JSON body. */
|
|
31
|
+
private static _injectIntegration;
|
|
32
|
+
private _buildRequestSignal;
|
|
21
33
|
/**
|
|
22
34
|
* Core request method with retry and error mapping.
|
|
23
35
|
* All public methods (get, post, postStream) delegate here.
|
|
@@ -31,14 +43,9 @@ export declare class BaseClient {
|
|
|
31
43
|
private _parseErrorMessage;
|
|
32
44
|
/** Maps HTTP status codes to typed error classes. Matches Python SDK's _make_status_error. */
|
|
33
45
|
private _makeStatusError;
|
|
34
|
-
get<T>(path: string, options?:
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
post<T>(path: string, options?: {
|
|
38
|
-
json?: unknown;
|
|
39
|
-
}): Promise<T>;
|
|
40
|
-
postStream(path: string, options?: {
|
|
41
|
-
json?: unknown;
|
|
42
|
-
}): Promise<ReadableStream<string>>;
|
|
46
|
+
get<T>(path: string, options?: GetRequestOptions): Promise<T>;
|
|
47
|
+
post<T>(path: string, options?: PostRequestOptions): Promise<T>;
|
|
48
|
+
postStream(path: string, options?: PostRequestOptions): Promise<ReadableStream<string>>;
|
|
43
49
|
}
|
|
50
|
+
export {};
|
|
44
51
|
//# sourceMappingURL=client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/_utils/client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAqBH,MAAM,WAAW,aAAa;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/_utils/client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAqBH,MAAM,WAAW,aAAa;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,cAAc;IACvB,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CACjC;AAED,UAAU,iBAAkB,SAAQ,cAAc;IACjD,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;CAC/D;AAED,UAAU,kBAAmB,SAAQ,cAAc;IAClD,IAAI,CAAC,EAAE,OAAO,CAAC;CACf;AAYD,qBAAa,UAAU;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;gBAEhB,OAAO,GAAE,aAAkB;IAcvC;;OAEG;IACH,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAejC,SAAS,CAAC,aAAa,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAUjD,6EAA6E;IAC7E,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAYjC,OAAO,CAAC,mBAAmB;IAyC3B;;;OAGG;YACW,QAAQ;IAmFtB;;;;OAIG;YACW,kBAAkB;IAuBhC,8FAA8F;YAChF,gBAAgB;IAmCxB,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,CAAC,CAAC;IAgB7D,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,CAAC,CAAC;IAK/D,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;CAS7F"}
|