@search1api/ai-sdk 0.1.1 → 0.1.2
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 +16 -7
- package/dist/index.cjs +87 -15
- package/dist/index.cjs.map +2 -2
- package/dist/index.d.ts +54 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +87 -15
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -36,19 +36,28 @@ The tool set has three entries:
|
|
|
36
36
|
|
|
37
37
|
| Tool | Model input | API | Output |
|
|
38
38
|
| --- | --- | --- | --- |
|
|
39
|
-
| `search` | `{ query }` | `/search` | Typed results with titles, links, and snippets |
|
|
40
|
-
| `news` |
|
|
39
|
+
| `search` | `{ query, search_service?, max_results?, include_sites?, exclude_sites?, time_range? }` | `/search` | Typed results with titles, links, and snippets |
|
|
40
|
+
| `news` | Same fields as `search`, with news engines | `/news` | Typed news results and source links |
|
|
41
41
|
| `crawl` | `{ url }` | `/crawl` | A page's title, URL, and readable content |
|
|
42
42
|
|
|
43
|
+
The model-facing parameters match the
|
|
44
|
+
[Search1API MCP server](https://s1.dev/docs/integrations/mcp). The model can
|
|
45
|
+
pick an engine (`google`, `bing`, `duckduckgo`, `yahoo`, `x`, `reddit`, `github`,
|
|
46
|
+
`youtube`, `arxiv`, `wechat`, `bilibili`, `imdb`, `wikipedia`; news supports
|
|
47
|
+
`google`, `bing`, `duckduckgo`, `yahoo`, and `hackernews`), return 1–50 results,
|
|
48
|
+
scope or exclude domains, and limit results to the past day, month, or year.
|
|
49
|
+
Result page crawling is not exposed to the model. Unknown arguments are ignored
|
|
50
|
+
rather than failing the call.
|
|
51
|
+
|
|
43
52
|
Outputs preserve the API response, including optional publication dates,
|
|
44
53
|
metadata, and content. Empty results remain empty. Ask the model to cite the
|
|
45
54
|
returned links; these tools do not add AI SDK source events automatically.
|
|
46
55
|
|
|
47
56
|
## Configure one tool
|
|
48
57
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
58
|
+
Settings passed in code are defaults. When the model supplies the same
|
|
59
|
+
parameter, the model's value is used for that call; anything it omits falls
|
|
60
|
+
back to your settings.
|
|
52
61
|
|
|
53
62
|
```ts
|
|
54
63
|
import { search1apiSearch, search1apiCrawl } from '@search1api/ai-sdk';
|
|
@@ -72,8 +81,8 @@ const tools = search1apiTools({
|
|
|
72
81
|
});
|
|
73
82
|
```
|
|
74
83
|
|
|
75
|
-
Search and news default to
|
|
76
|
-
`search.crawlResults` or `news.crawlResults`
|
|
84
|
+
Search and news default to ten results with `crawlResults: 0`. Set
|
|
85
|
+
`search.crawlResults` or `news.crawlResults` in code when you want result page
|
|
77
86
|
content included. Each successful page retrieval incurs a separate crawl charge;
|
|
78
87
|
see [pricing](https://s1.dev/pricing).
|
|
79
88
|
|
package/dist/index.cjs
CHANGED
|
@@ -29,15 +29,73 @@ module.exports = __toCommonJS(index_exports);
|
|
|
29
29
|
var import_client = require("@search1api/client");
|
|
30
30
|
var import_ai = require("ai");
|
|
31
31
|
var import_zod = require("zod");
|
|
32
|
-
var
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
var SEARCH_ENGINES = [
|
|
33
|
+
"google",
|
|
34
|
+
"bing",
|
|
35
|
+
"duckduckgo",
|
|
36
|
+
"yahoo",
|
|
37
|
+
"x",
|
|
38
|
+
"reddit",
|
|
39
|
+
"github",
|
|
40
|
+
"youtube",
|
|
41
|
+
"arxiv",
|
|
42
|
+
"wechat",
|
|
43
|
+
"bilibili",
|
|
44
|
+
"imdb",
|
|
45
|
+
"wikipedia"
|
|
46
|
+
];
|
|
47
|
+
var NEWS_ENGINES = [
|
|
48
|
+
"google",
|
|
49
|
+
"bing",
|
|
50
|
+
"duckduckgo",
|
|
51
|
+
"yahoo",
|
|
52
|
+
"hackernews"
|
|
53
|
+
];
|
|
54
|
+
function queryFields(kind) {
|
|
55
|
+
const noun = kind === "search" ? "results" : "articles";
|
|
56
|
+
return {
|
|
57
|
+
query: import_zod.z.string().trim().min(1).describe(`Short, focused ${kind} query`),
|
|
58
|
+
max_results: import_zod.z.number().int().min(1).max(50).optional().describe(`Maximum number of ${noun} to return`),
|
|
59
|
+
include_sites: import_zod.z.array(import_zod.z.string()).optional().describe(
|
|
60
|
+
kind === "search" ? "Domains to include when the user explicitly scopes the search" : "News domains to include"
|
|
61
|
+
),
|
|
62
|
+
exclude_sites: import_zod.z.array(import_zod.z.string()).optional().describe(
|
|
63
|
+
kind === "search" ? "Domains to exclude from the search" : "News domains to exclude"
|
|
64
|
+
),
|
|
65
|
+
time_range: import_zod.z.enum(["day", "month", "year"]).optional().describe(
|
|
66
|
+
kind === "search" ? "Optional recency window for time-sensitive searches" : "Optional recency window; use day for breaking news"
|
|
67
|
+
)
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
var searchSchema = import_zod.z.object({
|
|
71
|
+
...queryFields("search"),
|
|
72
|
+
search_service: import_zod.z.enum(SEARCH_ENGINES).optional().describe(
|
|
73
|
+
"Search engine to use; choose one only when it matches the user's source intent"
|
|
74
|
+
)
|
|
75
|
+
});
|
|
76
|
+
var newsSchema = import_zod.z.object({
|
|
77
|
+
...queryFields("news"),
|
|
78
|
+
search_service: import_zod.z.enum(NEWS_ENGINES).optional().describe("News search engine to use")
|
|
79
|
+
});
|
|
35
80
|
var crawlSchema = import_zod.z.object({
|
|
36
81
|
url: import_zod.z.string().url().refine(
|
|
37
82
|
(url) => ["http:", "https:"].includes(new URL(url).protocol),
|
|
38
83
|
"Use an HTTP or HTTPS URL."
|
|
39
|
-
).describe("
|
|
40
|
-
})
|
|
84
|
+
).describe("Public HTTP or HTTPS URL to retrieve")
|
|
85
|
+
});
|
|
86
|
+
function requestOptions(defaults, input) {
|
|
87
|
+
const fromModel = {
|
|
88
|
+
searchService: input.search_service,
|
|
89
|
+
maxResults: input.max_results,
|
|
90
|
+
includeSites: input.include_sites,
|
|
91
|
+
excludeSites: input.exclude_sites,
|
|
92
|
+
timeRange: input.time_range
|
|
93
|
+
};
|
|
94
|
+
const overrides = Object.fromEntries(
|
|
95
|
+
Object.entries(fromModel).filter(([, value]) => value !== void 0)
|
|
96
|
+
);
|
|
97
|
+
return { ...defaults, ...overrides };
|
|
98
|
+
}
|
|
41
99
|
function clientGetter(options) {
|
|
42
100
|
let client = options.client;
|
|
43
101
|
const { client: _client, ...settings } = options;
|
|
@@ -54,26 +112,40 @@ function clientGetter(options) {
|
|
|
54
112
|
};
|
|
55
113
|
}
|
|
56
114
|
function searchTool(getClient, settings = {}) {
|
|
57
|
-
const
|
|
115
|
+
const defaults = {
|
|
116
|
+
maxResults: 10,
|
|
117
|
+
crawlResults: 0,
|
|
118
|
+
...settings
|
|
119
|
+
};
|
|
58
120
|
return (0, import_ai.tool)({
|
|
59
|
-
description: "Search the public web
|
|
60
|
-
inputSchema:
|
|
121
|
+
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.",
|
|
122
|
+
inputSchema: searchSchema,
|
|
61
123
|
execute: async (input, { abortSignal }) => {
|
|
62
124
|
abortSignal?.throwIfAborted();
|
|
63
|
-
const
|
|
64
|
-
return getClient().search(
|
|
125
|
+
const parsed = searchSchema.parse(input);
|
|
126
|
+
return getClient().search(
|
|
127
|
+
parsed.query,
|
|
128
|
+
requestOptions(defaults, parsed),
|
|
129
|
+
{ signal: abortSignal }
|
|
130
|
+
);
|
|
65
131
|
}
|
|
66
132
|
});
|
|
67
133
|
}
|
|
68
134
|
function newsTool(getClient, settings = {}) {
|
|
69
|
-
const
|
|
135
|
+
const defaults = {
|
|
136
|
+
maxResults: 10,
|
|
137
|
+
crawlResults: 0,
|
|
138
|
+
...settings
|
|
139
|
+
};
|
|
70
140
|
return (0, import_ai.tool)({
|
|
71
|
-
description: "Search news
|
|
72
|
-
inputSchema:
|
|
141
|
+
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.",
|
|
142
|
+
inputSchema: newsSchema,
|
|
73
143
|
execute: async (input, { abortSignal }) => {
|
|
74
144
|
abortSignal?.throwIfAborted();
|
|
75
|
-
const
|
|
76
|
-
return getClient().news(query,
|
|
145
|
+
const parsed = newsSchema.parse(input);
|
|
146
|
+
return getClient().news(parsed.query, requestOptions(defaults, parsed), {
|
|
147
|
+
signal: abortSignal
|
|
148
|
+
});
|
|
77
149
|
}
|
|
78
150
|
});
|
|
79
151
|
}
|
package/dist/index.cjs.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 /**
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA2B;AAU3B,gBAAqB;AAErB,iBAAkB;
|
|
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 /** 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 };\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 'duckduckgo',\n 'yahoo',\n 'x',\n 'reddit',\n 'github',\n 'youtube',\n 'arxiv',\n 'wechat',\n 'bilibili',\n 'imdb',\n 'wikipedia',\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', '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});\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\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>;\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 };\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\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\nexport interface Search1APIToolSet {\n search: Tool<SearchInput, SearchResponse>;\n news: Tool<NewsInput, 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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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,33 +1,77 @@
|
|
|
1
1
|
import { Search1API } from '@search1api/client';
|
|
2
2
|
import type { 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
|
-
/**
|
|
10
|
+
/** Default search settings; values the model supplies take precedence. */
|
|
10
11
|
search?: SearchOptions;
|
|
11
12
|
}
|
|
12
13
|
export interface Search1APINewsOptions extends Search1APIToolOptions {
|
|
13
|
-
/**
|
|
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
|
-
|
|
26
|
-
|
|
23
|
+
declare const searchSchema: z.ZodObject<{
|
|
24
|
+
search_service: z.ZodOptional<z.ZodEnum<{
|
|
25
|
+
google: "google";
|
|
26
|
+
bing: "bing";
|
|
27
|
+
duckduckgo: "duckduckgo";
|
|
28
|
+
yahoo: "yahoo";
|
|
29
|
+
x: "x";
|
|
30
|
+
reddit: "reddit";
|
|
31
|
+
github: "github";
|
|
32
|
+
youtube: "youtube";
|
|
33
|
+
arxiv: "arxiv";
|
|
34
|
+
wechat: "wechat";
|
|
35
|
+
bilibili: "bilibili";
|
|
36
|
+
imdb: "imdb";
|
|
37
|
+
wikipedia: "wikipedia";
|
|
38
|
+
}>>;
|
|
39
|
+
query: z.ZodString;
|
|
40
|
+
max_results: z.ZodOptional<z.ZodNumber>;
|
|
41
|
+
include_sites: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
42
|
+
exclude_sites: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
43
|
+
time_range: z.ZodOptional<z.ZodEnum<{
|
|
44
|
+
day: "day";
|
|
45
|
+
month: "month";
|
|
46
|
+
year: "year";
|
|
47
|
+
}>>;
|
|
48
|
+
}, z.core.$strip>;
|
|
49
|
+
declare const newsSchema: z.ZodObject<{
|
|
50
|
+
search_service: z.ZodOptional<z.ZodEnum<{
|
|
51
|
+
google: "google";
|
|
52
|
+
bing: "bing";
|
|
53
|
+
duckduckgo: "duckduckgo";
|
|
54
|
+
yahoo: "yahoo";
|
|
55
|
+
hackernews: "hackernews";
|
|
56
|
+
}>>;
|
|
57
|
+
query: z.ZodString;
|
|
58
|
+
max_results: z.ZodOptional<z.ZodNumber>;
|
|
59
|
+
include_sites: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
60
|
+
exclude_sites: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
61
|
+
time_range: z.ZodOptional<z.ZodEnum<{
|
|
62
|
+
day: "day";
|
|
63
|
+
month: "month";
|
|
64
|
+
year: "year";
|
|
65
|
+
}>>;
|
|
66
|
+
}, z.core.$strip>;
|
|
67
|
+
export type SearchInput = z.input<typeof searchSchema>;
|
|
68
|
+
export type NewsInput = z.input<typeof newsSchema>;
|
|
69
|
+
export declare function search1apiSearch(options?: Search1APISearchOptions): Tool<SearchInput, SearchResponse>;
|
|
70
|
+
export declare function search1apiNews(options?: Search1APINewsOptions): Tool<NewsInput, NewsResponse>;
|
|
27
71
|
export declare function search1apiCrawl(options?: Search1APICrawlOptions): Tool<CrawlInput, CrawlResponse>;
|
|
28
72
|
export interface Search1APIToolSet {
|
|
29
|
-
search: Tool<
|
|
30
|
-
news: Tool<
|
|
73
|
+
search: Tool<SearchInput, SearchResponse>;
|
|
74
|
+
news: Tool<NewsInput, NewsResponse>;
|
|
31
75
|
crawl: Tool<CrawlInput, CrawlResponse>;
|
|
32
76
|
}
|
|
33
77
|
export type Search1APIToolName = keyof Search1APIToolSet;
|
|
@@ -39,4 +83,5 @@ export interface Search1APIToolsOptions<Name extends Search1APIToolName = Search
|
|
|
39
83
|
crawl?: CrawlOptions;
|
|
40
84
|
}
|
|
41
85
|
export declare function search1apiTools<Name extends Search1APIToolName = Search1APIToolName>(options?: Search1APIToolsOptions<Name>): Pick<Search1APIToolSet, Name>;
|
|
86
|
+
export {};
|
|
42
87
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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;
|
|
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;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;AAuEzC,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;iBAQhB,CAAC;AAEH,QAAA,MAAM,UAAU;;;;;;;;;;;;;;;;;iBAMd,CAAC;AAaH,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;AA8GnD,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,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;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"}
|
package/dist/index.js
CHANGED
|
@@ -2,15 +2,73 @@
|
|
|
2
2
|
import { Search1API } from "@search1api/client";
|
|
3
3
|
import { tool } from "ai";
|
|
4
4
|
import { z } from "zod";
|
|
5
|
-
var
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
var SEARCH_ENGINES = [
|
|
6
|
+
"google",
|
|
7
|
+
"bing",
|
|
8
|
+
"duckduckgo",
|
|
9
|
+
"yahoo",
|
|
10
|
+
"x",
|
|
11
|
+
"reddit",
|
|
12
|
+
"github",
|
|
13
|
+
"youtube",
|
|
14
|
+
"arxiv",
|
|
15
|
+
"wechat",
|
|
16
|
+
"bilibili",
|
|
17
|
+
"imdb",
|
|
18
|
+
"wikipedia"
|
|
19
|
+
];
|
|
20
|
+
var NEWS_ENGINES = [
|
|
21
|
+
"google",
|
|
22
|
+
"bing",
|
|
23
|
+
"duckduckgo",
|
|
24
|
+
"yahoo",
|
|
25
|
+
"hackernews"
|
|
26
|
+
];
|
|
27
|
+
function queryFields(kind) {
|
|
28
|
+
const noun = kind === "search" ? "results" : "articles";
|
|
29
|
+
return {
|
|
30
|
+
query: z.string().trim().min(1).describe(`Short, focused ${kind} query`),
|
|
31
|
+
max_results: z.number().int().min(1).max(50).optional().describe(`Maximum number of ${noun} to return`),
|
|
32
|
+
include_sites: z.array(z.string()).optional().describe(
|
|
33
|
+
kind === "search" ? "Domains to include when the user explicitly scopes the search" : "News domains to include"
|
|
34
|
+
),
|
|
35
|
+
exclude_sites: z.array(z.string()).optional().describe(
|
|
36
|
+
kind === "search" ? "Domains to exclude from the search" : "News domains to exclude"
|
|
37
|
+
),
|
|
38
|
+
time_range: z.enum(["day", "month", "year"]).optional().describe(
|
|
39
|
+
kind === "search" ? "Optional recency window for time-sensitive searches" : "Optional recency window; use day for breaking news"
|
|
40
|
+
)
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
var searchSchema = z.object({
|
|
44
|
+
...queryFields("search"),
|
|
45
|
+
search_service: z.enum(SEARCH_ENGINES).optional().describe(
|
|
46
|
+
"Search engine to use; choose one only when it matches the user's source intent"
|
|
47
|
+
)
|
|
48
|
+
});
|
|
49
|
+
var newsSchema = z.object({
|
|
50
|
+
...queryFields("news"),
|
|
51
|
+
search_service: z.enum(NEWS_ENGINES).optional().describe("News search engine to use")
|
|
52
|
+
});
|
|
8
53
|
var crawlSchema = z.object({
|
|
9
54
|
url: z.string().url().refine(
|
|
10
55
|
(url) => ["http:", "https:"].includes(new URL(url).protocol),
|
|
11
56
|
"Use an HTTP or HTTPS URL."
|
|
12
|
-
).describe("
|
|
13
|
-
})
|
|
57
|
+
).describe("Public HTTP or HTTPS URL to retrieve")
|
|
58
|
+
});
|
|
59
|
+
function requestOptions(defaults, input) {
|
|
60
|
+
const fromModel = {
|
|
61
|
+
searchService: input.search_service,
|
|
62
|
+
maxResults: input.max_results,
|
|
63
|
+
includeSites: input.include_sites,
|
|
64
|
+
excludeSites: input.exclude_sites,
|
|
65
|
+
timeRange: input.time_range
|
|
66
|
+
};
|
|
67
|
+
const overrides = Object.fromEntries(
|
|
68
|
+
Object.entries(fromModel).filter(([, value]) => value !== void 0)
|
|
69
|
+
);
|
|
70
|
+
return { ...defaults, ...overrides };
|
|
71
|
+
}
|
|
14
72
|
function clientGetter(options) {
|
|
15
73
|
let client = options.client;
|
|
16
74
|
const { client: _client, ...settings } = options;
|
|
@@ -27,26 +85,40 @@ function clientGetter(options) {
|
|
|
27
85
|
};
|
|
28
86
|
}
|
|
29
87
|
function searchTool(getClient, settings = {}) {
|
|
30
|
-
const
|
|
88
|
+
const defaults = {
|
|
89
|
+
maxResults: 10,
|
|
90
|
+
crawlResults: 0,
|
|
91
|
+
...settings
|
|
92
|
+
};
|
|
31
93
|
return tool({
|
|
32
|
-
description: "Search the public web
|
|
33
|
-
inputSchema:
|
|
94
|
+
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.",
|
|
95
|
+
inputSchema: searchSchema,
|
|
34
96
|
execute: async (input, { abortSignal }) => {
|
|
35
97
|
abortSignal?.throwIfAborted();
|
|
36
|
-
const
|
|
37
|
-
return getClient().search(
|
|
98
|
+
const parsed = searchSchema.parse(input);
|
|
99
|
+
return getClient().search(
|
|
100
|
+
parsed.query,
|
|
101
|
+
requestOptions(defaults, parsed),
|
|
102
|
+
{ signal: abortSignal }
|
|
103
|
+
);
|
|
38
104
|
}
|
|
39
105
|
});
|
|
40
106
|
}
|
|
41
107
|
function newsTool(getClient, settings = {}) {
|
|
42
|
-
const
|
|
108
|
+
const defaults = {
|
|
109
|
+
maxResults: 10,
|
|
110
|
+
crawlResults: 0,
|
|
111
|
+
...settings
|
|
112
|
+
};
|
|
43
113
|
return tool({
|
|
44
|
-
description: "Search news
|
|
45
|
-
inputSchema:
|
|
114
|
+
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.",
|
|
115
|
+
inputSchema: newsSchema,
|
|
46
116
|
execute: async (input, { abortSignal }) => {
|
|
47
117
|
abortSignal?.throwIfAborted();
|
|
48
|
-
const
|
|
49
|
-
return getClient().news(query,
|
|
118
|
+
const parsed = newsSchema.parse(input);
|
|
119
|
+
return getClient().news(parsed.query, requestOptions(defaults, parsed), {
|
|
120
|
+
signal: abortSignal
|
|
121
|
+
});
|
|
50
122
|
}
|
|
51
123
|
});
|
|
52
124
|
}
|
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 /**
|
|
5
|
-
"mappings": ";AAAA,SAAS,kBAAkB;AAU3B,SAAS,YAAY;AAErB,SAAS,SAAS;
|
|
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 /** 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 };\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 'duckduckgo',\n 'yahoo',\n 'x',\n 'reddit',\n 'github',\n 'youtube',\n 'arxiv',\n 'wechat',\n 'bilibili',\n 'imdb',\n 'wikipedia',\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', '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});\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\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>;\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 };\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\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\nexport interface Search1APIToolSet {\n search: Tool<SearchInput, SearchResponse>;\n news: Tool<NewsInput, 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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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|