@polpo-ai/tools 0.6.32 → 0.7.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/dist/__tests__/email-tools.test.d.ts +2 -0
- package/dist/__tests__/email-tools.test.d.ts.map +1 -0
- package/dist/__tests__/email-tools.test.js +705 -0
- package/dist/__tests__/email-tools.test.js.map +1 -0
- package/dist/__tests__/extended-tools.test.d.ts +2 -0
- package/dist/__tests__/extended-tools.test.d.ts.map +1 -0
- package/dist/__tests__/extended-tools.test.js +743 -0
- package/dist/__tests__/extended-tools.test.js.map +1 -0
- package/dist/__tests__/external-api-tools.test.d.ts +2 -0
- package/dist/__tests__/external-api-tools.test.d.ts.map +1 -0
- package/dist/__tests__/external-api-tools.test.js +1731 -0
- package/dist/__tests__/external-api-tools.test.js.map +1 -0
- package/dist/__tests__/memory-tools.test.d.ts +2 -0
- package/dist/__tests__/memory-tools.test.d.ts.map +1 -0
- package/dist/__tests__/memory-tools.test.js +0 -0
- package/dist/__tests__/memory-tools.test.js.map +1 -0
- package/dist/audio-tools.d.ts +25 -27
- package/dist/audio-tools.d.ts.map +1 -1
- package/dist/audio-tools.js +156 -438
- package/dist/audio-tools.js.map +1 -1
- package/dist/browser-tools.d.ts.map +1 -1
- package/dist/browser-tools.js +5 -1
- package/dist/browser-tools.js.map +1 -1
- package/dist/email-tools.d.ts.map +1 -1
- package/dist/email-tools.js +11 -3
- package/dist/email-tools.js.map +1 -1
- package/dist/image-tools.d.ts +27 -25
- package/dist/image-tools.d.ts.map +1 -1
- package/dist/image-tools.js +151 -332
- package/dist/image-tools.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/lib/edge-speech-model.d.ts +61 -0
- package/dist/lib/edge-speech-model.d.ts.map +1 -0
- package/dist/lib/edge-speech-model.js +144 -0
- package/dist/lib/edge-speech-model.js.map +1 -0
- package/dist/lib/exa-search-provider.d.ts +27 -0
- package/dist/lib/exa-search-provider.d.ts.map +1 -0
- package/dist/lib/exa-search-provider.js +109 -0
- package/dist/lib/exa-search-provider.js.map +1 -0
- package/dist/lib/provider-resolver.d.ts +54 -0
- package/dist/lib/provider-resolver.d.ts.map +1 -0
- package/dist/lib/provider-resolver.js +115 -0
- package/dist/lib/provider-resolver.js.map +1 -0
- package/dist/search-tools.d.ts +10 -13
- package/dist/search-tools.d.ts.map +1 -1
- package/dist/search-tools.js +63 -140
- package/dist/search-tools.js.map +1 -1
- package/dist/system-tools.d.ts +19 -5
- package/dist/system-tools.d.ts.map +1 -1
- package/dist/system-tools.js +16 -10
- package/dist/system-tools.js.map +1 -1
- package/package.json +12 -2
- package/dist/phone-tools.d.ts +0 -27
- package/dist/phone-tools.d.ts.map +0 -1
- package/dist/phone-tools.js +0 -577
- package/dist/phone-tools.js.map +0 -1
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazy resolvers that map a Polpo provider name + ResolvedVault into an
|
|
3
|
+
* AI SDK provider instance. Each resolver dynamically imports the
|
|
4
|
+
* provider package so it stays optional — installing `@polpo-ai/tools`
|
|
5
|
+
* does not pull in `@ai-sdk/fal` / `@ai-sdk/anthropic` / etc unless the
|
|
6
|
+
* matching tool is actually used.
|
|
7
|
+
*
|
|
8
|
+
* Vault key conventions (must match the strings in the tools):
|
|
9
|
+
* - `fal-ai` / "key" → fal.ai (image_generate, video_generate)
|
|
10
|
+
* - `openai` / "key" → OpenAI (image_analyze)
|
|
11
|
+
* - `anthropic` / "key" → Anthropic (image_analyze)
|
|
12
|
+
*
|
|
13
|
+
* Env-var fallbacks are read by the tool layer, not here. Resolvers
|
|
14
|
+
* receive a fully-resolved API key string.
|
|
15
|
+
*/
|
|
16
|
+
// ── Resolvers ──
|
|
17
|
+
/** Build a fal.ai image provider. Throws a friendly error if the optional `@ai-sdk/fal` package is not installed. */
|
|
18
|
+
export async function resolveImageProvider(name, apiKey) {
|
|
19
|
+
if (name !== "fal") {
|
|
20
|
+
throw new Error(`Unknown image provider: ${name}`);
|
|
21
|
+
}
|
|
22
|
+
const mod = await loadOptional("@ai-sdk/fal", "image_generate");
|
|
23
|
+
// @ts-ignore — mod typed as `any` from the dynamic import helper
|
|
24
|
+
const fal = mod.createFal({ apiKey });
|
|
25
|
+
return { image: (modelId) => fal.image(modelId) };
|
|
26
|
+
}
|
|
27
|
+
/** Build a video provider — currently fal.ai only. */
|
|
28
|
+
export async function resolveVideoProvider(name, apiKey) {
|
|
29
|
+
if (name !== "fal") {
|
|
30
|
+
throw new Error(`Unknown video provider: ${name}`);
|
|
31
|
+
}
|
|
32
|
+
// fal.ai uses image-style queue API even for video; reuse the image
|
|
33
|
+
// provider's queue path. The `ai` SDK `experimental_generateVideo`
|
|
34
|
+
// accepts the result of `fal.video(...)`.
|
|
35
|
+
const mod = await loadOptional("@ai-sdk/fal", "video_generate");
|
|
36
|
+
// @ts-ignore — mod typed as `any` from the dynamic import helper
|
|
37
|
+
const fal = mod.createFal({ apiKey });
|
|
38
|
+
return { video: (modelId) => fal.video(modelId) };
|
|
39
|
+
}
|
|
40
|
+
/** Build a speech-to-text (transcription) provider. */
|
|
41
|
+
export async function resolveTranscribeProvider(name, apiKey) {
|
|
42
|
+
if (name === "openai") {
|
|
43
|
+
const mod = await loadOptional("@ai-sdk/openai", "audio_transcribe (openai)");
|
|
44
|
+
// @ts-ignore — mod typed as `any` from the dynamic import helper
|
|
45
|
+
const openai = mod.createOpenAI({ apiKey });
|
|
46
|
+
return { transcription: (modelId) => openai.transcription(modelId) };
|
|
47
|
+
}
|
|
48
|
+
if (name === "deepgram") {
|
|
49
|
+
const mod = await loadOptional("@ai-sdk/deepgram", "audio_transcribe (deepgram)");
|
|
50
|
+
// @ts-ignore — mod typed as `any` from the dynamic import helper
|
|
51
|
+
const deepgram = mod.createDeepgram({ apiKey });
|
|
52
|
+
return { transcription: (modelId) => deepgram.transcription(modelId) };
|
|
53
|
+
}
|
|
54
|
+
throw new Error(`Unknown transcribe provider: ${name}`);
|
|
55
|
+
}
|
|
56
|
+
/** Build a text-to-speech provider. The local `edge` provider needs a
|
|
57
|
+
* Shell + FileSystem (no API key); cloud providers need an API key. */
|
|
58
|
+
export async function resolveSpeakProvider(name, config) {
|
|
59
|
+
if (name === "edge") {
|
|
60
|
+
if (!config.shell || !config.fs) {
|
|
61
|
+
throw new Error("edge provider requires shell and fs to be supplied");
|
|
62
|
+
}
|
|
63
|
+
const { createEdgeSpeechProvider } = await import("./edge-speech-model.js");
|
|
64
|
+
return createEdgeSpeechProvider({ shell: config.shell, fs: config.fs });
|
|
65
|
+
}
|
|
66
|
+
if (!config.apiKey) {
|
|
67
|
+
throw new Error(`${name} speech provider requires an apiKey`);
|
|
68
|
+
}
|
|
69
|
+
if (name === "openai") {
|
|
70
|
+
const mod = await loadOptional("@ai-sdk/openai", "audio_speak (openai)");
|
|
71
|
+
// @ts-ignore — mod typed as `any` from the dynamic import helper
|
|
72
|
+
const openai = mod.createOpenAI({ apiKey: config.apiKey });
|
|
73
|
+
return { speech: (modelId) => openai.speech(modelId) };
|
|
74
|
+
}
|
|
75
|
+
if (name === "deepgram") {
|
|
76
|
+
const mod = await loadOptional("@ai-sdk/deepgram", "audio_speak (deepgram)");
|
|
77
|
+
// @ts-ignore — mod typed as `any` from the dynamic import helper
|
|
78
|
+
const deepgram = mod.createDeepgram({ apiKey: config.apiKey });
|
|
79
|
+
return { speech: (modelId) => deepgram.speech(modelId) };
|
|
80
|
+
}
|
|
81
|
+
if (name === "elevenlabs") {
|
|
82
|
+
const mod = await loadOptional("@ai-sdk/elevenlabs", "audio_speak (elevenlabs)");
|
|
83
|
+
// @ts-ignore — mod typed as `any` from the dynamic import helper
|
|
84
|
+
const elevenlabs = mod.createElevenLabs({ apiKey: config.apiKey });
|
|
85
|
+
return { speech: (modelId) => elevenlabs.speech(modelId) };
|
|
86
|
+
}
|
|
87
|
+
throw new Error(`Unknown speak provider: ${name}`);
|
|
88
|
+
}
|
|
89
|
+
/** Build a vision (multimodal LanguageModel) provider. */
|
|
90
|
+
export async function resolveVisionProvider(name, apiKey) {
|
|
91
|
+
if (name === "openai") {
|
|
92
|
+
const mod = await loadOptional("@ai-sdk/openai", "image_analyze (openai)");
|
|
93
|
+
// @ts-ignore — mod typed as `any` from the dynamic import helper
|
|
94
|
+
const openai = mod.createOpenAI({ apiKey });
|
|
95
|
+
return (modelId) => openai(modelId);
|
|
96
|
+
}
|
|
97
|
+
if (name === "anthropic") {
|
|
98
|
+
const mod = await loadOptional("@ai-sdk/anthropic", "image_analyze (anthropic)");
|
|
99
|
+
// @ts-ignore — mod typed as `any` from the dynamic import helper
|
|
100
|
+
const anthropic = mod.createAnthropic({ apiKey });
|
|
101
|
+
return (modelId) => anthropic(modelId);
|
|
102
|
+
}
|
|
103
|
+
throw new Error(`Unknown vision provider: ${name}`);
|
|
104
|
+
}
|
|
105
|
+
// ── Internal ──
|
|
106
|
+
async function loadOptional(pkg, toolName) {
|
|
107
|
+
try {
|
|
108
|
+
return await import(pkg);
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
throw new Error(`${pkg} is required for ${toolName} but is not installed. ` +
|
|
112
|
+
`Install it with: pnpm add ${pkg}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=provider-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-resolver.js","sourceRoot":"","sources":["../../src/lib/provider-resolver.ts"],"names":[],"mappings":"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"}
|
package/dist/search-tools.d.ts
CHANGED
|
@@ -1,22 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Web search tools
|
|
2
|
+
* Web search tools — thin wrappers over a SearchProvider.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* - search_web: Search the web with a natural language query
|
|
9
|
-
* - search_find_similar: Find pages similar to a given URL
|
|
4
|
+
* The provider is injected by the shell (OSS today: ExaSearchProvider).
|
|
5
|
+
* The tool layer doesn't know which backend runs; it formats results
|
|
6
|
+
* for the agent and surfaces errors. `search_find_similar` is registered
|
|
7
|
+
* only when the provider implements the optional `findSimilar` method.
|
|
10
8
|
*/
|
|
11
|
-
import type { PolpoTool as AgentTool } from "@polpo-ai/core";
|
|
12
|
-
import type { ResolvedVault } from "./types.js";
|
|
9
|
+
import type { PolpoTool as AgentTool, SearchProvider } from "@polpo-ai/core";
|
|
13
10
|
export type SearchToolName = "search_web" | "search_find_similar";
|
|
14
11
|
export declare const ALL_SEARCH_TOOL_NAMES: readonly SearchToolName[];
|
|
15
12
|
/**
|
|
16
|
-
* Create
|
|
13
|
+
* Create web search tools backed by a SearchProvider.
|
|
17
14
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
15
|
+
* `search_find_similar` is only registered when the provider supports
|
|
16
|
+
* it (i.e. exposes the optional `findSimilar` method).
|
|
20
17
|
*/
|
|
21
|
-
export declare function createSearchTools(
|
|
18
|
+
export declare function createSearchTools(provider: SearchProvider, allowedTools?: string[]): AgentTool<any>[];
|
|
22
19
|
//# sourceMappingURL=search-tools.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-tools.d.ts","sourceRoot":"","sources":["../src/search-tools.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"search-tools.d.ts","sourceRoot":"","sources":["../src/search-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,SAAS,IAAI,SAAS,EAAE,cAAc,EAAgB,MAAM,gBAAgB,CAAC;AAkH3F,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG,qBAAqB,CAAC;AAElE,eAAO,MAAM,qBAAqB,EAAE,SAAS,cAAc,EAA0C,CAAC;AAEtG;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,cAAc,EACxB,YAAY,CAAC,EAAE,MAAM,EAAE,GACtB,SAAS,CAAC,GAAG,CAAC,EAAE,CASlB"}
|
package/dist/search-tools.js
CHANGED
|
@@ -1,122 +1,71 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Web search tools
|
|
2
|
+
* Web search tools — thin wrappers over a SearchProvider.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* - search_web: Search the web with a natural language query
|
|
9
|
-
* - search_find_similar: Find pages similar to a given URL
|
|
4
|
+
* The provider is injected by the shell (OSS today: ExaSearchProvider).
|
|
5
|
+
* The tool layer doesn't know which backend runs; it formats results
|
|
6
|
+
* for the agent and surfaces errors. `search_find_similar` is registered
|
|
7
|
+
* only when the provider implements the optional `findSimilar` method.
|
|
10
8
|
*/
|
|
11
9
|
import { Type } from "@sinclair/typebox";
|
|
12
|
-
const EXA_BASE = "https://api.exa.ai";
|
|
13
10
|
const DEFAULT_NUM_RESULTS = 5;
|
|
14
|
-
const DEFAULT_TIMEOUT = 15_000;
|
|
15
11
|
// ─── Helpers ───
|
|
16
|
-
function
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
function ok(text, details) {
|
|
13
|
+
return { content: [{ type: "text", text }], details: details ?? {} };
|
|
14
|
+
}
|
|
15
|
+
function err(text) {
|
|
16
|
+
return { content: [{ type: "text", text }], details: { error: true } };
|
|
19
17
|
}
|
|
20
|
-
function
|
|
21
|
-
function err(text) { return { content: [{ type: "text", text }], details: { error: true } }; }
|
|
22
|
-
function formatResults(results, withContent) {
|
|
18
|
+
function formatResults(results) {
|
|
23
19
|
if (results.length === 0)
|
|
24
20
|
return "(no results)";
|
|
25
21
|
return results.map((r, i) => {
|
|
26
|
-
const parts = [`${i + 1}. **${r.title}**`, ` ${r.url}`];
|
|
22
|
+
const parts = [`${i + 1}. **${r.title || r.url}**`, ` ${r.url}`];
|
|
27
23
|
if (r.publishedDate)
|
|
28
24
|
parts.push(` Published: ${r.publishedDate}`);
|
|
29
|
-
if (r.
|
|
30
|
-
parts.push(` Author: ${r.author}`);
|
|
31
|
-
if (r.summary) {
|
|
32
|
-
parts.push(` Summary: ${r.summary}`);
|
|
33
|
-
}
|
|
34
|
-
else if (withContent && r.text) {
|
|
35
|
-
// Truncate content to avoid token bloat
|
|
25
|
+
if (r.text) {
|
|
36
26
|
const text = r.text.length > 1500 ? r.text.slice(0, 1500) + "..." : r.text;
|
|
37
|
-
parts.push(`
|
|
38
|
-
}
|
|
39
|
-
if (r.highlights?.length) {
|
|
40
|
-
parts.push(` Highlights:`);
|
|
41
|
-
for (const h of r.highlights.slice(0, 3)) {
|
|
42
|
-
parts.push(` - ${h}`);
|
|
43
|
-
}
|
|
27
|
+
parts.push(` ${text}`);
|
|
44
28
|
}
|
|
45
29
|
return parts.join("\n");
|
|
46
30
|
}).join("\n\n");
|
|
47
31
|
}
|
|
48
32
|
// ─── Tool: search_web ───
|
|
49
33
|
const SearchWebSchema = Type.Object({
|
|
50
|
-
query: Type.String({ description: "Natural language search query. Be descriptive —
|
|
34
|
+
query: Type.String({ description: "Natural language search query. Be descriptive — semantic search providers reward intent over keywords." }),
|
|
51
35
|
numResults: Type.Optional(Type.Number({ description: `Number of results to return (default: ${DEFAULT_NUM_RESULTS}, max: 20)` })),
|
|
52
36
|
includeContent: Type.Optional(Type.Boolean({ description: "Include page content/summary in results (default: true). Costs more but saves a follow-up http_fetch." })),
|
|
53
37
|
includeDomains: Type.Optional(Type.Array(Type.String(), { description: "Only return results from these domains (e.g. ['github.com', 'docs.python.org'])" })),
|
|
54
38
|
excludeDomains: Type.Optional(Type.Array(Type.String(), { description: "Exclude results from these domains" })),
|
|
55
39
|
startPublishedDate: Type.Optional(Type.String({ description: "Only results published after this date (ISO format, e.g. '2024-01-01')" })),
|
|
56
|
-
|
|
40
|
+
endPublishedDate: Type.Optional(Type.String({ description: "Only results published before this date (ISO format)" })),
|
|
57
41
|
});
|
|
58
|
-
function createSearchWebTool(
|
|
42
|
+
function createSearchWebTool(provider) {
|
|
59
43
|
return {
|
|
60
44
|
name: "search_web",
|
|
61
45
|
label: "Web Search",
|
|
62
|
-
description:
|
|
63
|
-
"Use natural language queries
|
|
64
|
-
"Example: 'how to implement OAuth2 with Better Auth in Next.js'",
|
|
46
|
+
description: `Search the web via ${provider.name}. Returns relevant pages with titles, URLs, and optionally snippet/summary. ` +
|
|
47
|
+
"Use natural language queries. Example: 'how to implement OAuth2 with Better Auth in Next.js'",
|
|
65
48
|
parameters: SearchWebSchema,
|
|
66
49
|
async execute(_id, params, signal) {
|
|
67
|
-
const apiKey = getExaApiKey(vault);
|
|
68
|
-
if (!apiKey) {
|
|
69
|
-
return err("Error: EXA_API_KEY not found. Add it to vault (service: exa, key: key) or set as environment variable.");
|
|
70
|
-
}
|
|
71
|
-
const numResults = Math.min(params.numResults ?? DEFAULT_NUM_RESULTS, 20);
|
|
72
|
-
const includeContent = params.includeContent ?? true;
|
|
73
|
-
const body = {
|
|
74
|
-
query: params.query,
|
|
75
|
-
numResults,
|
|
76
|
-
type: "auto",
|
|
77
|
-
};
|
|
78
|
-
if (includeContent) {
|
|
79
|
-
body.contents = {
|
|
80
|
-
text: { maxCharacters: 2000 },
|
|
81
|
-
highlights: { numSentences: 3 },
|
|
82
|
-
summary: { query: params.query },
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
if (params.includeDomains?.length)
|
|
86
|
-
body.includeDomains = params.includeDomains;
|
|
87
|
-
if (params.excludeDomains?.length)
|
|
88
|
-
body.excludeDomains = params.excludeDomains;
|
|
89
|
-
if (params.startPublishedDate)
|
|
90
|
-
body.startPublishedDate = params.startPublishedDate;
|
|
91
|
-
if (params.category)
|
|
92
|
-
body.category = params.category;
|
|
93
50
|
try {
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
51
|
+
const results = await provider.search(params.query, {
|
|
52
|
+
numResults: params.numResults,
|
|
53
|
+
includeText: params.includeContent ?? true,
|
|
54
|
+
includeDomains: params.includeDomains,
|
|
55
|
+
excludeDomains: params.excludeDomains,
|
|
56
|
+
startPublishedDate: params.startPublishedDate,
|
|
57
|
+
endPublishedDate: params.endPublishedDate,
|
|
58
|
+
signal,
|
|
59
|
+
});
|
|
60
|
+
const header = `Found ${results.length} result(s) for: "${params.query}"`;
|
|
61
|
+
return ok(`${header}\n\n${formatResults(results)}`, {
|
|
62
|
+
provider: provider.name,
|
|
63
|
+
query: params.query,
|
|
64
|
+
count: results.length,
|
|
106
65
|
});
|
|
107
|
-
clearTimeout(timeout);
|
|
108
|
-
if (!response.ok) {
|
|
109
|
-
const errText = await response.text().catch(() => "");
|
|
110
|
-
return err(`Error: Exa API returned ${response.status}: ${errText}`);
|
|
111
|
-
}
|
|
112
|
-
const data = (await response.json());
|
|
113
|
-
const formatted = formatResults(data.results, includeContent);
|
|
114
|
-
const header = `Found ${data.results.length} result(s) for: "${params.query}"`;
|
|
115
|
-
return ok(`${header}\n\n${formatted}`);
|
|
116
66
|
}
|
|
117
67
|
catch (e) {
|
|
118
|
-
|
|
119
|
-
return err(`Error: Web search failed — ${message}`);
|
|
68
|
+
return err(`Error: web search failed (${provider.name}) — ${e.message}`);
|
|
120
69
|
}
|
|
121
70
|
},
|
|
122
71
|
};
|
|
@@ -128,78 +77,52 @@ const FindSimilarSchema = Type.Object({
|
|
|
128
77
|
includeContent: Type.Optional(Type.Boolean({ description: "Include page content/summary (default: false)" })),
|
|
129
78
|
excludeDomains: Type.Optional(Type.Array(Type.String(), { description: "Exclude results from these domains" })),
|
|
130
79
|
});
|
|
131
|
-
function createFindSimilarTool(
|
|
80
|
+
function createFindSimilarTool(provider) {
|
|
132
81
|
return {
|
|
133
82
|
name: "search_find_similar",
|
|
134
83
|
label: "Find Similar Pages",
|
|
135
|
-
description:
|
|
136
|
-
"Example:
|
|
84
|
+
description: `Find web pages similar to a given URL via ${provider.name}. Useful for finding alternatives, ` +
|
|
85
|
+
"competitors, or related resources. Example: pass a GitHub repo URL to find similar projects.",
|
|
137
86
|
parameters: FindSimilarSchema,
|
|
138
87
|
async execute(_id, params, signal) {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
return err("Error: EXA_API_KEY not found. Add it to vault or set as environment variable.");
|
|
142
|
-
}
|
|
143
|
-
const numResults = Math.min(params.numResults ?? DEFAULT_NUM_RESULTS, 20);
|
|
144
|
-
const includeContent = params.includeContent ?? false;
|
|
145
|
-
const body = {
|
|
146
|
-
url: params.url,
|
|
147
|
-
numResults,
|
|
148
|
-
};
|
|
149
|
-
if (includeContent) {
|
|
150
|
-
body.contents = {
|
|
151
|
-
text: { maxCharacters: 2000 },
|
|
152
|
-
highlights: { numSentences: 3 },
|
|
153
|
-
};
|
|
88
|
+
if (!provider.findSimilar) {
|
|
89
|
+
return err(`Error: provider '${provider.name}' does not support findSimilar`);
|
|
154
90
|
}
|
|
155
|
-
if (params.excludeDomains?.length)
|
|
156
|
-
body.excludeDomains = params.excludeDomains;
|
|
157
91
|
try {
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
signal: controller.signal,
|
|
92
|
+
const results = await provider.findSimilar(params.url, {
|
|
93
|
+
numResults: params.numResults,
|
|
94
|
+
includeText: params.includeContent ?? false,
|
|
95
|
+
excludeDomains: params.excludeDomains,
|
|
96
|
+
signal,
|
|
97
|
+
});
|
|
98
|
+
const header = `Found ${results.length} page(s) similar to: ${params.url}`;
|
|
99
|
+
return ok(`${header}\n\n${formatResults(results)}`, {
|
|
100
|
+
provider: provider.name,
|
|
101
|
+
url: params.url,
|
|
102
|
+
count: results.length,
|
|
170
103
|
});
|
|
171
|
-
clearTimeout(timeout);
|
|
172
|
-
if (!response.ok) {
|
|
173
|
-
const errText = await response.text().catch(() => "");
|
|
174
|
-
return err(`Error: Exa API returned ${response.status}: ${errText}`);
|
|
175
|
-
}
|
|
176
|
-
const data = (await response.json());
|
|
177
|
-
const formatted = formatResults(data.results, includeContent);
|
|
178
|
-
const header = `Found ${data.results.length} page(s) similar to: ${params.url}`;
|
|
179
|
-
return ok(`${header}\n\n${formatted}`);
|
|
180
104
|
}
|
|
181
105
|
catch (e) {
|
|
182
|
-
|
|
183
|
-
return err(`Error: Find similar failed — ${message}`);
|
|
106
|
+
return err(`Error: find similar failed (${provider.name}) — ${e.message}`);
|
|
184
107
|
}
|
|
185
108
|
},
|
|
186
109
|
};
|
|
187
110
|
}
|
|
188
111
|
export const ALL_SEARCH_TOOL_NAMES = ["search_web", "search_find_similar"];
|
|
189
112
|
/**
|
|
190
|
-
* Create
|
|
113
|
+
* Create web search tools backed by a SearchProvider.
|
|
191
114
|
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
115
|
+
* `search_find_similar` is only registered when the provider supports
|
|
116
|
+
* it (i.e. exposes the optional `findSimilar` method).
|
|
194
117
|
*/
|
|
195
|
-
export function createSearchTools(
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
return
|
|
118
|
+
export function createSearchTools(provider, allowedTools) {
|
|
119
|
+
const tools = [createSearchWebTool(provider)];
|
|
120
|
+
if (provider.findSimilar) {
|
|
121
|
+
tools.push(createFindSimilarTool(provider));
|
|
122
|
+
}
|
|
123
|
+
if (!allowedTools)
|
|
124
|
+
return tools;
|
|
125
|
+
const allowed = new Set(allowedTools.map(a => a.toLowerCase()));
|
|
126
|
+
return tools.filter(t => allowed.has(t.name));
|
|
204
127
|
}
|
|
205
128
|
//# sourceMappingURL=search-tools.js.map
|
package/dist/search-tools.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-tools.js","sourceRoot":"","sources":["../src/search-tools.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"search-tools.js","sourceRoot":"","sources":["../src/search-tools.ts"],"names":[],"mappings":"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"}
|
package/dist/system-tools.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { FileSystem } from "@polpo-ai/core/filesystem";
|
|
9
9
|
import type { Shell } from "@polpo-ai/core/shell";
|
|
10
|
-
import type { PolpoTool as AgentTool } from "@polpo-ai/core";
|
|
10
|
+
import type { PolpoTool as AgentTool, SearchProvider } from "@polpo-ai/core";
|
|
11
11
|
import type { ResolvedVault } from "./types.js";
|
|
12
12
|
/**
|
|
13
13
|
* Check if a tool name matches an allowed pattern.
|
|
@@ -45,14 +45,13 @@ export type { ExcelToolName } from "./excel-tools.js";
|
|
|
45
45
|
export type { PdfToolName } from "./pdf-tools.js";
|
|
46
46
|
export type { DocxToolName } from "./docx-tools.js";
|
|
47
47
|
export type { SearchToolName } from "./search-tools.js";
|
|
48
|
-
export type { PhoneToolName } from "./phone-tools.js";
|
|
49
48
|
/** All known tool names across all categories */
|
|
50
|
-
export type ExtendedToolName = SystemToolName | import("./browser-tools.js").BrowserToolName | import("./http-tools.js").HttpToolName | import("./email-tools.js").EmailToolName | import("./outcome-tools.js").OutcomeToolName | import("./vault-tools.js").VaultToolName | import("./image-tools.js").ImageToolName | import("./audio-tools.js").AudioToolName | import("./excel-tools.js").ExcelToolName | import("./pdf-tools.js").PdfToolName | import("./docx-tools.js").DocxToolName | import("./search-tools.js").SearchToolName
|
|
49
|
+
export type ExtendedToolName = SystemToolName | import("./browser-tools.js").BrowserToolName | import("./http-tools.js").HttpToolName | import("./email-tools.js").EmailToolName | import("./outcome-tools.js").OutcomeToolName | import("./vault-tools.js").VaultToolName | import("./image-tools.js").ImageToolName | import("./audio-tools.js").AudioToolName | import("./excel-tools.js").ExcelToolName | import("./pdf-tools.js").PdfToolName | import("./docx-tools.js").DocxToolName | import("./search-tools.js").SearchToolName;
|
|
51
50
|
/**
|
|
52
51
|
* Public catalog of every configurable built-in tool name (core coding
|
|
53
52
|
* + http + vault + browser + email + image + audio + excel + pdf +
|
|
54
|
-
* docx + search
|
|
55
|
-
*
|
|
53
|
+
* docx + search). Use this for config validation, documentation,
|
|
54
|
+
* and the `/v1/tools` endpoint.
|
|
56
55
|
*
|
|
57
56
|
* Notable exclusion: `register_outcome` is not listed. It's a
|
|
58
57
|
* task-only infrastructural tool, injected automatically when the
|
|
@@ -84,6 +83,21 @@ export interface CreateAllToolsOptions {
|
|
|
84
83
|
fs?: FileSystem;
|
|
85
84
|
/** Shell implementation (default: NodeShell). */
|
|
86
85
|
shell?: Shell;
|
|
86
|
+
/** image_generate model. e.g. "fal/fal-ai/flux/dev" */
|
|
87
|
+
imageModel?: string;
|
|
88
|
+
/** video_generate model. e.g. "fal/luma-ray-2-flash" */
|
|
89
|
+
videoModel?: string;
|
|
90
|
+
/** image_analyze model. e.g. "openai/gpt-4o-mini" */
|
|
91
|
+
visionModel?: string;
|
|
92
|
+
/** audio_transcribe model. e.g. "openai/whisper-1" */
|
|
93
|
+
transcribeModel?: string;
|
|
94
|
+
/** audio_speak model. e.g. "openai/tts-1" or "edge/edge-tts" */
|
|
95
|
+
ttsModel?: string;
|
|
96
|
+
/** Pre-instantiated SearchProvider. When omitted, falls back to
|
|
97
|
+
* ExaSearchProvider built from the vault's "exa" key. The cloud
|
|
98
|
+
* shell can swap in a Gateway-routed provider here without
|
|
99
|
+
* touching the tool layer. */
|
|
100
|
+
searchProvider?: SearchProvider;
|
|
87
101
|
}
|
|
88
102
|
/**
|
|
89
103
|
* Create all available tools for an agent, including extended tool categories.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-tools.d.ts","sourceRoot":"","sources":["../src/system-tools.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAIlD,OAAO,KAAK,EAAE,SAAS,IAAI,SAAS,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"system-tools.d.ts","sourceRoot":"","sources":["../src/system-tools.ts"],"names":[],"mappings":"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"}
|
package/dist/system-tools.js
CHANGED
|
@@ -356,12 +356,11 @@ import { createExcelTools, ALL_EXCEL_TOOL_NAMES } from "./excel-tools.js";
|
|
|
356
356
|
import { createPdfTools, ALL_PDF_TOOL_NAMES } from "./pdf-tools.js";
|
|
357
357
|
import { createDocxTools, ALL_DOCX_TOOL_NAMES } from "./docx-tools.js";
|
|
358
358
|
import { createSearchTools, ALL_SEARCH_TOOL_NAMES } from "./search-tools.js";
|
|
359
|
-
import { createPhoneTools, ALL_PHONE_TOOL_NAMES } from "./phone-tools.js";
|
|
360
359
|
/**
|
|
361
360
|
* Public catalog of every configurable built-in tool name (core coding
|
|
362
361
|
* + http + vault + browser + email + image + audio + excel + pdf +
|
|
363
|
-
* docx + search
|
|
364
|
-
*
|
|
362
|
+
* docx + search). Use this for config validation, documentation,
|
|
363
|
+
* and the `/v1/tools` endpoint.
|
|
365
364
|
*
|
|
366
365
|
* Notable exclusion: `register_outcome` is not listed. It's a
|
|
367
366
|
* task-only infrastructural tool, injected automatically when the
|
|
@@ -380,7 +379,6 @@ export const TOOL_CATALOG = [
|
|
|
380
379
|
...ALL_PDF_TOOL_NAMES,
|
|
381
380
|
...ALL_DOCX_TOOL_NAMES,
|
|
382
381
|
...ALL_SEARCH_TOOL_NAMES,
|
|
383
|
-
...ALL_PHONE_TOOL_NAMES,
|
|
384
382
|
];
|
|
385
383
|
/**
|
|
386
384
|
* Create all available tools for an agent, including extended tool categories.
|
|
@@ -434,13 +432,21 @@ export async function createAllTools(options) {
|
|
|
434
432
|
if (categoryRequested(ALL_DOCX_TOOL_NAMES)) {
|
|
435
433
|
tools.push(...createDocxTools(cwd, allowedPaths, allowedTools, options.fs));
|
|
436
434
|
}
|
|
437
|
-
// Search tools
|
|
435
|
+
// Search tools — activated when any search_* tool is in allowedTools.
|
|
436
|
+
// Provider injection: pre-instantiated `searchProvider` wins;
|
|
437
|
+
// otherwise we default to ExaSearchProvider built from the vault.
|
|
438
438
|
if (categoryRequested(ALL_SEARCH_TOOL_NAMES)) {
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
439
|
+
let provider = options.searchProvider;
|
|
440
|
+
if (!provider) {
|
|
441
|
+
const exaKey = options.vault?.getKey("exa", "key") ?? process.env.EXA_API_KEY;
|
|
442
|
+
if (exaKey) {
|
|
443
|
+
const { ExaSearchProvider } = await import("./lib/exa-search-provider.js");
|
|
444
|
+
provider = new ExaSearchProvider({ apiKey: exaKey });
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
if (provider) {
|
|
448
|
+
tools.push(...createSearchTools(provider, allowedTools));
|
|
449
|
+
}
|
|
444
450
|
}
|
|
445
451
|
// HTTP, register_outcome, and vault are already included via createSystemTools() above — no need to add again
|
|
446
452
|
return tools;
|