@search1api/ai-sdk 0.1.1 → 0.2.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,8 +1,9 @@
1
1
  # Search1API tools for the Vercel AI SDK
2
2
 
3
- Add web search, news search, and webpage reading to an AI SDK agent. The tools
4
- use the official [`@search1api/client`](https://s1.dev/docs/integrations/sdks)
5
- for transport, retries, timeouts, and typed API errors.
3
+ Add web search, news search, webpage reading, and agentic search to an AI SDK
4
+ agent. The tools use the official
5
+ [`@search1api/client`](https://s1.dev/docs/integrations/sdks) for transport,
6
+ retries, timeouts, and typed API errors.
6
7
 
7
8
  ## Install
8
9
 
@@ -32,23 +33,58 @@ const result = await generateText({
32
33
  console.log(result.text);
33
34
  ```
34
35
 
35
- The tool set has three entries:
36
+ The tool set has four entries:
36
37
 
37
38
  | Tool | Model input | API | Output |
38
39
  | --- | --- | --- | --- |
39
- | `search` | `{ query }` | `/search` | Typed results with titles, links, and snippets |
40
- | `news` | `{ query }` | `/news` | Typed news results and source links |
40
+ | `search` | `{ query, search_service?, page?, max_results?, include_sites?, exclude_sites?, time_range? }` | `/search` | Typed results with titles, links, and snippets |
41
+ | `news` | Same fields as `search` except `page`, with news engines | `/news` | Typed news results and source links |
41
42
  | `crawl` | `{ url }` | `/crawl` | A page's title, URL, and readable content |
43
+ | `ask` | `{ query }` | `/ask` | Up to 10 results ranked by relevance, plus the engines and window used |
44
+
45
+ The model-facing parameters match the
46
+ [Search1API MCP server](https://s1.dev/docs/integrations/mcp). The model can
47
+ pick an engine (`google`, `bing`, `bingcn`, `duckduckgo`, `yahoo`, `yandex`,
48
+ `x`, `reddit`, `github`, `youtube`, `arxiv`, `wechat`, `bilibili`, `imdb`,
49
+ `wikipedia`, `grokipedia`; news supports `google`, `bing`, `duckduckgo`,
50
+ `yahoo`, and `hackernews`), return 1–50 results, request a later results page
51
+ (only `bing`, `bingcn`, `baidu`, and `grokipedia` paginate), scope or exclude
52
+ domains, and limit results to the past day, week, month, or year. Result page
53
+ crawling is not exposed to the model. Unknown arguments are ignored rather than
54
+ failing the call.
42
55
 
43
56
  Outputs preserve the API response, including optional publication dates,
44
- metadata, and content. Empty results remain empty. Ask the model to cite the
45
- returned links; these tools do not add AI SDK source events automatically.
57
+ GitHub and Hacker News fields, metadata, and content. Empty results remain
58
+ empty. Ask the model to cite the returned links; these tools do not add AI SDK
59
+ source events automatically. When an answer uses `grokipedia` results, credit
60
+ them as "Powered by xAI"; see
61
+ [Improving search results](https://s1.dev/docs/guides/improving-search-results).
62
+
63
+ ## Agentic search with ask
64
+
65
+ `ask` sends a natural-language request to
66
+ [`POST /ask`](https://s1.dev/docs/basic/ask). Search1API chooses up to five
67
+ engines and a time window, drops off-topic results, and returns at most 10
68
+ results ranked by relevance. Each call costs 5 credits, compared with 1 credit
69
+ for `search`. `ask` is in the default tool set, matching the MCP server; leave
70
+ it out with `only`, or create it on its own with `search1apiAsk()`:
71
+
72
+ ```ts
73
+ import { search1apiAsk, search1apiTools } from '@search1api/ai-sdk';
74
+
75
+ const withoutAsk = search1apiTools({ only: ['search', 'news', 'crawl'] });
76
+ const askOnly = { ask: search1apiAsk() };
77
+ ```
78
+
79
+ The SDK gives `ask` a 45-second timeout. `ask` is not available with
80
+ pay-per-request payments. Prefer `search` when the agent already knows the
81
+ engine and keywords.
46
82
 
47
83
  ## Configure one tool
48
84
 
49
- Applications control the engine, result count, domains, language, and time
50
- window. The model sees only the query or URL, so it cannot change those settings
51
- or enable extra result crawling.
85
+ Settings passed in code are defaults. When the model supplies the same
86
+ parameter, the model's value is used for that call; anything it omits falls
87
+ back to your settings.
52
88
 
53
89
  ```ts
54
90
  import { search1apiSearch, search1apiCrawl } from '@search1api/ai-sdk';
@@ -72,8 +108,8 @@ const tools = search1apiTools({
72
108
  });
73
109
  ```
74
110
 
75
- Search and news default to five results with `crawlResults: 0`. Set
76
- `search.crawlResults` or `news.crawlResults` explicitly when you want result page
111
+ Search and news default to ten results with `crawlResults: 0`. Set
112
+ `search.crawlResults` or `news.crawlResults` in code when you want result page
77
113
  content included. Each successful page retrieval incurs a separate crawl charge;
78
114
  see [pricing](https://s1.dev/pricing).
79
115
 
@@ -132,7 +168,7 @@ To verify the current version from the public registry, run
132
168
  `node scripts/verify-package.mjs --registry` after publication.
133
169
 
134
170
  To validate a local build, create and install the tarball with
135
- `npm pack` and `npm install /absolute/path/search1api-ai-sdk-0.1.0.tgz`.
171
+ `npm pack` and `npm install /absolute/path/search1api-ai-sdk-0.2.0.tgz`.
136
172
  Publication tracking is in [RELEASE.md](https://github.com/superagents-lab/search1api-ai-sdk/blob/main/RELEASE.md).
137
173
 
138
174
  ## License
package/dist/index.cjs CHANGED
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ search1apiAsk: () => search1apiAsk,
23
24
  search1apiCrawl: () => search1apiCrawl,
24
25
  search1apiNews: () => search1apiNews,
25
26
  search1apiSearch: () => search1apiSearch,
@@ -29,15 +30,85 @@ module.exports = __toCommonJS(index_exports);
29
30
  var import_client = require("@search1api/client");
30
31
  var import_ai = require("ai");
31
32
  var import_zod = require("zod");
32
- var querySchema = import_zod.z.object({
33
- query: import_zod.z.string().trim().min(1).describe("Search keywords or a specific question.")
34
- }).strict();
33
+ var SEARCH_ENGINES = [
34
+ "google",
35
+ "bing",
36
+ "bingcn",
37
+ "duckduckgo",
38
+ "yahoo",
39
+ "yandex",
40
+ "x",
41
+ "reddit",
42
+ "github",
43
+ "youtube",
44
+ "arxiv",
45
+ "wechat",
46
+ "bilibili",
47
+ "imdb",
48
+ "wikipedia",
49
+ "grokipedia"
50
+ ];
51
+ var NEWS_ENGINES = [
52
+ "google",
53
+ "bing",
54
+ "duckduckgo",
55
+ "yahoo",
56
+ "hackernews"
57
+ ];
58
+ function queryFields(kind) {
59
+ const noun = kind === "search" ? "results" : "articles";
60
+ return {
61
+ query: import_zod.z.string().trim().min(1).describe(`Short, focused ${kind} query`),
62
+ max_results: import_zod.z.number().int().min(1).max(50).optional().describe(`Maximum number of ${noun} to return`),
63
+ include_sites: import_zod.z.array(import_zod.z.string()).optional().describe(
64
+ kind === "search" ? "Domains to include when the user explicitly scopes the search" : "News domains to include"
65
+ ),
66
+ exclude_sites: import_zod.z.array(import_zod.z.string()).optional().describe(
67
+ kind === "search" ? "Domains to exclude from the search" : "News domains to exclude"
68
+ ),
69
+ time_range: import_zod.z.enum(["day", "week", "month", "year"]).optional().describe(
70
+ kind === "search" ? "Optional recency window for time-sensitive searches" : "Optional recency window; use day for breaking news"
71
+ )
72
+ };
73
+ }
74
+ var searchSchema = import_zod.z.object({
75
+ ...queryFields("search"),
76
+ search_service: import_zod.z.enum(SEARCH_ENGINES).optional().describe(
77
+ "Search engine to use; choose one only when it matches the user's source intent"
78
+ ),
79
+ page: import_zod.z.number().int().min(1).max(100).optional().describe(
80
+ "Results page to fetch; only bing, bingcn, baidu, and grokipedia paginate, other engines ignore it"
81
+ )
82
+ });
83
+ var newsSchema = import_zod.z.object({
84
+ ...queryFields("news"),
85
+ search_service: import_zod.z.enum(NEWS_ENGINES).optional().describe("News search engine to use")
86
+ });
35
87
  var crawlSchema = import_zod.z.object({
36
88
  url: import_zod.z.string().url().refine(
37
89
  (url) => ["http:", "https:"].includes(new URL(url).protocol),
38
90
  "Use an HTTP or HTTPS URL."
39
- ).describe("A public webpage URL, for example a link returned by search.")
40
- }).strict();
91
+ ).describe("Public HTTP or HTTPS URL to retrieve")
92
+ });
93
+ var askSchema = import_zod.z.object({
94
+ query: import_zod.z.string().trim().min(1).max(500).describe(
95
+ "Natural-language description of what to find, including any platform or time frame"
96
+ )
97
+ });
98
+ function requestOptions(defaults, input) {
99
+ const fromModel = {
100
+ searchService: input.search_service,
101
+ maxResults: input.max_results,
102
+ includeSites: input.include_sites,
103
+ excludeSites: input.exclude_sites,
104
+ timeRange: input.time_range,
105
+ page: input.page
106
+ };
107
+ const overrides = Object.fromEntries(
108
+ Object.entries(fromModel).filter(([, value]) => value !== void 0)
109
+ );
110
+ return { ...defaults, ...overrides };
111
+ }
41
112
  function clientGetter(options) {
42
113
  let client = options.client;
43
114
  const { client: _client, ...settings } = options;
@@ -54,26 +125,40 @@ function clientGetter(options) {
54
125
  };
55
126
  }
56
127
  function searchTool(getClient, settings = {}) {
57
- const options = { maxResults: 5, crawlResults: 0, ...settings };
128
+ const defaults = {
129
+ maxResults: 10,
130
+ crawlResults: 0,
131
+ ...settings
132
+ };
58
133
  return (0, import_ai.tool)({
59
- description: "Search the public web for current information and sources. Returns titles, links, and snippets. Use crawl to read a result page in full.",
60
- inputSchema: querySchema,
134
+ description: "Search the live public web when the user needs current information, sources, or research. Returns titles, links, and snippets. Use crawl to read a result page in full.",
135
+ inputSchema: searchSchema,
61
136
  execute: async (input, { abortSignal }) => {
62
137
  abortSignal?.throwIfAborted();
63
- const { query } = querySchema.parse(input);
64
- return getClient().search(query, options, { signal: abortSignal });
138
+ const parsed = searchSchema.parse(input);
139
+ return getClient().search(
140
+ parsed.query,
141
+ requestOptions(defaults, parsed),
142
+ { signal: abortSignal }
143
+ );
65
144
  }
66
145
  });
67
146
  }
68
147
  function newsTool(getClient, settings = {}) {
69
- const options = { maxResults: 5, crawlResults: 0, ...settings };
148
+ const defaults = {
149
+ maxResults: 10,
150
+ crawlResults: 0,
151
+ ...settings
152
+ };
70
153
  return (0, import_ai.tool)({
71
- description: "Search news coverage of recent events and announcements. Returns article titles, links, and snippets. Use crawl to read an article in full.",
72
- inputSchema: querySchema,
154
+ description: "Search current news when the user asks about recent events, announcements, or coverage. Returns article titles, links, and snippets. Use crawl to read an article in full.",
155
+ inputSchema: newsSchema,
73
156
  execute: async (input, { abortSignal }) => {
74
157
  abortSignal?.throwIfAborted();
75
- const { query } = querySchema.parse(input);
76
- return getClient().news(query, options, { signal: abortSignal });
158
+ const parsed = newsSchema.parse(input);
159
+ return getClient().news(parsed.query, requestOptions(defaults, parsed), {
160
+ signal: abortSignal
161
+ });
77
162
  }
78
163
  });
79
164
  }
@@ -89,6 +174,17 @@ function crawlTool(getClient, settings = {}) {
89
174
  }
90
175
  });
91
176
  }
177
+ function askTool(getClient) {
178
+ return (0, import_ai.tool)({
179
+ description: "Describe what you need in natural language; Search1API chooses up to five engines and a time window, then returns at most 10 results ranked by relevance, with the engines and window it used. Costs 5 credits per call. Use search instead when you already know the engine and keywords.",
180
+ inputSchema: askSchema,
181
+ execute: async (input, { abortSignal }) => {
182
+ abortSignal?.throwIfAborted();
183
+ const { query } = askSchema.parse(input);
184
+ return getClient().ask(query, { signal: abortSignal });
185
+ }
186
+ });
187
+ }
92
188
  function search1apiSearch(options = {}) {
93
189
  return searchTool(clientGetter(options), options.search);
94
190
  }
@@ -98,14 +194,18 @@ function search1apiNews(options = {}) {
98
194
  function search1apiCrawl(options = {}) {
99
195
  return crawlTool(clientGetter(options), options.crawl);
100
196
  }
197
+ function search1apiAsk(options = {}) {
198
+ return askTool(clientGetter(options));
199
+ }
101
200
  function search1apiTools(options = {}) {
102
201
  const getClient = clientGetter(options);
103
202
  const tools = {
104
203
  search: searchTool(getClient, options.search),
105
204
  news: newsTool(getClient, options.news),
106
- crawl: crawlTool(getClient, options.crawl)
205
+ crawl: crawlTool(getClient, options.crawl),
206
+ ask: askTool(getClient)
107
207
  };
108
- const names = options.only ?? ["search", "news", "crawl"];
208
+ const names = options.only ?? ["search", "news", "crawl", "ask"];
109
209
  const selected = {};
110
210
  for (const name of names) {
111
211
  if (!Object.hasOwn(tools, name)) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts"],
4
- "sourcesContent": ["import { Search1API } from '@search1api/client';\nimport type {\n CrawlOptions,\n CrawlResponse,\n NewsOptions,\n NewsResponse,\n Search1APIOptions,\n SearchOptions,\n SearchResponse,\n} from '@search1api/client';\nimport { tool } from 'ai';\nimport type { Tool } from 'ai';\nimport { z } from 'zod';\n\nexport interface Search1APIToolOptions extends Search1APIOptions {\n /** Reuse an existing client. When supplied, other client options are ignored. */\n client?: Search1API;\n}\n\nexport interface Search1APISearchOptions extends Search1APIToolOptions {\n /** Application-owned search settings; the model only supplies the query. */\n search?: SearchOptions;\n}\n\nexport interface Search1APINewsOptions extends Search1APIToolOptions {\n /** Application-owned news settings; the model only supplies the query. */\n news?: NewsOptions;\n}\n\nexport interface Search1APICrawlOptions extends Search1APIToolOptions {\n crawl?: CrawlOptions;\n}\n\nexport type QueryInput = { query: string };\nexport type CrawlInput = { url: string };\n\nconst querySchema = z\n .object({\n query: z\n .string()\n .trim()\n .min(1)\n .describe('Search keywords or a specific question.'),\n })\n .strict();\n\nconst crawlSchema = z\n .object({\n url: z\n .string()\n .url()\n .refine(\n (url) => ['http:', 'https:'].includes(new URL(url).protocol),\n 'Use an HTTP or HTTPS URL.'\n )\n .describe('A public webpage URL, for example a link returned by search.'),\n })\n .strict();\n\ntype ClientGetter = () => Search1API;\n\nfunction clientGetter(options: Search1APIToolOptions): ClientGetter {\n let client = options.client;\n const { client: _client, ...settings } = options;\n return () => {\n if (!client) {\n const processLike = globalThis as typeof globalThis & {\n process?: { env?: Record<string, string | undefined> };\n };\n const env = processLike.process?.env;\n client = new Search1API({\n ...settings,\n apiKey:\n settings.apiKey || env?.SEARCH1API_API_KEY || env?.SEARCH1API_KEY,\n });\n }\n return client;\n };\n}\n\nfunction searchTool(\n getClient: ClientGetter,\n settings: SearchOptions = {}\n): Tool<QueryInput, SearchResponse> {\n const options = { maxResults: 5, crawlResults: 0, ...settings };\n return tool({\n description:\n 'Search the public web for current information and sources. Returns titles, links, and snippets. Use crawl to read a result page in full.',\n inputSchema: querySchema,\n execute: async (input, { abortSignal }) => {\n abortSignal?.throwIfAborted();\n const { query } = querySchema.parse(input);\n return getClient().search(query, options, { signal: abortSignal });\n },\n });\n}\n\nfunction newsTool(\n getClient: ClientGetter,\n settings: NewsOptions = {}\n): Tool<QueryInput, NewsResponse> {\n const options = { maxResults: 5, crawlResults: 0, ...settings };\n return tool({\n description:\n 'Search news coverage of recent events and announcements. Returns article titles, links, and snippets. Use crawl to read an article in full.',\n inputSchema: querySchema,\n execute: async (input, { abortSignal }) => {\n abortSignal?.throwIfAborted();\n const { query } = querySchema.parse(input);\n return getClient().news(query, options, { signal: abortSignal });\n },\n });\n}\n\nfunction crawlTool(\n getClient: ClientGetter,\n settings: CrawlOptions = {}\n): Tool<CrawlInput, CrawlResponse> {\n const options = { ...settings };\n return tool({\n description:\n 'Read one public webpage and return its title, source URL, and readable content. Use a URL supplied by the user or returned by search or news.',\n inputSchema: crawlSchema,\n execute: async (input, { abortSignal }) => {\n abortSignal?.throwIfAborted();\n const { url } = crawlSchema.parse(input);\n return getClient().crawl(url, options, { signal: abortSignal });\n },\n });\n}\n\nexport function search1apiSearch(\n options: Search1APISearchOptions = {}\n): Tool<QueryInput, SearchResponse> {\n return searchTool(clientGetter(options), options.search);\n}\n\nexport function search1apiNews(\n options: Search1APINewsOptions = {}\n): Tool<QueryInput, NewsResponse> {\n return newsTool(clientGetter(options), options.news);\n}\n\nexport function search1apiCrawl(\n options: Search1APICrawlOptions = {}\n): Tool<CrawlInput, CrawlResponse> {\n return crawlTool(clientGetter(options), options.crawl);\n}\n\nexport interface Search1APIToolSet {\n search: Tool<QueryInput, SearchResponse>;\n news: Tool<QueryInput, NewsResponse>;\n crawl: Tool<CrawlInput, CrawlResponse>;\n}\n\nexport type Search1APIToolName = keyof Search1APIToolSet;\n\nexport interface Search1APIToolsOptions<\n Name extends Search1APIToolName = Search1APIToolName,\n> extends Search1APIToolOptions {\n /** Include only these tools. By default all three are included. */\n only?: readonly Name[];\n search?: SearchOptions;\n news?: NewsOptions;\n crawl?: CrawlOptions;\n}\n\nexport function search1apiTools<\n Name extends Search1APIToolName = Search1APIToolName,\n>(options: Search1APIToolsOptions<Name> = {}): Pick<Search1APIToolSet, Name> {\n const getClient = clientGetter(options);\n const tools: Search1APIToolSet = {\n search: searchTool(getClient, options.search),\n news: newsTool(getClient, options.news),\n crawl: crawlTool(getClient, options.crawl),\n };\n const names = options.only ?? (['search', 'news', 'crawl'] as const);\n const selected = {} as Pick<Search1APIToolSet, Name>;\n for (const name of names) {\n if (!Object.hasOwn(tools, name)) {\n throw new Error(`Unknown Search1API tool: ${name}`);\n }\n Object.assign(selected, { [name]: tools[name] });\n }\n return selected;\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA2B;AAU3B,gBAAqB;AAErB,iBAAkB;AAwBlB,IAAM,cAAc,aACjB,OAAO;AAAA,EACN,OAAO,aACJ,OAAO,EACP,KAAK,EACL,IAAI,CAAC,EACL,SAAS,yCAAyC;AACvD,CAAC,EACA,OAAO;AAEV,IAAM,cAAc,aACjB,OAAO;AAAA,EACN,KAAK,aACF,OAAO,EACP,IAAI,EACJ;AAAA,IACC,CAAC,QAAQ,CAAC,SAAS,QAAQ,EAAE,SAAS,IAAI,IAAI,GAAG,EAAE,QAAQ;AAAA,IAC3D;AAAA,EACF,EACC,SAAS,8DAA8D;AAC5E,CAAC,EACA,OAAO;AAIV,SAAS,aAAa,SAA8C;AAClE,MAAI,SAAS,QAAQ;AACrB,QAAM,EAAE,QAAQ,SAAS,GAAG,SAAS,IAAI;AACzC,SAAO,MAAM;AACX,QAAI,CAAC,QAAQ;AACX,YAAM,cAAc;AAGpB,YAAM,MAAM,YAAY,SAAS;AACjC,eAAS,IAAI,yBAAW;AAAA,QACtB,GAAG;AAAA,QACH,QACE,SAAS,UAAU,KAAK,sBAAsB,KAAK;AAAA,MACvD,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AACF;AAEA,SAAS,WACP,WACA,WAA0B,CAAC,GACO;AAClC,QAAM,UAAU,EAAE,YAAY,GAAG,cAAc,GAAG,GAAG,SAAS;AAC9D,aAAO,gBAAK;AAAA,IACV,aACE;AAAA,IACF,aAAa;AAAA,IACb,SAAS,OAAO,OAAO,EAAE,YAAY,MAAM;AACzC,mBAAa,eAAe;AAC5B,YAAM,EAAE,MAAM,IAAI,YAAY,MAAM,KAAK;AACzC,aAAO,UAAU,EAAE,OAAO,OAAO,SAAS,EAAE,QAAQ,YAAY,CAAC;AAAA,IACnE;AAAA,EACF,CAAC;AACH;AAEA,SAAS,SACP,WACA,WAAwB,CAAC,GACO;AAChC,QAAM,UAAU,EAAE,YAAY,GAAG,cAAc,GAAG,GAAG,SAAS;AAC9D,aAAO,gBAAK;AAAA,IACV,aACE;AAAA,IACF,aAAa;AAAA,IACb,SAAS,OAAO,OAAO,EAAE,YAAY,MAAM;AACzC,mBAAa,eAAe;AAC5B,YAAM,EAAE,MAAM,IAAI,YAAY,MAAM,KAAK;AACzC,aAAO,UAAU,EAAE,KAAK,OAAO,SAAS,EAAE,QAAQ,YAAY,CAAC;AAAA,IACjE;AAAA,EACF,CAAC;AACH;AAEA,SAAS,UACP,WACA,WAAyB,CAAC,GACO;AACjC,QAAM,UAAU,EAAE,GAAG,SAAS;AAC9B,aAAO,gBAAK;AAAA,IACV,aACE;AAAA,IACF,aAAa;AAAA,IACb,SAAS,OAAO,OAAO,EAAE,YAAY,MAAM;AACzC,mBAAa,eAAe;AAC5B,YAAM,EAAE,IAAI,IAAI,YAAY,MAAM,KAAK;AACvC,aAAO,UAAU,EAAE,MAAM,KAAK,SAAS,EAAE,QAAQ,YAAY,CAAC;AAAA,IAChE;AAAA,EACF,CAAC;AACH;AAEO,SAAS,iBACd,UAAmC,CAAC,GACF;AAClC,SAAO,WAAW,aAAa,OAAO,GAAG,QAAQ,MAAM;AACzD;AAEO,SAAS,eACd,UAAiC,CAAC,GACF;AAChC,SAAO,SAAS,aAAa,OAAO,GAAG,QAAQ,IAAI;AACrD;AAEO,SAAS,gBACd,UAAkC,CAAC,GACF;AACjC,SAAO,UAAU,aAAa,OAAO,GAAG,QAAQ,KAAK;AACvD;AAoBO,SAAS,gBAEd,UAAwC,CAAC,GAAkC;AAC3E,QAAM,YAAY,aAAa,OAAO;AACtC,QAAM,QAA2B;AAAA,IAC/B,QAAQ,WAAW,WAAW,QAAQ,MAAM;AAAA,IAC5C,MAAM,SAAS,WAAW,QAAQ,IAAI;AAAA,IACtC,OAAO,UAAU,WAAW,QAAQ,KAAK;AAAA,EAC3C;AACA,QAAM,QAAQ,QAAQ,QAAS,CAAC,UAAU,QAAQ,OAAO;AACzD,QAAM,WAAW,CAAC;AAClB,aAAW,QAAQ,OAAO;AACxB,QAAI,CAAC,OAAO,OAAO,OAAO,IAAI,GAAG;AAC/B,YAAM,IAAI,MAAM,4BAA4B,IAAI,EAAE;AAAA,IACpD;AACA,WAAO,OAAO,UAAU,EAAE,CAAC,IAAI,GAAG,MAAM,IAAI,EAAE,CAAC;AAAA,EACjD;AACA,SAAO;AACT;",
4
+ "sourcesContent": ["import { Search1API } from '@search1api/client';\nimport type {\n AskResponse,\n CrawlOptions,\n CrawlResponse,\n NewsOptions,\n NewsResponse,\n Search1APIOptions,\n SearchOptions,\n SearchResponse,\n} from '@search1api/client';\nimport { tool } from 'ai';\nimport type { Tool } from 'ai';\nimport { z } from 'zod';\n\nexport interface Search1APIToolOptions extends Search1APIOptions {\n /** Reuse an existing client. When supplied, other client options are ignored. */\n client?: Search1API;\n}\n\nexport interface Search1APISearchOptions extends Search1APIToolOptions {\n /** Default search settings; values the model supplies take precedence. */\n search?: SearchOptions;\n}\n\nexport interface Search1APINewsOptions extends Search1APIToolOptions {\n /** Default news settings; values the model supplies take precedence. */\n news?: NewsOptions;\n}\n\nexport interface Search1APICrawlOptions extends Search1APIToolOptions {\n crawl?: CrawlOptions;\n}\n\nexport type CrawlInput = { url: string };\nexport type AskInput = { query: string };\n\n// Model-facing parameters mirror the Search1API MCP server's tool schemas,\n// except result crawling, which only application settings can enable.\nconst SEARCH_ENGINES = [\n 'google',\n 'bing',\n 'bingcn',\n 'duckduckgo',\n 'yahoo',\n 'yandex',\n 'x',\n 'reddit',\n 'github',\n 'youtube',\n 'arxiv',\n 'wechat',\n 'bilibili',\n 'imdb',\n 'wikipedia',\n 'grokipedia',\n] as const;\nconst NEWS_ENGINES = [\n 'google',\n 'bing',\n 'duckduckgo',\n 'yahoo',\n 'hackernews',\n] as const;\n\nfunction queryFields(kind: 'search' | 'news') {\n const noun = kind === 'search' ? 'results' : 'articles';\n return {\n query: z\n .string()\n .trim()\n .min(1)\n .describe(`Short, focused ${kind} query`),\n max_results: z\n .number()\n .int()\n .min(1)\n .max(50)\n .optional()\n .describe(`Maximum number of ${noun} to return`),\n include_sites: z\n .array(z.string())\n .optional()\n .describe(\n kind === 'search'\n ? 'Domains to include when the user explicitly scopes the search'\n : 'News domains to include'\n ),\n exclude_sites: z\n .array(z.string())\n .optional()\n .describe(\n kind === 'search'\n ? 'Domains to exclude from the search'\n : 'News domains to exclude'\n ),\n time_range: z\n .enum(['day', 'week', 'month', 'year'])\n .optional()\n .describe(\n kind === 'search'\n ? 'Optional recency window for time-sensitive searches'\n : 'Optional recency window; use day for breaking news'\n ),\n };\n}\n\n// Unknown keys are stripped rather than rejected so a stray argument does not\n// cost the agent a retry step.\nconst searchSchema = z.object({\n ...queryFields('search'),\n search_service: z\n .enum(SEARCH_ENGINES)\n .optional()\n .describe(\n \"Search engine to use; choose one only when it matches the user's source intent\"\n ),\n page: z\n .number()\n .int()\n .min(1)\n .max(100)\n .optional()\n .describe(\n 'Results page to fetch; only bing, bingcn, baidu, and grokipedia paginate, other engines ignore it'\n ),\n});\n\nconst newsSchema = z.object({\n ...queryFields('news'),\n search_service: z\n .enum(NEWS_ENGINES)\n .optional()\n .describe('News search engine to use'),\n});\n\nconst crawlSchema = z.object({\n url: z\n .string()\n .url()\n .refine(\n (url) => ['http:', 'https:'].includes(new URL(url).protocol),\n 'Use an HTTP or HTTPS URL.'\n )\n .describe('Public HTTP or HTTPS URL to retrieve'),\n});\n\nconst askSchema = z.object({\n query: z\n .string()\n .trim()\n .min(1)\n .max(500)\n .describe(\n 'Natural-language description of what to find, including any platform or time frame'\n ),\n});\n\nexport type SearchInput = z.input<typeof searchSchema>;\nexport type NewsInput = z.input<typeof newsSchema>;\n\ntype ModelQueryInput =\n | z.output<typeof searchSchema>\n | (z.output<typeof newsSchema> & { page?: undefined });\n\n// Merge model-supplied values over application defaults, dropping omitted keys.\nfunction requestOptions<Options extends SearchOptions | NewsOptions>(\n defaults: Options,\n input: ModelQueryInput\n): Options {\n const fromModel = {\n searchService: input.search_service,\n maxResults: input.max_results,\n includeSites: input.include_sites,\n excludeSites: input.exclude_sites,\n timeRange: input.time_range,\n page: input.page,\n };\n const overrides = Object.fromEntries(\n Object.entries(fromModel).filter(([, value]) => value !== undefined)\n );\n return { ...defaults, ...overrides } as Options;\n}\n\ntype ClientGetter = () => Search1API;\n\nfunction clientGetter(options: Search1APIToolOptions): ClientGetter {\n let client = options.client;\n const { client: _client, ...settings } = options;\n return () => {\n if (!client) {\n const processLike = globalThis as typeof globalThis & {\n process?: { env?: Record<string, string | undefined> };\n };\n const env = processLike.process?.env;\n client = new Search1API({\n ...settings,\n apiKey:\n settings.apiKey || env?.SEARCH1API_API_KEY || env?.SEARCH1API_KEY,\n });\n }\n return client;\n };\n}\n\nfunction searchTool(\n getClient: ClientGetter,\n settings: SearchOptions = {}\n): Tool<SearchInput, SearchResponse> {\n const defaults: SearchOptions = {\n maxResults: 10,\n crawlResults: 0,\n ...settings,\n };\n return tool({\n description:\n 'Search the live public web when the user needs current information, sources, or research. Returns titles, links, and snippets. Use crawl to read a result page in full.',\n inputSchema: searchSchema,\n execute: async (input, { abortSignal }) => {\n abortSignal?.throwIfAborted();\n const parsed = searchSchema.parse(input);\n return getClient().search(\n parsed.query,\n requestOptions(defaults, parsed),\n { signal: abortSignal }\n );\n },\n });\n}\n\nfunction newsTool(\n getClient: ClientGetter,\n settings: NewsOptions = {}\n): Tool<NewsInput, NewsResponse> {\n const defaults: NewsOptions = {\n maxResults: 10,\n crawlResults: 0,\n ...settings,\n };\n return tool({\n description:\n 'Search current news when the user asks about recent events, announcements, or coverage. Returns article titles, links, and snippets. Use crawl to read an article in full.',\n inputSchema: newsSchema,\n execute: async (input, { abortSignal }) => {\n abortSignal?.throwIfAborted();\n const parsed = newsSchema.parse(input);\n return getClient().news(parsed.query, requestOptions(defaults, parsed), {\n signal: abortSignal,\n });\n },\n });\n}\n\nfunction crawlTool(\n getClient: ClientGetter,\n settings: CrawlOptions = {}\n): Tool<CrawlInput, CrawlResponse> {\n const options = { ...settings };\n return tool({\n description:\n 'Read one public webpage and return its title, source URL, and readable content. Use a URL supplied by the user or returned by search or news.',\n inputSchema: crawlSchema,\n execute: async (input, { abortSignal }) => {\n abortSignal?.throwIfAborted();\n const { url } = crawlSchema.parse(input);\n return getClient().crawl(url, options, { signal: abortSignal });\n },\n });\n}\n\nfunction askTool(getClient: ClientGetter): Tool<AskInput, AskResponse> {\n return tool({\n description:\n 'Describe what you need in natural language; Search1API chooses up to five engines and a time window, then returns at most 10 results ranked by relevance, with the engines and window it used. Costs 5 credits per call. Use search instead when you already know the engine and keywords.',\n inputSchema: askSchema,\n execute: async (input, { abortSignal }) => {\n abortSignal?.throwIfAborted();\n const { query } = askSchema.parse(input);\n return getClient().ask(query, { signal: abortSignal });\n },\n });\n}\n\nexport function search1apiSearch(\n options: Search1APISearchOptions = {}\n): Tool<SearchInput, SearchResponse> {\n return searchTool(clientGetter(options), options.search);\n}\n\nexport function search1apiNews(\n options: Search1APINewsOptions = {}\n): Tool<NewsInput, NewsResponse> {\n return newsTool(clientGetter(options), options.news);\n}\n\nexport function search1apiCrawl(\n options: Search1APICrawlOptions = {}\n): Tool<CrawlInput, CrawlResponse> {\n return crawlTool(clientGetter(options), options.crawl);\n}\n\n/** Agentic search through `POST /ask`. Costs 5 credits per call. */\nexport function search1apiAsk(\n options: Search1APIToolOptions = {}\n): Tool<AskInput, AskResponse> {\n return askTool(clientGetter(options));\n}\n\nexport interface Search1APIToolSet {\n search: Tool<SearchInput, SearchResponse>;\n news: Tool<NewsInput, NewsResponse>;\n crawl: Tool<CrawlInput, CrawlResponse>;\n ask: Tool<AskInput, AskResponse>;\n}\n\nexport type Search1APIToolName = keyof Search1APIToolSet;\n\nexport interface Search1APIToolsOptions<\n Name extends Search1APIToolName = Search1APIToolName,\n> extends Search1APIToolOptions {\n /** Include only these tools. By default all four are included. */\n only?: readonly Name[];\n search?: SearchOptions;\n news?: NewsOptions;\n crawl?: CrawlOptions;\n}\n\nexport function search1apiTools<\n Name extends Search1APIToolName = Search1APIToolName,\n>(options: Search1APIToolsOptions<Name> = {}): Pick<Search1APIToolSet, Name> {\n const getClient = clientGetter(options);\n const tools: Search1APIToolSet = {\n search: searchTool(getClient, options.search),\n news: newsTool(getClient, options.news),\n crawl: crawlTool(getClient, options.crawl),\n ask: askTool(getClient),\n };\n const names =\n options.only ?? (['search', 'news', 'crawl', 'ask'] as const);\n const selected = {} as Pick<Search1APIToolSet, Name>;\n for (const name of names) {\n if (!Object.hasOwn(tools, name)) {\n throw new Error(`Unknown Search1API tool: ${name}`);\n }\n Object.assign(selected, { [name]: tools[name] });\n }\n return selected;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/dist/index.d.ts CHANGED
@@ -1,42 +1,99 @@
1
1
  import { Search1API } from '@search1api/client';
2
- import type { CrawlOptions, CrawlResponse, NewsOptions, NewsResponse, Search1APIOptions, SearchOptions, SearchResponse } from '@search1api/client';
2
+ import type { AskResponse, CrawlOptions, CrawlResponse, NewsOptions, NewsResponse, Search1APIOptions, SearchOptions, SearchResponse } from '@search1api/client';
3
3
  import type { Tool } from 'ai';
4
+ import { z } from 'zod';
4
5
  export interface Search1APIToolOptions extends Search1APIOptions {
5
6
  /** Reuse an existing client. When supplied, other client options are ignored. */
6
7
  client?: Search1API;
7
8
  }
8
9
  export interface Search1APISearchOptions extends Search1APIToolOptions {
9
- /** Application-owned search settings; the model only supplies the query. */
10
+ /** Default search settings; values the model supplies take precedence. */
10
11
  search?: SearchOptions;
11
12
  }
12
13
  export interface Search1APINewsOptions extends Search1APIToolOptions {
13
- /** Application-owned news settings; the model only supplies the query. */
14
+ /** Default news settings; values the model supplies take precedence. */
14
15
  news?: NewsOptions;
15
16
  }
16
17
  export interface Search1APICrawlOptions extends Search1APIToolOptions {
17
18
  crawl?: CrawlOptions;
18
19
  }
19
- export type QueryInput = {
20
- query: string;
21
- };
22
20
  export type CrawlInput = {
23
21
  url: string;
24
22
  };
25
- export declare function search1apiSearch(options?: Search1APISearchOptions): Tool<QueryInput, SearchResponse>;
26
- export declare function search1apiNews(options?: Search1APINewsOptions): Tool<QueryInput, NewsResponse>;
23
+ export type AskInput = {
24
+ query: string;
25
+ };
26
+ declare const searchSchema: z.ZodObject<{
27
+ search_service: z.ZodOptional<z.ZodEnum<{
28
+ google: "google";
29
+ bing: "bing";
30
+ bingcn: "bingcn";
31
+ duckduckgo: "duckduckgo";
32
+ yahoo: "yahoo";
33
+ yandex: "yandex";
34
+ x: "x";
35
+ reddit: "reddit";
36
+ github: "github";
37
+ youtube: "youtube";
38
+ arxiv: "arxiv";
39
+ wechat: "wechat";
40
+ bilibili: "bilibili";
41
+ imdb: "imdb";
42
+ wikipedia: "wikipedia";
43
+ grokipedia: "grokipedia";
44
+ }>>;
45
+ page: z.ZodOptional<z.ZodNumber>;
46
+ query: z.ZodString;
47
+ max_results: z.ZodOptional<z.ZodNumber>;
48
+ include_sites: z.ZodOptional<z.ZodArray<z.ZodString>>;
49
+ exclude_sites: z.ZodOptional<z.ZodArray<z.ZodString>>;
50
+ time_range: z.ZodOptional<z.ZodEnum<{
51
+ day: "day";
52
+ week: "week";
53
+ month: "month";
54
+ year: "year";
55
+ }>>;
56
+ }, z.core.$strip>;
57
+ declare const newsSchema: z.ZodObject<{
58
+ search_service: z.ZodOptional<z.ZodEnum<{
59
+ google: "google";
60
+ bing: "bing";
61
+ duckduckgo: "duckduckgo";
62
+ yahoo: "yahoo";
63
+ hackernews: "hackernews";
64
+ }>>;
65
+ query: z.ZodString;
66
+ max_results: z.ZodOptional<z.ZodNumber>;
67
+ include_sites: z.ZodOptional<z.ZodArray<z.ZodString>>;
68
+ exclude_sites: z.ZodOptional<z.ZodArray<z.ZodString>>;
69
+ time_range: z.ZodOptional<z.ZodEnum<{
70
+ day: "day";
71
+ week: "week";
72
+ month: "month";
73
+ year: "year";
74
+ }>>;
75
+ }, z.core.$strip>;
76
+ export type SearchInput = z.input<typeof searchSchema>;
77
+ export type NewsInput = z.input<typeof newsSchema>;
78
+ export declare function search1apiSearch(options?: Search1APISearchOptions): Tool<SearchInput, SearchResponse>;
79
+ export declare function search1apiNews(options?: Search1APINewsOptions): Tool<NewsInput, NewsResponse>;
27
80
  export declare function search1apiCrawl(options?: Search1APICrawlOptions): Tool<CrawlInput, CrawlResponse>;
81
+ /** Agentic search through `POST /ask`. Costs 5 credits per call. */
82
+ export declare function search1apiAsk(options?: Search1APIToolOptions): Tool<AskInput, AskResponse>;
28
83
  export interface Search1APIToolSet {
29
- search: Tool<QueryInput, SearchResponse>;
30
- news: Tool<QueryInput, NewsResponse>;
84
+ search: Tool<SearchInput, SearchResponse>;
85
+ news: Tool<NewsInput, NewsResponse>;
31
86
  crawl: Tool<CrawlInput, CrawlResponse>;
87
+ ask: Tool<AskInput, AskResponse>;
32
88
  }
33
89
  export type Search1APIToolName = keyof Search1APIToolSet;
34
90
  export interface Search1APIToolsOptions<Name extends Search1APIToolName = Search1APIToolName> extends Search1APIToolOptions {
35
- /** Include only these tools. By default all three are included. */
91
+ /** Include only these tools. By default all four are included. */
36
92
  only?: readonly Name[];
37
93
  search?: SearchOptions;
38
94
  news?: NewsOptions;
39
95
  crawl?: CrawlOptions;
40
96
  }
41
97
  export declare function search1apiTools<Name extends Search1APIToolName = Search1APIToolName>(options?: Search1APIToolsOptions<Name>): Pick<Search1APIToolSet, Name>;
98
+ export {};
42
99
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,aAAa,EACb,cAAc,EACf,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAG/B,MAAM,WAAW,qBAAsB,SAAQ,iBAAiB;IAC9D,iFAAiF;IACjF,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,uBAAwB,SAAQ,qBAAqB;IACpE,4EAA4E;IAC5E,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,MAAM,WAAW,qBAAsB,SAAQ,qBAAqB;IAClE,0EAA0E;IAC1E,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB;AAED,MAAM,WAAW,sBAAuB,SAAQ,qBAAqB;IACnE,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAED,MAAM,MAAM,UAAU,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAC3C,MAAM,MAAM,UAAU,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAiGzC,wBAAgB,gBAAgB,CAC9B,OAAO,GAAE,uBAA4B,GACpC,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAElC;AAED,wBAAgB,cAAc,CAC5B,OAAO,GAAE,qBAA0B,GAClC,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAEhC;AAED,wBAAgB,eAAe,CAC7B,OAAO,GAAE,sBAA2B,GACnC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAEjC;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;IACzC,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IACrC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;CACxC;AAED,MAAM,MAAM,kBAAkB,GAAG,MAAM,iBAAiB,CAAC;AAEzD,MAAM,WAAW,sBAAsB,CACrC,IAAI,SAAS,kBAAkB,GAAG,kBAAkB,CACpD,SAAQ,qBAAqB;IAC7B,mEAAmE;IACnE,IAAI,CAAC,EAAE,SAAS,IAAI,EAAE,CAAC;IACvB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAED,wBAAgB,eAAe,CAC7B,IAAI,SAAS,kBAAkB,GAAG,kBAAkB,EACpD,OAAO,GAAE,sBAAsB,CAAC,IAAI,CAAM,GAAG,IAAI,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAgB3E"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EACZ,aAAa,EACb,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,aAAa,EACb,cAAc,EACf,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,WAAW,qBAAsB,SAAQ,iBAAiB;IAC9D,iFAAiF;IACjF,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,uBAAwB,SAAQ,qBAAqB;IACpE,0EAA0E;IAC1E,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,MAAM,WAAW,qBAAsB,SAAQ,qBAAqB;IAClE,wEAAwE;IACxE,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB;AAED,MAAM,WAAW,sBAAuB,SAAQ,qBAAqB;IACnE,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAED,MAAM,MAAM,UAAU,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AACzC,MAAM,MAAM,QAAQ,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AA0EzC,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiBhB,CAAC;AAEH,QAAA,MAAM,UAAU;;;;;;;;;;;;;;;;;;iBAMd,CAAC;AAwBH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AACvD,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AA4HnD,wBAAgB,gBAAgB,CAC9B,OAAO,GAAE,uBAA4B,GACpC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAEnC;AAED,wBAAgB,cAAc,CAC5B,OAAO,GAAE,qBAA0B,GAClC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAE/B;AAED,wBAAgB,eAAe,CAC7B,OAAO,GAAE,sBAA2B,GACnC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAEjC;AAED,oEAAoE;AACpE,wBAAgB,aAAa,CAC3B,OAAO,GAAE,qBAA0B,GAClC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAE7B;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IAC1C,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IACpC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IACvC,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;CAClC;AAED,MAAM,MAAM,kBAAkB,GAAG,MAAM,iBAAiB,CAAC;AAEzD,MAAM,WAAW,sBAAsB,CACrC,IAAI,SAAS,kBAAkB,GAAG,kBAAkB,CACpD,SAAQ,qBAAqB;IAC7B,kEAAkE;IAClE,IAAI,CAAC,EAAE,SAAS,IAAI,EAAE,CAAC;IACvB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAED,wBAAgB,eAAe,CAC7B,IAAI,SAAS,kBAAkB,GAAG,kBAAkB,EACpD,OAAO,GAAE,sBAAsB,CAAC,IAAI,CAAM,GAAG,IAAI,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAkB3E"}
package/dist/index.js CHANGED
@@ -2,15 +2,85 @@
2
2
  import { Search1API } from "@search1api/client";
3
3
  import { tool } from "ai";
4
4
  import { z } from "zod";
5
- var querySchema = z.object({
6
- query: z.string().trim().min(1).describe("Search keywords or a specific question.")
7
- }).strict();
5
+ var SEARCH_ENGINES = [
6
+ "google",
7
+ "bing",
8
+ "bingcn",
9
+ "duckduckgo",
10
+ "yahoo",
11
+ "yandex",
12
+ "x",
13
+ "reddit",
14
+ "github",
15
+ "youtube",
16
+ "arxiv",
17
+ "wechat",
18
+ "bilibili",
19
+ "imdb",
20
+ "wikipedia",
21
+ "grokipedia"
22
+ ];
23
+ var NEWS_ENGINES = [
24
+ "google",
25
+ "bing",
26
+ "duckduckgo",
27
+ "yahoo",
28
+ "hackernews"
29
+ ];
30
+ function queryFields(kind) {
31
+ const noun = kind === "search" ? "results" : "articles";
32
+ return {
33
+ query: z.string().trim().min(1).describe(`Short, focused ${kind} query`),
34
+ max_results: z.number().int().min(1).max(50).optional().describe(`Maximum number of ${noun} to return`),
35
+ include_sites: z.array(z.string()).optional().describe(
36
+ kind === "search" ? "Domains to include when the user explicitly scopes the search" : "News domains to include"
37
+ ),
38
+ exclude_sites: z.array(z.string()).optional().describe(
39
+ kind === "search" ? "Domains to exclude from the search" : "News domains to exclude"
40
+ ),
41
+ time_range: z.enum(["day", "week", "month", "year"]).optional().describe(
42
+ kind === "search" ? "Optional recency window for time-sensitive searches" : "Optional recency window; use day for breaking news"
43
+ )
44
+ };
45
+ }
46
+ var searchSchema = z.object({
47
+ ...queryFields("search"),
48
+ search_service: z.enum(SEARCH_ENGINES).optional().describe(
49
+ "Search engine to use; choose one only when it matches the user's source intent"
50
+ ),
51
+ page: z.number().int().min(1).max(100).optional().describe(
52
+ "Results page to fetch; only bing, bingcn, baidu, and grokipedia paginate, other engines ignore it"
53
+ )
54
+ });
55
+ var newsSchema = z.object({
56
+ ...queryFields("news"),
57
+ search_service: z.enum(NEWS_ENGINES).optional().describe("News search engine to use")
58
+ });
8
59
  var crawlSchema = z.object({
9
60
  url: z.string().url().refine(
10
61
  (url) => ["http:", "https:"].includes(new URL(url).protocol),
11
62
  "Use an HTTP or HTTPS URL."
12
- ).describe("A public webpage URL, for example a link returned by search.")
13
- }).strict();
63
+ ).describe("Public HTTP or HTTPS URL to retrieve")
64
+ });
65
+ var askSchema = z.object({
66
+ query: z.string().trim().min(1).max(500).describe(
67
+ "Natural-language description of what to find, including any platform or time frame"
68
+ )
69
+ });
70
+ function requestOptions(defaults, input) {
71
+ const fromModel = {
72
+ searchService: input.search_service,
73
+ maxResults: input.max_results,
74
+ includeSites: input.include_sites,
75
+ excludeSites: input.exclude_sites,
76
+ timeRange: input.time_range,
77
+ page: input.page
78
+ };
79
+ const overrides = Object.fromEntries(
80
+ Object.entries(fromModel).filter(([, value]) => value !== void 0)
81
+ );
82
+ return { ...defaults, ...overrides };
83
+ }
14
84
  function clientGetter(options) {
15
85
  let client = options.client;
16
86
  const { client: _client, ...settings } = options;
@@ -27,26 +97,40 @@ function clientGetter(options) {
27
97
  };
28
98
  }
29
99
  function searchTool(getClient, settings = {}) {
30
- const options = { maxResults: 5, crawlResults: 0, ...settings };
100
+ const defaults = {
101
+ maxResults: 10,
102
+ crawlResults: 0,
103
+ ...settings
104
+ };
31
105
  return tool({
32
- description: "Search the public web for current information and sources. Returns titles, links, and snippets. Use crawl to read a result page in full.",
33
- inputSchema: querySchema,
106
+ description: "Search the live public web when the user needs current information, sources, or research. Returns titles, links, and snippets. Use crawl to read a result page in full.",
107
+ inputSchema: searchSchema,
34
108
  execute: async (input, { abortSignal }) => {
35
109
  abortSignal?.throwIfAborted();
36
- const { query } = querySchema.parse(input);
37
- return getClient().search(query, options, { signal: abortSignal });
110
+ const parsed = searchSchema.parse(input);
111
+ return getClient().search(
112
+ parsed.query,
113
+ requestOptions(defaults, parsed),
114
+ { signal: abortSignal }
115
+ );
38
116
  }
39
117
  });
40
118
  }
41
119
  function newsTool(getClient, settings = {}) {
42
- const options = { maxResults: 5, crawlResults: 0, ...settings };
120
+ const defaults = {
121
+ maxResults: 10,
122
+ crawlResults: 0,
123
+ ...settings
124
+ };
43
125
  return tool({
44
- description: "Search news coverage of recent events and announcements. Returns article titles, links, and snippets. Use crawl to read an article in full.",
45
- inputSchema: querySchema,
126
+ description: "Search current news when the user asks about recent events, announcements, or coverage. Returns article titles, links, and snippets. Use crawl to read an article in full.",
127
+ inputSchema: newsSchema,
46
128
  execute: async (input, { abortSignal }) => {
47
129
  abortSignal?.throwIfAborted();
48
- const { query } = querySchema.parse(input);
49
- return getClient().news(query, options, { signal: abortSignal });
130
+ const parsed = newsSchema.parse(input);
131
+ return getClient().news(parsed.query, requestOptions(defaults, parsed), {
132
+ signal: abortSignal
133
+ });
50
134
  }
51
135
  });
52
136
  }
@@ -62,6 +146,17 @@ function crawlTool(getClient, settings = {}) {
62
146
  }
63
147
  });
64
148
  }
149
+ function askTool(getClient) {
150
+ return tool({
151
+ description: "Describe what you need in natural language; Search1API chooses up to five engines and a time window, then returns at most 10 results ranked by relevance, with the engines and window it used. Costs 5 credits per call. Use search instead when you already know the engine and keywords.",
152
+ inputSchema: askSchema,
153
+ execute: async (input, { abortSignal }) => {
154
+ abortSignal?.throwIfAborted();
155
+ const { query } = askSchema.parse(input);
156
+ return getClient().ask(query, { signal: abortSignal });
157
+ }
158
+ });
159
+ }
65
160
  function search1apiSearch(options = {}) {
66
161
  return searchTool(clientGetter(options), options.search);
67
162
  }
@@ -71,14 +166,18 @@ function search1apiNews(options = {}) {
71
166
  function search1apiCrawl(options = {}) {
72
167
  return crawlTool(clientGetter(options), options.crawl);
73
168
  }
169
+ function search1apiAsk(options = {}) {
170
+ return askTool(clientGetter(options));
171
+ }
74
172
  function search1apiTools(options = {}) {
75
173
  const getClient = clientGetter(options);
76
174
  const tools = {
77
175
  search: searchTool(getClient, options.search),
78
176
  news: newsTool(getClient, options.news),
79
- crawl: crawlTool(getClient, options.crawl)
177
+ crawl: crawlTool(getClient, options.crawl),
178
+ ask: askTool(getClient)
80
179
  };
81
- const names = options.only ?? ["search", "news", "crawl"];
180
+ const names = options.only ?? ["search", "news", "crawl", "ask"];
82
181
  const selected = {};
83
182
  for (const name of names) {
84
183
  if (!Object.hasOwn(tools, name)) {
@@ -89,6 +188,7 @@ function search1apiTools(options = {}) {
89
188
  return selected;
90
189
  }
91
190
  export {
191
+ search1apiAsk,
92
192
  search1apiCrawl,
93
193
  search1apiNews,
94
194
  search1apiSearch,
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts"],
4
- "sourcesContent": ["import { Search1API } from '@search1api/client';\nimport type {\n CrawlOptions,\n CrawlResponse,\n NewsOptions,\n NewsResponse,\n Search1APIOptions,\n SearchOptions,\n SearchResponse,\n} from '@search1api/client';\nimport { tool } from 'ai';\nimport type { Tool } from 'ai';\nimport { z } from 'zod';\n\nexport interface Search1APIToolOptions extends Search1APIOptions {\n /** Reuse an existing client. When supplied, other client options are ignored. */\n client?: Search1API;\n}\n\nexport interface Search1APISearchOptions extends Search1APIToolOptions {\n /** Application-owned search settings; the model only supplies the query. */\n search?: SearchOptions;\n}\n\nexport interface Search1APINewsOptions extends Search1APIToolOptions {\n /** Application-owned news settings; the model only supplies the query. */\n news?: NewsOptions;\n}\n\nexport interface Search1APICrawlOptions extends Search1APIToolOptions {\n crawl?: CrawlOptions;\n}\n\nexport type QueryInput = { query: string };\nexport type CrawlInput = { url: string };\n\nconst querySchema = z\n .object({\n query: z\n .string()\n .trim()\n .min(1)\n .describe('Search keywords or a specific question.'),\n })\n .strict();\n\nconst crawlSchema = z\n .object({\n url: z\n .string()\n .url()\n .refine(\n (url) => ['http:', 'https:'].includes(new URL(url).protocol),\n 'Use an HTTP or HTTPS URL.'\n )\n .describe('A public webpage URL, for example a link returned by search.'),\n })\n .strict();\n\ntype ClientGetter = () => Search1API;\n\nfunction clientGetter(options: Search1APIToolOptions): ClientGetter {\n let client = options.client;\n const { client: _client, ...settings } = options;\n return () => {\n if (!client) {\n const processLike = globalThis as typeof globalThis & {\n process?: { env?: Record<string, string | undefined> };\n };\n const env = processLike.process?.env;\n client = new Search1API({\n ...settings,\n apiKey:\n settings.apiKey || env?.SEARCH1API_API_KEY || env?.SEARCH1API_KEY,\n });\n }\n return client;\n };\n}\n\nfunction searchTool(\n getClient: ClientGetter,\n settings: SearchOptions = {}\n): Tool<QueryInput, SearchResponse> {\n const options = { maxResults: 5, crawlResults: 0, ...settings };\n return tool({\n description:\n 'Search the public web for current information and sources. Returns titles, links, and snippets. Use crawl to read a result page in full.',\n inputSchema: querySchema,\n execute: async (input, { abortSignal }) => {\n abortSignal?.throwIfAborted();\n const { query } = querySchema.parse(input);\n return getClient().search(query, options, { signal: abortSignal });\n },\n });\n}\n\nfunction newsTool(\n getClient: ClientGetter,\n settings: NewsOptions = {}\n): Tool<QueryInput, NewsResponse> {\n const options = { maxResults: 5, crawlResults: 0, ...settings };\n return tool({\n description:\n 'Search news coverage of recent events and announcements. Returns article titles, links, and snippets. Use crawl to read an article in full.',\n inputSchema: querySchema,\n execute: async (input, { abortSignal }) => {\n abortSignal?.throwIfAborted();\n const { query } = querySchema.parse(input);\n return getClient().news(query, options, { signal: abortSignal });\n },\n });\n}\n\nfunction crawlTool(\n getClient: ClientGetter,\n settings: CrawlOptions = {}\n): Tool<CrawlInput, CrawlResponse> {\n const options = { ...settings };\n return tool({\n description:\n 'Read one public webpage and return its title, source URL, and readable content. Use a URL supplied by the user or returned by search or news.',\n inputSchema: crawlSchema,\n execute: async (input, { abortSignal }) => {\n abortSignal?.throwIfAborted();\n const { url } = crawlSchema.parse(input);\n return getClient().crawl(url, options, { signal: abortSignal });\n },\n });\n}\n\nexport function search1apiSearch(\n options: Search1APISearchOptions = {}\n): Tool<QueryInput, SearchResponse> {\n return searchTool(clientGetter(options), options.search);\n}\n\nexport function search1apiNews(\n options: Search1APINewsOptions = {}\n): Tool<QueryInput, NewsResponse> {\n return newsTool(clientGetter(options), options.news);\n}\n\nexport function search1apiCrawl(\n options: Search1APICrawlOptions = {}\n): Tool<CrawlInput, CrawlResponse> {\n return crawlTool(clientGetter(options), options.crawl);\n}\n\nexport interface Search1APIToolSet {\n search: Tool<QueryInput, SearchResponse>;\n news: Tool<QueryInput, NewsResponse>;\n crawl: Tool<CrawlInput, CrawlResponse>;\n}\n\nexport type Search1APIToolName = keyof Search1APIToolSet;\n\nexport interface Search1APIToolsOptions<\n Name extends Search1APIToolName = Search1APIToolName,\n> extends Search1APIToolOptions {\n /** Include only these tools. By default all three are included. */\n only?: readonly Name[];\n search?: SearchOptions;\n news?: NewsOptions;\n crawl?: CrawlOptions;\n}\n\nexport function search1apiTools<\n Name extends Search1APIToolName = Search1APIToolName,\n>(options: Search1APIToolsOptions<Name> = {}): Pick<Search1APIToolSet, Name> {\n const getClient = clientGetter(options);\n const tools: Search1APIToolSet = {\n search: searchTool(getClient, options.search),\n news: newsTool(getClient, options.news),\n crawl: crawlTool(getClient, options.crawl),\n };\n const names = options.only ?? (['search', 'news', 'crawl'] as const);\n const selected = {} as Pick<Search1APIToolSet, Name>;\n for (const name of names) {\n if (!Object.hasOwn(tools, name)) {\n throw new Error(`Unknown Search1API tool: ${name}`);\n }\n Object.assign(selected, { [name]: tools[name] });\n }\n return selected;\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Search1API } from '@search1api/client';\nimport type {\n AskResponse,\n CrawlOptions,\n CrawlResponse,\n NewsOptions,\n NewsResponse,\n Search1APIOptions,\n SearchOptions,\n SearchResponse,\n} from '@search1api/client';\nimport { tool } from 'ai';\nimport type { Tool } from 'ai';\nimport { z } from 'zod';\n\nexport interface Search1APIToolOptions extends Search1APIOptions {\n /** Reuse an existing client. When supplied, other client options are ignored. */\n client?: Search1API;\n}\n\nexport interface Search1APISearchOptions extends Search1APIToolOptions {\n /** Default search settings; values the model supplies take precedence. */\n search?: SearchOptions;\n}\n\nexport interface Search1APINewsOptions extends Search1APIToolOptions {\n /** Default news settings; values the model supplies take precedence. */\n news?: NewsOptions;\n}\n\nexport interface Search1APICrawlOptions extends Search1APIToolOptions {\n crawl?: CrawlOptions;\n}\n\nexport type CrawlInput = { url: string };\nexport type AskInput = { query: string };\n\n// Model-facing parameters mirror the Search1API MCP server's tool schemas,\n// except result crawling, which only application settings can enable.\nconst SEARCH_ENGINES = [\n 'google',\n 'bing',\n 'bingcn',\n 'duckduckgo',\n 'yahoo',\n 'yandex',\n 'x',\n 'reddit',\n 'github',\n 'youtube',\n 'arxiv',\n 'wechat',\n 'bilibili',\n 'imdb',\n 'wikipedia',\n 'grokipedia',\n] as const;\nconst NEWS_ENGINES = [\n 'google',\n 'bing',\n 'duckduckgo',\n 'yahoo',\n 'hackernews',\n] as const;\n\nfunction queryFields(kind: 'search' | 'news') {\n const noun = kind === 'search' ? 'results' : 'articles';\n return {\n query: z\n .string()\n .trim()\n .min(1)\n .describe(`Short, focused ${kind} query`),\n max_results: z\n .number()\n .int()\n .min(1)\n .max(50)\n .optional()\n .describe(`Maximum number of ${noun} to return`),\n include_sites: z\n .array(z.string())\n .optional()\n .describe(\n kind === 'search'\n ? 'Domains to include when the user explicitly scopes the search'\n : 'News domains to include'\n ),\n exclude_sites: z\n .array(z.string())\n .optional()\n .describe(\n kind === 'search'\n ? 'Domains to exclude from the search'\n : 'News domains to exclude'\n ),\n time_range: z\n .enum(['day', 'week', 'month', 'year'])\n .optional()\n .describe(\n kind === 'search'\n ? 'Optional recency window for time-sensitive searches'\n : 'Optional recency window; use day for breaking news'\n ),\n };\n}\n\n// Unknown keys are stripped rather than rejected so a stray argument does not\n// cost the agent a retry step.\nconst searchSchema = z.object({\n ...queryFields('search'),\n search_service: z\n .enum(SEARCH_ENGINES)\n .optional()\n .describe(\n \"Search engine to use; choose one only when it matches the user's source intent\"\n ),\n page: z\n .number()\n .int()\n .min(1)\n .max(100)\n .optional()\n .describe(\n 'Results page to fetch; only bing, bingcn, baidu, and grokipedia paginate, other engines ignore it'\n ),\n});\n\nconst newsSchema = z.object({\n ...queryFields('news'),\n search_service: z\n .enum(NEWS_ENGINES)\n .optional()\n .describe('News search engine to use'),\n});\n\nconst crawlSchema = z.object({\n url: z\n .string()\n .url()\n .refine(\n (url) => ['http:', 'https:'].includes(new URL(url).protocol),\n 'Use an HTTP or HTTPS URL.'\n )\n .describe('Public HTTP or HTTPS URL to retrieve'),\n});\n\nconst askSchema = z.object({\n query: z\n .string()\n .trim()\n .min(1)\n .max(500)\n .describe(\n 'Natural-language description of what to find, including any platform or time frame'\n ),\n});\n\nexport type SearchInput = z.input<typeof searchSchema>;\nexport type NewsInput = z.input<typeof newsSchema>;\n\ntype ModelQueryInput =\n | z.output<typeof searchSchema>\n | (z.output<typeof newsSchema> & { page?: undefined });\n\n// Merge model-supplied values over application defaults, dropping omitted keys.\nfunction requestOptions<Options extends SearchOptions | NewsOptions>(\n defaults: Options,\n input: ModelQueryInput\n): Options {\n const fromModel = {\n searchService: input.search_service,\n maxResults: input.max_results,\n includeSites: input.include_sites,\n excludeSites: input.exclude_sites,\n timeRange: input.time_range,\n page: input.page,\n };\n const overrides = Object.fromEntries(\n Object.entries(fromModel).filter(([, value]) => value !== undefined)\n );\n return { ...defaults, ...overrides } as Options;\n}\n\ntype ClientGetter = () => Search1API;\n\nfunction clientGetter(options: Search1APIToolOptions): ClientGetter {\n let client = options.client;\n const { client: _client, ...settings } = options;\n return () => {\n if (!client) {\n const processLike = globalThis as typeof globalThis & {\n process?: { env?: Record<string, string | undefined> };\n };\n const env = processLike.process?.env;\n client = new Search1API({\n ...settings,\n apiKey:\n settings.apiKey || env?.SEARCH1API_API_KEY || env?.SEARCH1API_KEY,\n });\n }\n return client;\n };\n}\n\nfunction searchTool(\n getClient: ClientGetter,\n settings: SearchOptions = {}\n): Tool<SearchInput, SearchResponse> {\n const defaults: SearchOptions = {\n maxResults: 10,\n crawlResults: 0,\n ...settings,\n };\n return tool({\n description:\n 'Search the live public web when the user needs current information, sources, or research. Returns titles, links, and snippets. Use crawl to read a result page in full.',\n inputSchema: searchSchema,\n execute: async (input, { abortSignal }) => {\n abortSignal?.throwIfAborted();\n const parsed = searchSchema.parse(input);\n return getClient().search(\n parsed.query,\n requestOptions(defaults, parsed),\n { signal: abortSignal }\n );\n },\n });\n}\n\nfunction newsTool(\n getClient: ClientGetter,\n settings: NewsOptions = {}\n): Tool<NewsInput, NewsResponse> {\n const defaults: NewsOptions = {\n maxResults: 10,\n crawlResults: 0,\n ...settings,\n };\n return tool({\n description:\n 'Search current news when the user asks about recent events, announcements, or coverage. Returns article titles, links, and snippets. Use crawl to read an article in full.',\n inputSchema: newsSchema,\n execute: async (input, { abortSignal }) => {\n abortSignal?.throwIfAborted();\n const parsed = newsSchema.parse(input);\n return getClient().news(parsed.query, requestOptions(defaults, parsed), {\n signal: abortSignal,\n });\n },\n });\n}\n\nfunction crawlTool(\n getClient: ClientGetter,\n settings: CrawlOptions = {}\n): Tool<CrawlInput, CrawlResponse> {\n const options = { ...settings };\n return tool({\n description:\n 'Read one public webpage and return its title, source URL, and readable content. Use a URL supplied by the user or returned by search or news.',\n inputSchema: crawlSchema,\n execute: async (input, { abortSignal }) => {\n abortSignal?.throwIfAborted();\n const { url } = crawlSchema.parse(input);\n return getClient().crawl(url, options, { signal: abortSignal });\n },\n });\n}\n\nfunction askTool(getClient: ClientGetter): Tool<AskInput, AskResponse> {\n return tool({\n description:\n 'Describe what you need in natural language; Search1API chooses up to five engines and a time window, then returns at most 10 results ranked by relevance, with the engines and window it used. Costs 5 credits per call. Use search instead when you already know the engine and keywords.',\n inputSchema: askSchema,\n execute: async (input, { abortSignal }) => {\n abortSignal?.throwIfAborted();\n const { query } = askSchema.parse(input);\n return getClient().ask(query, { signal: abortSignal });\n },\n });\n}\n\nexport function search1apiSearch(\n options: Search1APISearchOptions = {}\n): Tool<SearchInput, SearchResponse> {\n return searchTool(clientGetter(options), options.search);\n}\n\nexport function search1apiNews(\n options: Search1APINewsOptions = {}\n): Tool<NewsInput, NewsResponse> {\n return newsTool(clientGetter(options), options.news);\n}\n\nexport function search1apiCrawl(\n options: Search1APICrawlOptions = {}\n): Tool<CrawlInput, CrawlResponse> {\n return crawlTool(clientGetter(options), options.crawl);\n}\n\n/** Agentic search through `POST /ask`. Costs 5 credits per call. */\nexport function search1apiAsk(\n options: Search1APIToolOptions = {}\n): Tool<AskInput, AskResponse> {\n return askTool(clientGetter(options));\n}\n\nexport interface Search1APIToolSet {\n search: Tool<SearchInput, SearchResponse>;\n news: Tool<NewsInput, NewsResponse>;\n crawl: Tool<CrawlInput, CrawlResponse>;\n ask: Tool<AskInput, AskResponse>;\n}\n\nexport type Search1APIToolName = keyof Search1APIToolSet;\n\nexport interface Search1APIToolsOptions<\n Name extends Search1APIToolName = Search1APIToolName,\n> extends Search1APIToolOptions {\n /** Include only these tools. By default all four are included. */\n only?: readonly Name[];\n search?: SearchOptions;\n news?: NewsOptions;\n crawl?: CrawlOptions;\n}\n\nexport function search1apiTools<\n Name extends Search1APIToolName = Search1APIToolName,\n>(options: Search1APIToolsOptions<Name> = {}): Pick<Search1APIToolSet, Name> {\n const getClient = clientGetter(options);\n const tools: Search1APIToolSet = {\n search: searchTool(getClient, options.search),\n news: newsTool(getClient, options.news),\n crawl: crawlTool(getClient, options.crawl),\n ask: askTool(getClient),\n };\n const names =\n options.only ?? (['search', 'news', 'crawl', 'ask'] as const);\n const selected = {} as Pick<Search1APIToolSet, Name>;\n for (const name of names) {\n if (!Object.hasOwn(tools, name)) {\n throw new Error(`Unknown Search1API tool: ${name}`);\n }\n Object.assign(selected, { [name]: tools[name] });\n }\n return selected;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@search1api/ai-sdk",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Official Search1API web search, news, and page reading tools for the Vercel AI SDK.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -53,7 +53,7 @@
53
53
  "prepack": "npm run build"
54
54
  },
55
55
  "dependencies": {
56
- "@search1api/client": "^0.2.1"
56
+ "@search1api/client": "^0.3.0"
57
57
  },
58
58
  "peerDependencies": {
59
59
  "ai": "^5.0.0 || ^6.0.0 || ^7.0.0",