context-dev-ai-tools 0.1.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/LICENSE +21 -0
- package/README.md +304 -0
- package/dist/index.cjs +289 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +5176 -0
- package/dist/index.d.ts +5176 -0
- package/dist/index.js +253 -0
- package/dist/index.js.map +1 -0
- package/package.json +64 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 context-dev-ai-tools contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
# context-dev-ai-tools
|
|
2
|
+
|
|
3
|
+
> **Community-built, unofficial.** This package wraps the official [`context.dev`](https://www.npmjs.com/package/context.dev) SDK as [Vercel AI SDK](https://ai-sdk.dev) tools. It is not published or maintained by context.dev — see [context.dev](https://www.context.dev/) and [docs.context.dev](https://docs.context.dev) for their official SDKs and MCP server.
|
|
4
|
+
|
|
5
|
+
Vercel AI SDK `tool()` wrappers for [context.dev](https://www.context.dev/)'s live web data API: search, scrape, crawl, structured extraction, document parsing, screenshots, brand intelligence, and news — ready to drop into `generateText`/`streamText`. Every example below was run against the real context.dev API; the sample output is real (trimmed for length), not illustrative.
|
|
6
|
+
|
|
7
|
+
## Contents
|
|
8
|
+
|
|
9
|
+
- [Install](#install)
|
|
10
|
+
- [Quick start](#quick-start)
|
|
11
|
+
- [Setup](#setup)
|
|
12
|
+
- [Tools](#tools)
|
|
13
|
+
- [contextSearch](#contextsearch)
|
|
14
|
+
- [contextScrape](#contextscrape)
|
|
15
|
+
- [contextCrawl](#contextcrawl)
|
|
16
|
+
- [contextSitemap](#contextsitemap)
|
|
17
|
+
- [contextExtract](#contextextract)
|
|
18
|
+
- [contextParse](#contextparse)
|
|
19
|
+
- [contextScreenshot](#contextscreenshot)
|
|
20
|
+
- [contextBrand](#contextbrand)
|
|
21
|
+
- [contextNews](#contextnews)
|
|
22
|
+
- [The `contextTools()` bundle](#the-contexttools-bundle)
|
|
23
|
+
- [Error handling](#error-handling)
|
|
24
|
+
- [Not included (v1 scope)](#not-included-v1-scope)
|
|
25
|
+
- [TypeScript](#typescript)
|
|
26
|
+
- [Links](#links)
|
|
27
|
+
|
|
28
|
+
## Install
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install context-dev-ai-tools ai zod
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Requires an `ai` version in `^5.0.0 || ^6.0.0 || ^7.0.0` and a context.dev API key ([get one here](https://www.context.dev/) — the free tier includes 250-500 one-time credits, enough to try every tool below several times over).
|
|
35
|
+
|
|
36
|
+
## Quick start
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import { generateText, stepCountIs } from "ai";
|
|
40
|
+
import { contextSearch, contextScrape } from "context-dev-ai-tools";
|
|
41
|
+
|
|
42
|
+
const result = await generateText({
|
|
43
|
+
model: yourModel,
|
|
44
|
+
prompt: "What did Stripe announce this week? Cite the source URL.",
|
|
45
|
+
tools: {
|
|
46
|
+
contextSearch: contextSearch(),
|
|
47
|
+
contextScrape: contextScrape(),
|
|
48
|
+
},
|
|
49
|
+
stopWhen: stepCountIs(3),
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
console.log(result.text);
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
This exact pattern (asking a live question, letting the model pick a tool on its own) has been run end-to-end against the real API — see [`examples/smoke.ts`](./examples/smoke.ts).
|
|
56
|
+
|
|
57
|
+
## Setup
|
|
58
|
+
|
|
59
|
+
Each tool factory accepts an optional config object, or falls back to environment variables (the same ones the underlying `context.dev` SDK reads):
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
contextSearch({ apiKey: "...", baseURL: "..." });
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
| Env var | Purpose |
|
|
66
|
+
|---|---|
|
|
67
|
+
| `CONTEXT_DEV_API_KEY` | Your context.dev API key. Required if `apiKey` isn't passed explicitly. |
|
|
68
|
+
| `CONTEXT_DEV_BASE_URL` | Override the API base URL. Optional. |
|
|
69
|
+
|
|
70
|
+
## Tools
|
|
71
|
+
|
|
72
|
+
Every code sample below calls `.execute()` directly (bypassing a model) purely to show real input/output shapes — in normal use you hand the tool to `generateText`/`streamText` and the model decides when to call it, as in [Quick start](#quick-start).
|
|
73
|
+
|
|
74
|
+
### `contextSearch`
|
|
75
|
+
|
|
76
|
+
Search the live web; returns structured results with relevance and (optionally) inline markdown.
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
await contextSearch().execute({ query: "context.dev pricing", numResults: 10 });
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
`numResults` must be between **10 and 100** (defaults to 10) — this is a real API-enforced minimum, not a suggestion; passing less throws a validation error.
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"results": [
|
|
87
|
+
{
|
|
88
|
+
"url": "https://www.context.dev/pricing",
|
|
89
|
+
"title": "Pricing - Simple & Scalable Plans",
|
|
90
|
+
"description": "Start free, build for $25, and scale to enterprise ・ $25/month Start building 10,000 credits per month...",
|
|
91
|
+
"relevance": "high",
|
|
92
|
+
"markdown": { "markdown": null, "code": "NOT_REQUESTED" }
|
|
93
|
+
}
|
|
94
|
+
]
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### `contextScrape`
|
|
99
|
+
|
|
100
|
+
Scrape one URL to clean Markdown, boilerplate stripped by default.
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
await contextScrape().execute({ url: "https://www.context.dev/pricing", useMainContentOnly: true });
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
```json
|
|
107
|
+
{
|
|
108
|
+
"success": true,
|
|
109
|
+
"markdown": "# Pricing that scales with your product\n\nStart with **250 credits...**\n\n### Free\n\nFor testing out the API\n\n$0/month\n..."
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### `contextCrawl`
|
|
114
|
+
|
|
115
|
+
Crawl a site from a starting URL, page by page, to Markdown. `maxPages` defaults to **10** here (well under the API's own cap of 500) so an agent can't trigger a large, credit-metered crawl by omission — raise it explicitly for bigger jobs. `maxDepth` accepts `0` (crawl only the starting page).
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
await contextCrawl().execute({ url: "https://www.context.dev/pricing", maxPages: 2 });
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"results": [
|
|
124
|
+
{
|
|
125
|
+
"markdown": "[New: Monitors. Watch any website for changes→](https://www.context.dev/blog/announcing-context-dev-monitors)\n\n[Context.dev](https://www.context.dev/)\n\nFeatures\n\n..."
|
|
126
|
+
}
|
|
127
|
+
]
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### `contextSitemap`
|
|
132
|
+
|
|
133
|
+
Discover a site's URLs via its sitemap; good for planning a crawl before running `contextCrawl`.
|
|
134
|
+
|
|
135
|
+
```ts
|
|
136
|
+
await contextSitemap().execute({ domain: "context.dev", maxLinks: 5 });
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
```json
|
|
140
|
+
{
|
|
141
|
+
"success": true,
|
|
142
|
+
"domain": "context.dev",
|
|
143
|
+
"urls": [
|
|
144
|
+
"https://www.context.dev",
|
|
145
|
+
"https://www.context.dev/pricing",
|
|
146
|
+
"https://www.context.dev/web-scraping-api",
|
|
147
|
+
"https://www.context.dev/data-extraction-api",
|
|
148
|
+
"https://www.context.dev/signup"
|
|
149
|
+
],
|
|
150
|
+
"meta": { "sitemapsDiscovered": 1, "sitemapsFetched": 1, "sitemapsSkipped": 0, "errors": 0 },
|
|
151
|
+
"key_metadata": { "credits_consumed": 1, "credits_remaining": 246 }
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Note `key_metadata` — every response includes live credit accounting, so an agent's logs can show exactly what a call cost.
|
|
156
|
+
|
|
157
|
+
### `contextExtract`
|
|
158
|
+
|
|
159
|
+
Extract structured data from a URL using a JSON Schema you provide. Under the hood this can crawl a handful of linked pages to fill the schema, which is why it costs more credits than a single scrape.
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
await contextExtract().execute({
|
|
163
|
+
url: "https://www.context.dev/pricing",
|
|
164
|
+
schema: { type: "object", properties: { plans: { type: "array", items: { type: "string" } } } },
|
|
165
|
+
});
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
```json
|
|
169
|
+
{
|
|
170
|
+
"status": "ok",
|
|
171
|
+
"url": "https://www.context.dev/pricing",
|
|
172
|
+
"urls_analyzed": ["https://www.context.dev/pricing", "https://www.context.dev/compare", "..."],
|
|
173
|
+
"data": { "plans": ["Free", "Developer", "Pro", "Scale", "Enterprise"] },
|
|
174
|
+
"metadata": { "numUrls": 5, "maxCrawlDepth": 1, "numSucceeded": 5, "numFailed": 0 },
|
|
175
|
+
"key_metadata": { "credits_consumed": 10, "credits_remaining": 234 }
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### `contextParse`
|
|
180
|
+
|
|
181
|
+
Parse an uploaded document (PDF, DOCX, PPTX, XLSX, HTML, CSV, and more) to Markdown. Input is a base64-encoded file.
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
const fileBase64 = Buffer.from("# Hello\n\nThis is a test document.").toString("base64");
|
|
185
|
+
await contextParse().execute({ fileBase64, extension: "md" });
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
```json
|
|
189
|
+
{
|
|
190
|
+
"success": true,
|
|
191
|
+
"markdown": "# Hello\n\nThis is a test document.",
|
|
192
|
+
"type": "markdown",
|
|
193
|
+
"key_metadata": { "credits_consumed": 1, "credits_remaining": 233 }
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### `contextScreenshot`
|
|
198
|
+
|
|
199
|
+
Screenshot a page (viewport or full-page) by domain or direct URL; returns an image URL, not raw bytes.
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
await contextScreenshot().execute({ domain: "context.dev" });
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
```json
|
|
206
|
+
{
|
|
207
|
+
"status": "ok",
|
|
208
|
+
"domain": "context.dev",
|
|
209
|
+
"screenshot": "https://media.brand.dev/screenshots/cache/18d2bd86ef6794b899022ec129f184d4.png",
|
|
210
|
+
"screenshotType": "viewport",
|
|
211
|
+
"width": 1920,
|
|
212
|
+
"height": 1080,
|
|
213
|
+
"cache_metadata": { "status": "hit", "age_ms": 50586303 }
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### `contextBrand`
|
|
218
|
+
|
|
219
|
+
Look up a company's brand profile by domain — description, colors, logos, and more. Only the by-domain lookup is exposed here (the underlying API also supports by-name/email/ticker).
|
|
220
|
+
|
|
221
|
+
```ts
|
|
222
|
+
await contextBrand().execute({ domain: "stripe.com" });
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
```json
|
|
226
|
+
{
|
|
227
|
+
"status": "ok",
|
|
228
|
+
"brand": {
|
|
229
|
+
"domain": "stripe.com",
|
|
230
|
+
"title": "Stripe",
|
|
231
|
+
"description": "Stripe is a global financial-infrastructure platform that enables businesses of all sizes to accept payments, manage billing, issue cards, and move money across borders...",
|
|
232
|
+
"slogan": "Financial infrastructure to grow your revenue.",
|
|
233
|
+
"colors": [
|
|
234
|
+
{ "hex": "#543cfc", "name": "Meteor Shower", "source": "logo" },
|
|
235
|
+
{ "hex": "#a494fc", "name": "Cobalite", "source": "logo" }
|
|
236
|
+
],
|
|
237
|
+
"logos": [{ "url": "https://media.brand.dev/46054561-c3dc-4220-ae40-a170bf6deda8.svg", "mode": "dark" }]
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### `contextNews`
|
|
243
|
+
|
|
244
|
+
Search recent news about a company by name, domain, or ticker.
|
|
245
|
+
|
|
246
|
+
```ts
|
|
247
|
+
await contextNews().execute({ entity: "Stripe", entityType: "name", limit: 2 });
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
```json
|
|
251
|
+
{
|
|
252
|
+
"data": [
|
|
253
|
+
{
|
|
254
|
+
"id": "8f8d0a7cce11510ef014dc29604b76721acda1c4c0da4a4ac18b8e2553c801c7",
|
|
255
|
+
"url": "https://techinasia.com/meet-16yearold-builder-caught-stripes-attention",
|
|
256
|
+
"title": "Meet the 16-year-old builder who caught Stripe's attention",
|
|
257
|
+
"published_at": "2026-08-31T08:30:39.000Z",
|
|
258
|
+
"source": { "name": "Tech in Asia", "domain": "techinasia.com", "direct": true },
|
|
259
|
+
"match": { "level": "primary", "confidence": 0.72 }
|
|
260
|
+
}
|
|
261
|
+
]
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## The `contextTools()` bundle
|
|
266
|
+
|
|
267
|
+
Pull in every tool at once instead of importing each individually:
|
|
268
|
+
|
|
269
|
+
```ts
|
|
270
|
+
import { generateText, stepCountIs } from "ai";
|
|
271
|
+
import { contextTools } from "context-dev-ai-tools";
|
|
272
|
+
|
|
273
|
+
const result = await generateText({
|
|
274
|
+
model: yourModel,
|
|
275
|
+
prompt: "...",
|
|
276
|
+
tools: { ...contextTools() },
|
|
277
|
+
stopWhen: stepCountIs(5),
|
|
278
|
+
});
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
`contextTools(config?)` applies the same config (API key, base URL) to every tool it returns.
|
|
282
|
+
|
|
283
|
+
## Error handling
|
|
284
|
+
|
|
285
|
+
Every tool's `execute` lets thrown errors propagate — the AI SDK automatically catches them and surfaces a `tool-error` step the model can react to (retry, apologize, try different arguments), so nothing is silently swallowed. Two exceptions are rewrapped with an actionable message before propagating: a `RateLimitError` becomes "context.dev rate limit reached...", and an `AuthenticationError` becomes "...check that CONTEXT_DEV_API_KEY is set correctly." Every other error (the context.dev SDK's typed `APIError` subclasses — 400/404/409/422/5xx) passes through unmodified.
|
|
286
|
+
|
|
287
|
+
## Not included (v1 scope)
|
|
288
|
+
|
|
289
|
+
This package deliberately covers the tools that make sense as single-call agent actions, not the full ~40-method context.dev API surface. Not exposed here: monitor management (create/update/list/webhooks — stateful, not a single-shot call), batch job submission/polling, people enrichment, NAICS/SIC industry classification, transaction enrichment, competitor/font/styleguide extraction, and brand lookup by name/email/ticker (only by-domain is exposed). Use the official [`context.dev`](https://www.npmjs.com/package/context.dev) SDK directly for those.
|
|
290
|
+
|
|
291
|
+
## TypeScript
|
|
292
|
+
|
|
293
|
+
Fully typed — every tool's input schema is a Zod object, and `contextTools()` is typed as a `Record` of AI SDK `Tool`s.
|
|
294
|
+
|
|
295
|
+
## Links
|
|
296
|
+
|
|
297
|
+
- [context.dev](https://www.context.dev/)
|
|
298
|
+
- [context.dev docs](https://docs.context.dev)
|
|
299
|
+
- [context.dev TypeScript SDK](https://github.com/context-dot-dev/context-typescript-sdk) (the dependency this package wraps)
|
|
300
|
+
- [Vercel AI SDK docs](https://ai-sdk.dev)
|
|
301
|
+
|
|
302
|
+
## License
|
|
303
|
+
|
|
304
|
+
MIT
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
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/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
contextBrand: () => contextBrand,
|
|
24
|
+
contextCrawl: () => contextCrawl,
|
|
25
|
+
contextExtract: () => contextExtract,
|
|
26
|
+
contextNews: () => contextNews,
|
|
27
|
+
contextParse: () => contextParse,
|
|
28
|
+
contextScrape: () => contextScrape,
|
|
29
|
+
contextScreenshot: () => contextScreenshot,
|
|
30
|
+
contextSearch: () => contextSearch,
|
|
31
|
+
contextSitemap: () => contextSitemap,
|
|
32
|
+
contextTools: () => contextTools
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(index_exports);
|
|
35
|
+
|
|
36
|
+
// src/tools/search.ts
|
|
37
|
+
var import_ai = require("ai");
|
|
38
|
+
var import_zod = require("zod");
|
|
39
|
+
|
|
40
|
+
// src/client.ts
|
|
41
|
+
var import_context = require("context.dev");
|
|
42
|
+
function createClient(config = {}) {
|
|
43
|
+
return new import_context.ContextDev({
|
|
44
|
+
apiKey: config.apiKey,
|
|
45
|
+
baseURL: config.baseURL
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
async function callContext(fn) {
|
|
49
|
+
try {
|
|
50
|
+
return await fn();
|
|
51
|
+
} catch (err) {
|
|
52
|
+
if (err instanceof import_context.RateLimitError) {
|
|
53
|
+
throw new Error(
|
|
54
|
+
"context.dev rate limit reached. Wait before retrying, reduce request frequency, or upgrade your plan."
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
if (err instanceof import_context.AuthenticationError) {
|
|
58
|
+
throw new Error(
|
|
59
|
+
"context.dev authentication failed. Check that CONTEXT_DEV_API_KEY is set to a valid key."
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
throw err;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// src/tools/search.ts
|
|
67
|
+
var inputSchema = import_zod.z.object({
|
|
68
|
+
query: import_zod.z.string().describe(
|
|
69
|
+
"Search query. Accepts natural language as well as Google-style operators such as site:, -site:, inurl:, intitle:, quoted phrases, and OR."
|
|
70
|
+
),
|
|
71
|
+
numResults: import_zod.z.number().int().min(10).max(100).optional().describe("Number of results to request (10-100). Defaults to 10."),
|
|
72
|
+
freshness: import_zod.z.enum(["last_24_hours", "last_week", "last_month", "last_year"]).optional().describe("Restrict results to content published within this window."),
|
|
73
|
+
includeDomains: import_zod.z.array(import_zod.z.string()).optional().describe('Allowlist domains, e.g. ["arxiv.org", "github.com"].'),
|
|
74
|
+
excludeDomains: import_zod.z.array(import_zod.z.string()).optional().describe('Blocklist domains, e.g. ["pinterest.com"].'),
|
|
75
|
+
country: import_zod.z.string().length(2).optional().describe("Two-letter ISO 3166-1 alpha-2 country code to localize results, e.g. 'us', 'gb', 'de'.")
|
|
76
|
+
});
|
|
77
|
+
var contextSearch = (config = {}) => {
|
|
78
|
+
const client = createClient(config);
|
|
79
|
+
return (0, import_ai.tool)({
|
|
80
|
+
description: "Search the live web and get back structured results (title, url, snippet) using context.dev's real-time search index.",
|
|
81
|
+
inputSchema,
|
|
82
|
+
execute: async ({ country, ...rest }) => callContext(
|
|
83
|
+
() => client.web.search({ ...rest, country })
|
|
84
|
+
)
|
|
85
|
+
});
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
// src/tools/scrape.ts
|
|
89
|
+
var import_ai2 = require("ai");
|
|
90
|
+
var import_zod2 = require("zod");
|
|
91
|
+
var inputSchema2 = import_zod2.z.object({
|
|
92
|
+
url: import_zod2.z.string().url().describe("Full URL to scrape into LLM-usable Markdown (must include http:// or https://)."),
|
|
93
|
+
includeImages: import_zod2.z.boolean().optional().describe("Include image references in the Markdown output."),
|
|
94
|
+
includeLinks: import_zod2.z.boolean().optional().describe("Preserve hyperlinks in the Markdown output."),
|
|
95
|
+
useMainContentOnly: import_zod2.z.boolean().optional().default(true).describe("Strip navigation, ads, and boilerplate, keeping only the main article/content region.")
|
|
96
|
+
});
|
|
97
|
+
var contextScrape = (config = {}) => {
|
|
98
|
+
const client = createClient(config);
|
|
99
|
+
return (0, import_ai2.tool)({
|
|
100
|
+
description: "Scrape a single URL and return clean Markdown with navigation and ads stripped, ready for LLM context.",
|
|
101
|
+
inputSchema: inputSchema2,
|
|
102
|
+
execute: async (input) => callContext(() => client.web.webScrapeMd(input))
|
|
103
|
+
});
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
// src/tools/crawl.ts
|
|
107
|
+
var import_ai3 = require("ai");
|
|
108
|
+
var import_zod3 = require("zod");
|
|
109
|
+
var inputSchema3 = import_zod3.z.object({
|
|
110
|
+
url: import_zod3.z.string().url().describe("The starting URL for the crawl (must include http:// or https://)."),
|
|
111
|
+
maxPages: import_zod3.z.number().int().min(1).max(500).optional().default(10).describe(
|
|
112
|
+
"Maximum number of pages to crawl. Defaults to 10 and is capped here well below the API's own ceiling \u2014 crawling is credit-metered per page, so an agent should not be able to trigger a large crawl without the caller raising this explicitly."
|
|
113
|
+
),
|
|
114
|
+
maxDepth: import_zod3.z.number().int().min(0).max(10).optional().describe("Maximum link depth from the starting URL (0 = only the starting page). No limit if omitted."),
|
|
115
|
+
urlRegex: import_zod3.z.string().optional().describe("Only crawl URLs matching this regular expression."),
|
|
116
|
+
followSubdomains: import_zod3.z.boolean().optional().describe("When true, also follow links on subdomains of the starting URL's domain.")
|
|
117
|
+
});
|
|
118
|
+
var contextCrawl = (config = {}) => {
|
|
119
|
+
const client = createClient(config);
|
|
120
|
+
return (0, import_ai3.tool)({
|
|
121
|
+
description: "Crawl a website starting from a URL and return clean Markdown for every reachable page, up to the given limits.",
|
|
122
|
+
inputSchema: inputSchema3,
|
|
123
|
+
execute: async (input) => callContext(() => client.web.webCrawlMd(input))
|
|
124
|
+
});
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
// src/tools/sitemap.ts
|
|
128
|
+
var import_ai4 = require("ai");
|
|
129
|
+
var import_zod4 = require("zod");
|
|
130
|
+
var inputSchema4 = import_zod4.z.object({
|
|
131
|
+
domain: import_zod4.z.string().describe("Domain to build/discover a sitemap for, e.g. 'example.com'."),
|
|
132
|
+
search: import_zod4.z.string().optional().describe("Optional search phrase; the sitemap is filtered to pages whose URLs are about that phrase, most relevant first."),
|
|
133
|
+
urlRegex: import_zod4.z.string().optional().describe("Only return URLs matching this regular expression."),
|
|
134
|
+
maxLinks: import_zod4.z.number().int().min(1).max(1e5).optional().describe("Maximum number of links to return. Defaults to 10,000.")
|
|
135
|
+
});
|
|
136
|
+
var contextSitemap = (config = {}) => {
|
|
137
|
+
const client = createClient(config);
|
|
138
|
+
return (0, import_ai4.tool)({
|
|
139
|
+
description: "Discover a website's URLs via its sitemap, optionally filtered by a search phrase or regex. Useful for planning a crawl before running contextCrawl.",
|
|
140
|
+
inputSchema: inputSchema4,
|
|
141
|
+
execute: async (input) => callContext(() => client.web.webScrapeSitemap(input))
|
|
142
|
+
});
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
// src/tools/extract.ts
|
|
146
|
+
var import_ai5 = require("ai");
|
|
147
|
+
var import_zod5 = require("zod");
|
|
148
|
+
var inputSchema5 = import_zod5.z.object({
|
|
149
|
+
url: import_zod5.z.string().url().describe("The starting website URL to crawl and extract structured data from (must include http:// or https://)."),
|
|
150
|
+
schema: import_zod5.z.record(import_zod5.z.string(), import_zod5.z.unknown()).describe(
|
|
151
|
+
"A JSON Schema object (not a Zod schema) describing the shape of data to extract, e.g. { type: 'object', properties: { price: { type: 'number' } } }."
|
|
152
|
+
),
|
|
153
|
+
instructions: import_zod5.z.string().optional().describe("Optional natural-language instructions to guide the extraction."),
|
|
154
|
+
factCheck: import_zod5.z.boolean().optional().describe("When true, every returned value must be grounded in facts stated on the page; ungrounded fields come back null/empty.")
|
|
155
|
+
});
|
|
156
|
+
var contextExtract = (config = {}) => {
|
|
157
|
+
const client = createClient(config);
|
|
158
|
+
return (0, import_ai5.tool)({
|
|
159
|
+
description: "Extract structured data from a URL according to a JSON Schema you provide.",
|
|
160
|
+
inputSchema: inputSchema5,
|
|
161
|
+
execute: async (input) => callContext(() => client.web.extract(input))
|
|
162
|
+
});
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
// src/tools/screenshot.ts
|
|
166
|
+
var import_ai6 = require("ai");
|
|
167
|
+
var import_zod6 = require("zod");
|
|
168
|
+
var inputSchema6 = import_zod6.z.object({
|
|
169
|
+
domain: import_zod6.z.string().optional().describe("Domain to screenshot, e.g. 'example.com'. Provide exactly one of domain or directUrl."),
|
|
170
|
+
directUrl: import_zod6.z.string().url().optional().describe("A specific URL to screenshot directly. Provide exactly one of domain or directUrl."),
|
|
171
|
+
fullScreenshot: import_zod6.z.boolean().optional().describe("Capture the full scrollable page instead of just the viewport."),
|
|
172
|
+
colorScheme: import_zod6.z.enum(["light", "dark"]).optional().describe("Force the site's light or dark visual theme before capture."),
|
|
173
|
+
clearPopups: import_zod6.z.boolean().optional().describe("Dismiss detected cookie/consent banners and other obstructive overlays before capture.")
|
|
174
|
+
}).refine((v) => v.domain ? !v.directUrl : !!v.directUrl, {
|
|
175
|
+
message: "Provide exactly one of `domain` or `directUrl`."
|
|
176
|
+
});
|
|
177
|
+
var contextScreenshot = (config = {}) => {
|
|
178
|
+
const client = createClient(config);
|
|
179
|
+
return (0, import_ai6.tool)({
|
|
180
|
+
description: "Capture a screenshot of a webpage (full page or viewport) and return an image URL.",
|
|
181
|
+
inputSchema: inputSchema6,
|
|
182
|
+
execute: async ({ domain, directUrl, fullScreenshot, ...rest }) => callContext(
|
|
183
|
+
() => client.web.screenshot({
|
|
184
|
+
...rest,
|
|
185
|
+
...domain ? { domain } : { directUrl },
|
|
186
|
+
...fullScreenshot !== void 0 && {
|
|
187
|
+
fullScreenshot: fullScreenshot ? "true" : "false"
|
|
188
|
+
}
|
|
189
|
+
})
|
|
190
|
+
)
|
|
191
|
+
});
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
// src/tools/brand.ts
|
|
195
|
+
var import_ai7 = require("ai");
|
|
196
|
+
var import_zod7 = require("zod");
|
|
197
|
+
var inputSchema7 = import_zod7.z.object({
|
|
198
|
+
domain: import_zod7.z.string().describe("Domain to retrieve brand data for, e.g. 'stripe.com'."),
|
|
199
|
+
maxSpeed: import_zod7.z.boolean().optional().describe("When true, skip time-consuming operations for a faster response at the cost of less comprehensive data.")
|
|
200
|
+
});
|
|
201
|
+
var contextBrand = (config = {}) => {
|
|
202
|
+
const client = createClient(config);
|
|
203
|
+
return (0, import_ai7.tool)({
|
|
204
|
+
description: "Look up a company's brand profile by domain \u2014 logo, colors, description, social profiles, and industry classification. Only the domain lookup variant is exposed; the underlying API also supports lookup by name/email/ticker.",
|
|
205
|
+
inputSchema: inputSchema7,
|
|
206
|
+
execute: async ({ domain, maxSpeed }) => callContext(() => client.brand.retrieve({ domain, type: "by_domain", maxSpeed }))
|
|
207
|
+
});
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
// src/tools/news.ts
|
|
211
|
+
var import_ai8 = require("ai");
|
|
212
|
+
var import_zod8 = require("zod");
|
|
213
|
+
var inputSchema8 = import_zod8.z.object({
|
|
214
|
+
entity: import_zod8.z.string().describe("The company to search news for \u2014 a name, domain, or stock ticker, matching `entityType`."),
|
|
215
|
+
entityType: import_zod8.z.enum(["name", "domain", "ticker"]).optional().default("name").describe("How to interpret `entity`. Defaults to 'name'."),
|
|
216
|
+
limit: import_zod8.z.number().int().min(1).max(50).optional().describe("Maximum articles to return. Defaults to 10."),
|
|
217
|
+
sortBy: import_zod8.z.enum(["relevance", "newest"]).optional().describe("Result ordering. Defaults to 'newest'.")
|
|
218
|
+
});
|
|
219
|
+
var contextNews = (config = {}) => {
|
|
220
|
+
const client = createClient(config);
|
|
221
|
+
return (0, import_ai8.tool)({
|
|
222
|
+
description: "Search recent news articles about a company, identified by name, domain, or stock ticker.",
|
|
223
|
+
inputSchema: inputSchema8,
|
|
224
|
+
execute: async ({ entity, entityType, limit, sortBy }) => callContext(
|
|
225
|
+
() => client.news.search({
|
|
226
|
+
searchBy: {
|
|
227
|
+
type: "entity",
|
|
228
|
+
entity: entityType === "domain" ? { type: "domain", domain: entity } : entityType === "ticker" ? { type: "ticker", ticker: entity } : { type: "name", name: entity }
|
|
229
|
+
},
|
|
230
|
+
limit,
|
|
231
|
+
sortBy: sortBy ? { type: sortBy } : void 0
|
|
232
|
+
})
|
|
233
|
+
)
|
|
234
|
+
});
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
// src/tools/parse.ts
|
|
238
|
+
var import_ai9 = require("ai");
|
|
239
|
+
var import_context2 = require("context.dev");
|
|
240
|
+
var import_zod9 = require("zod");
|
|
241
|
+
var inputSchema9 = import_zod9.z.object({
|
|
242
|
+
fileBase64: import_zod9.z.string().describe("The document's raw bytes, base64-encoded."),
|
|
243
|
+
extension: import_zod9.z.string().optional().describe("File extension hint, e.g. 'pdf', 'docx', 'xlsx', 'pptx', 'html', 'csv'. Helps the parser pick the right strategy."),
|
|
244
|
+
includeImages: import_zod9.z.boolean().optional().describe("Include image references in the Markdown output."),
|
|
245
|
+
includeLinks: import_zod9.z.boolean().optional().describe("Preserve hyperlinks in the Markdown output."),
|
|
246
|
+
ocr: import_zod9.z.boolean().optional().describe("For PDFs, OCR pages that have no usable text layer (scans) instead of skipping them.")
|
|
247
|
+
});
|
|
248
|
+
var contextParse = (config = {}) => {
|
|
249
|
+
const client = createClient(config);
|
|
250
|
+
return (0, import_ai9.tool)({
|
|
251
|
+
description: "Parse an uploaded document (PDF, DOCX, PPTX, XLSX, HTML, CSV, and more) into clean Markdown.",
|
|
252
|
+
inputSchema: inputSchema9,
|
|
253
|
+
execute: async ({ fileBase64, extension, ...rest }) => callContext(
|
|
254
|
+
async () => client.parse.handle(await (0, import_context2.toFile)(Buffer.from(fileBase64, "base64")), {
|
|
255
|
+
...rest,
|
|
256
|
+
extension
|
|
257
|
+
})
|
|
258
|
+
)
|
|
259
|
+
});
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
// src/index.ts
|
|
263
|
+
function contextTools(config = {}) {
|
|
264
|
+
return {
|
|
265
|
+
contextSearch: contextSearch(config),
|
|
266
|
+
contextScrape: contextScrape(config),
|
|
267
|
+
contextCrawl: contextCrawl(config),
|
|
268
|
+
contextSitemap: contextSitemap(config),
|
|
269
|
+
contextExtract: contextExtract(config),
|
|
270
|
+
contextScreenshot: contextScreenshot(config),
|
|
271
|
+
contextBrand: contextBrand(config),
|
|
272
|
+
contextNews: contextNews(config),
|
|
273
|
+
contextParse: contextParse(config)
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
277
|
+
0 && (module.exports = {
|
|
278
|
+
contextBrand,
|
|
279
|
+
contextCrawl,
|
|
280
|
+
contextExtract,
|
|
281
|
+
contextNews,
|
|
282
|
+
contextParse,
|
|
283
|
+
contextScrape,
|
|
284
|
+
contextScreenshot,
|
|
285
|
+
contextSearch,
|
|
286
|
+
contextSitemap,
|
|
287
|
+
contextTools
|
|
288
|
+
});
|
|
289
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/tools/search.ts","../src/client.ts","../src/tools/scrape.ts","../src/tools/crawl.ts","../src/tools/sitemap.ts","../src/tools/extract.ts","../src/tools/screenshot.ts","../src/tools/brand.ts","../src/tools/news.ts","../src/tools/parse.ts"],"sourcesContent":["import { contextSearch } from \"./tools/search.js\";\nimport { contextScrape } from \"./tools/scrape.js\";\nimport { contextCrawl } from \"./tools/crawl.js\";\nimport { contextSitemap } from \"./tools/sitemap.js\";\nimport { contextExtract } from \"./tools/extract.js\";\nimport { contextScreenshot } from \"./tools/screenshot.js\";\nimport { contextBrand } from \"./tools/brand.js\";\nimport { contextNews } from \"./tools/news.js\";\nimport { contextParse } from \"./tools/parse.js\";\nimport type { ContextToolConfig } from \"./types.js\";\n\nexport { contextSearch } from \"./tools/search.js\";\nexport { contextScrape } from \"./tools/scrape.js\";\nexport { contextCrawl } from \"./tools/crawl.js\";\nexport { contextSitemap } from \"./tools/sitemap.js\";\nexport { contextExtract } from \"./tools/extract.js\";\nexport { contextScreenshot } from \"./tools/screenshot.js\";\nexport { contextBrand } from \"./tools/brand.js\";\nexport { contextNews } from \"./tools/news.js\";\nexport { contextParse } from \"./tools/parse.js\";\nexport type { ContextToolConfig } from \"./types.js\";\n\n/**\n * Convenience bundle of every tool in this package, ready to spread into an\n * AI SDK `tools` object: `tools: { ...contextTools() }`.\n */\nexport function contextTools(config: ContextToolConfig = {}) {\n return {\n contextSearch: contextSearch(config),\n contextScrape: contextScrape(config),\n contextCrawl: contextCrawl(config),\n contextSitemap: contextSitemap(config),\n contextExtract: contextExtract(config),\n contextScreenshot: contextScreenshot(config),\n contextBrand: contextBrand(config),\n contextNews: contextNews(config),\n contextParse: contextParse(config),\n };\n}\n","import { tool } from \"ai\";\nimport type { WebSearchParams } from \"context.dev/resources/web\";\nimport { z } from \"zod\";\nimport { createClient, callContext } from \"../client.js\";\nimport type { ContextToolConfig } from \"../types.js\";\n\nconst inputSchema = z.object({\n query: z\n .string()\n .describe(\n \"Search query. Accepts natural language as well as Google-style operators such as site:, -site:, inurl:, intitle:, quoted phrases, and OR.\",\n ),\n numResults: z.number().int().min(10).max(100).optional().describe(\"Number of results to request (10-100). Defaults to 10.\"),\n freshness: z\n .enum([\"last_24_hours\", \"last_week\", \"last_month\", \"last_year\"])\n .optional()\n .describe(\"Restrict results to content published within this window.\"),\n includeDomains: z.array(z.string()).optional().describe('Allowlist domains, e.g. [\"arxiv.org\", \"github.com\"].'),\n excludeDomains: z.array(z.string()).optional().describe('Blocklist domains, e.g. [\"pinterest.com\"].'),\n country: z\n .string()\n .length(2)\n .optional()\n .describe(\"Two-letter ISO 3166-1 alpha-2 country code to localize results, e.g. 'us', 'gb', 'de'.\"),\n});\n\nexport const contextSearch = (config: ContextToolConfig = {}) => {\n const client = createClient(config);\n return tool({\n description: \"Search the live web and get back structured results (title, url, snippet) using context.dev's real-time search index.\",\n inputSchema,\n execute: async ({ country, ...rest }) =>\n callContext(() =>\n client.web.search({ ...rest, country: country as WebSearchParams[\"country\"] }),\n ),\n });\n};\n","import { ContextDev, AuthenticationError, RateLimitError } from \"context.dev\";\nimport type { ContextToolConfig } from \"./types.js\";\n\nexport function createClient(config: ContextToolConfig = {}): ContextDev {\n return new ContextDev({\n apiKey: config.apiKey,\n baseURL: config.baseURL,\n });\n}\n\n/**\n * Runs a context.dev SDK call and rewraps the two error types an agent can\n * plausibly self-correct from mid-run with an actionable message. Every other\n * error is left to throw as-is: the AI SDK catches thrown errors from `execute`\n * automatically and surfaces them to the model as a tool-error step, so no\n * broad try/catch belongs here.\n */\nexport async function callContext<T>(fn: () => Promise<T>): Promise<T> {\n try {\n return await fn();\n } catch (err) {\n if (err instanceof RateLimitError) {\n throw new Error(\n \"context.dev rate limit reached. Wait before retrying, reduce request frequency, or upgrade your plan.\",\n );\n }\n if (err instanceof AuthenticationError) {\n throw new Error(\n \"context.dev authentication failed. Check that CONTEXT_DEV_API_KEY is set to a valid key.\",\n );\n }\n throw err;\n }\n}\n","import { tool } from \"ai\";\nimport { z } from \"zod\";\nimport { createClient, callContext } from \"../client.js\";\nimport type { ContextToolConfig } from \"../types.js\";\n\nconst inputSchema = z.object({\n url: z.string().url().describe(\"Full URL to scrape into LLM-usable Markdown (must include http:// or https://).\"),\n includeImages: z.boolean().optional().describe(\"Include image references in the Markdown output.\"),\n includeLinks: z.boolean().optional().describe(\"Preserve hyperlinks in the Markdown output.\"),\n useMainContentOnly: z\n .boolean()\n .optional()\n .default(true)\n .describe(\"Strip navigation, ads, and boilerplate, keeping only the main article/content region.\"),\n});\n\nexport const contextScrape = (config: ContextToolConfig = {}) => {\n const client = createClient(config);\n return tool({\n description: \"Scrape a single URL and return clean Markdown with navigation and ads stripped, ready for LLM context.\",\n inputSchema,\n execute: async (input) => callContext(() => client.web.webScrapeMd(input)),\n });\n};\n","import { tool } from \"ai\";\nimport { z } from \"zod\";\nimport { createClient, callContext } from \"../client.js\";\nimport type { ContextToolConfig } from \"../types.js\";\n\nconst inputSchema = z.object({\n url: z.string().url().describe(\"The starting URL for the crawl (must include http:// or https://).\"),\n maxPages: z\n .number()\n .int()\n .min(1)\n .max(500)\n .optional()\n .default(10)\n .describe(\n \"Maximum number of pages to crawl. Defaults to 10 and is capped here well below the API's own ceiling — crawling is credit-metered per page, so an agent should not be able to trigger a large crawl without the caller raising this explicitly.\",\n ),\n maxDepth: z\n .number()\n .int()\n .min(0)\n .max(10)\n .optional()\n .describe(\"Maximum link depth from the starting URL (0 = only the starting page). No limit if omitted.\"),\n urlRegex: z.string().optional().describe(\"Only crawl URLs matching this regular expression.\"),\n followSubdomains: z\n .boolean()\n .optional()\n .describe(\"When true, also follow links on subdomains of the starting URL's domain.\"),\n});\n\nexport const contextCrawl = (config: ContextToolConfig = {}) => {\n const client = createClient(config);\n return tool({\n description: \"Crawl a website starting from a URL and return clean Markdown for every reachable page, up to the given limits.\",\n inputSchema,\n execute: async (input) => callContext(() => client.web.webCrawlMd(input)),\n });\n};\n","import { tool } from \"ai\";\nimport { z } from \"zod\";\nimport { createClient, callContext } from \"../client.js\";\nimport type { ContextToolConfig } from \"../types.js\";\n\nconst inputSchema = z.object({\n domain: z.string().describe(\"Domain to build/discover a sitemap for, e.g. 'example.com'.\"),\n search: z\n .string()\n .optional()\n .describe(\"Optional search phrase; the sitemap is filtered to pages whose URLs are about that phrase, most relevant first.\"),\n urlRegex: z.string().optional().describe(\"Only return URLs matching this regular expression.\"),\n maxLinks: z\n .number()\n .int()\n .min(1)\n .max(100_000)\n .optional()\n .describe(\"Maximum number of links to return. Defaults to 10,000.\"),\n});\n\nexport const contextSitemap = (config: ContextToolConfig = {}) => {\n const client = createClient(config);\n return tool({\n description: \"Discover a website's URLs via its sitemap, optionally filtered by a search phrase or regex. Useful for planning a crawl before running contextCrawl.\",\n inputSchema,\n execute: async (input) => callContext(() => client.web.webScrapeSitemap(input)),\n });\n};\n","import { tool } from \"ai\";\nimport { z } from \"zod\";\nimport { createClient, callContext } from \"../client.js\";\nimport type { ContextToolConfig } from \"../types.js\";\n\nconst inputSchema = z.object({\n url: z.string().url().describe(\"The starting website URL to crawl and extract structured data from (must include http:// or https://).\"),\n schema: z\n .record(z.string(), z.unknown())\n .describe(\n \"A JSON Schema object (not a Zod schema) describing the shape of data to extract, e.g. { type: 'object', properties: { price: { type: 'number' } } }.\",\n ),\n instructions: z.string().optional().describe(\"Optional natural-language instructions to guide the extraction.\"),\n factCheck: z\n .boolean()\n .optional()\n .describe(\"When true, every returned value must be grounded in facts stated on the page; ungrounded fields come back null/empty.\"),\n});\n\nexport const contextExtract = (config: ContextToolConfig = {}) => {\n const client = createClient(config);\n return tool({\n description: \"Extract structured data from a URL according to a JSON Schema you provide.\",\n inputSchema,\n execute: async (input) => callContext(() => client.web.extract(input)),\n });\n};\n","import { tool } from \"ai\";\nimport type { WebScreenshotParams } from \"context.dev/resources/web\";\nimport { z } from \"zod\";\nimport { createClient, callContext } from \"../client.js\";\nimport type { ContextToolConfig } from \"../types.js\";\n\nconst inputSchema = z\n .object({\n domain: z.string().optional().describe(\"Domain to screenshot, e.g. 'example.com'. Provide exactly one of domain or directUrl.\"),\n directUrl: z.string().url().optional().describe(\"A specific URL to screenshot directly. Provide exactly one of domain or directUrl.\"),\n fullScreenshot: z.boolean().optional().describe(\"Capture the full scrollable page instead of just the viewport.\"),\n colorScheme: z.enum([\"light\", \"dark\"]).optional().describe(\"Force the site's light or dark visual theme before capture.\"),\n clearPopups: z.boolean().optional().describe(\"Dismiss detected cookie/consent banners and other obstructive overlays before capture.\"),\n })\n .refine((v) => (v.domain ? !v.directUrl : !!v.directUrl), {\n message: \"Provide exactly one of `domain` or `directUrl`.\",\n });\n\nexport const contextScreenshot = (config: ContextToolConfig = {}) => {\n const client = createClient(config);\n return tool({\n description: \"Capture a screenshot of a webpage (full page or viewport) and return an image URL.\",\n inputSchema,\n execute: async ({ domain, directUrl, fullScreenshot, ...rest }) =>\n callContext(() =>\n client.web.screenshot({\n ...rest,\n ...(domain ? { domain } : { directUrl }),\n ...(fullScreenshot !== undefined && {\n fullScreenshot: (fullScreenshot ? \"true\" : \"false\") satisfies WebScreenshotParams[\"fullScreenshot\"],\n }),\n }),\n ),\n });\n};\n","import { tool } from \"ai\";\nimport { z } from \"zod\";\nimport { createClient, callContext } from \"../client.js\";\nimport type { ContextToolConfig } from \"../types.js\";\n\nconst inputSchema = z.object({\n domain: z.string().describe(\"Domain to retrieve brand data for, e.g. 'stripe.com'.\"),\n maxSpeed: z\n .boolean()\n .optional()\n .describe(\"When true, skip time-consuming operations for a faster response at the cost of less comprehensive data.\"),\n});\n\nexport const contextBrand = (config: ContextToolConfig = {}) => {\n const client = createClient(config);\n return tool({\n description:\n \"Look up a company's brand profile by domain — logo, colors, description, social profiles, and industry classification. Only the domain lookup variant is exposed; the underlying API also supports lookup by name/email/ticker.\",\n inputSchema,\n execute: async ({ domain, maxSpeed }) =>\n callContext(() => client.brand.retrieve({ domain, type: \"by_domain\", maxSpeed })),\n });\n};\n","import { tool } from \"ai\";\nimport { z } from \"zod\";\nimport { createClient, callContext } from \"../client.js\";\nimport type { ContextToolConfig } from \"../types.js\";\n\nconst inputSchema = z.object({\n entity: z.string().describe(\"The company to search news for — a name, domain, or stock ticker, matching `entityType`.\"),\n entityType: z\n .enum([\"name\", \"domain\", \"ticker\"])\n .optional()\n .default(\"name\")\n .describe(\"How to interpret `entity`. Defaults to 'name'.\"),\n limit: z.number().int().min(1).max(50).optional().describe(\"Maximum articles to return. Defaults to 10.\"),\n sortBy: z.enum([\"relevance\", \"newest\"]).optional().describe(\"Result ordering. Defaults to 'newest'.\"),\n});\n\nexport const contextNews = (config: ContextToolConfig = {}) => {\n const client = createClient(config);\n return tool({\n description: \"Search recent news articles about a company, identified by name, domain, or stock ticker.\",\n inputSchema,\n execute: async ({ entity, entityType, limit, sortBy }) =>\n callContext(() =>\n client.news.search({\n searchBy: {\n type: \"entity\",\n entity:\n entityType === \"domain\"\n ? { type: \"domain\", domain: entity }\n : entityType === \"ticker\"\n ? { type: \"ticker\", ticker: entity }\n : { type: \"name\", name: entity },\n },\n limit,\n sortBy: sortBy ? { type: sortBy } : undefined,\n }),\n ),\n });\n};\n","import { tool } from \"ai\";\nimport { toFile } from \"context.dev\";\nimport type { ParseHandleParams } from \"context.dev/resources/parse\";\nimport { z } from \"zod\";\nimport { createClient, callContext } from \"../client.js\";\nimport type { ContextToolConfig } from \"../types.js\";\n\nconst inputSchema = z.object({\n fileBase64: z.string().describe(\"The document's raw bytes, base64-encoded.\"),\n extension: z\n .string()\n .optional()\n .describe(\"File extension hint, e.g. 'pdf', 'docx', 'xlsx', 'pptx', 'html', 'csv'. Helps the parser pick the right strategy.\"),\n includeImages: z.boolean().optional().describe(\"Include image references in the Markdown output.\"),\n includeLinks: z.boolean().optional().describe(\"Preserve hyperlinks in the Markdown output.\"),\n ocr: z\n .boolean()\n .optional()\n .describe(\"For PDFs, OCR pages that have no usable text layer (scans) instead of skipping them.\"),\n});\n\nexport const contextParse = (config: ContextToolConfig = {}) => {\n const client = createClient(config);\n return tool({\n description: \"Parse an uploaded document (PDF, DOCX, PPTX, XLSX, HTML, CSV, and more) into clean Markdown.\",\n inputSchema,\n execute: async ({ fileBase64, extension, ...rest }) =>\n callContext(async () =>\n client.parse.handle(await toFile(Buffer.from(fileBase64, \"base64\")), {\n ...rest,\n extension: extension as ParseHandleParams[\"extension\"],\n }),\n ),\n });\n};\n"],"mappings":"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","names":["import_ai","import_zod","inputSchema","import_ai","import_zod","inputSchema","import_ai","import_zod","inputSchema","import_ai","import_zod","inputSchema","import_ai","import_zod","inputSchema","import_ai","import_zod","inputSchema","import_ai","import_zod","inputSchema","import_ai","import_context","import_zod","inputSchema"]}
|