@fortressllm/sybil 0.0.3
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/.env copy +91 -0
- package/.env.example +139 -0
- package/BROWSER_CONTROL.md +354 -0
- package/CLI_CHAT_FEATURE.md +224 -0
- package/CLI_GUIDE.md +359 -0
- package/DYNAMIC_SKILLS.md +345 -0
- package/DockerFile.sandbox +14 -0
- package/PROGRESS.md +249 -0
- package/README.md +281 -0
- package/RENAME_LOG.md +62 -0
- package/SIMPLIFIED_TELEGRAM_UX.md +273 -0
- package/SYBIL_SUMMARY.md +360 -0
- package/TASK11_NETWORK.md +202 -0
- package/TASK14_CLI.md +432 -0
- package/TASK8_SAFETY.md +317 -0
- package/TASK9_COMPLETION.md +186 -0
- package/TASK9_SUMMARY.md +201 -0
- package/TELEGRAM_OTP_AUTH.md +359 -0
- package/VECTOR_MEMORY.md +163 -0
- package/assets/logo.png +0 -0
- package/cypfq_code_search.md +287 -0
- package/cypfq_driver_search.md +297 -0
- package/cypfq_github_search.md +297 -0
- package/cypfq_repo_search.md +370 -0
- package/dist/agents/autonomous-agent.d.ts +61 -0
- package/dist/agents/autonomous-agent.d.ts.map +1 -0
- package/dist/agents/autonomous-agent.js +536 -0
- package/dist/agents/autonomous-agent.js.map +1 -0
- package/dist/agents/network.d.ts +1006 -0
- package/dist/agents/network.d.ts.map +1 -0
- package/dist/agents/network.js +1266 -0
- package/dist/agents/network.js.map +1 -0
- package/dist/cli/commands/backup.d.ts +3 -0
- package/dist/cli/commands/backup.d.ts.map +1 -0
- package/dist/cli/commands/backup.js +63 -0
- package/dist/cli/commands/backup.js.map +1 -0
- package/dist/cli/commands/config.d.ts +3 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +163 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +3 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +107 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/init.d.ts +3 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +138 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/logs.d.ts +3 -0
- package/dist/cli/commands/logs.d.ts.map +1 -0
- package/dist/cli/commands/logs.js +81 -0
- package/dist/cli/commands/logs.js.map +1 -0
- package/dist/cli/commands/otp.d.ts +3 -0
- package/dist/cli/commands/otp.d.ts.map +1 -0
- package/dist/cli/commands/otp.js +142 -0
- package/dist/cli/commands/otp.js.map +1 -0
- package/dist/cli/commands/restore.d.ts +3 -0
- package/dist/cli/commands/restore.d.ts.map +1 -0
- package/dist/cli/commands/restore.js +99 -0
- package/dist/cli/commands/restore.js.map +1 -0
- package/dist/cli/commands/start.d.ts +3 -0
- package/dist/cli/commands/start.d.ts.map +1 -0
- package/dist/cli/commands/start.js +65 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/status.d.ts +3 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +68 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/stop.d.ts +3 -0
- package/dist/cli/commands/stop.d.ts.map +1 -0
- package/dist/cli/commands/stop.js +62 -0
- package/dist/cli/commands/stop.js.map +1 -0
- package/dist/cli/commands/update.d.ts +3 -0
- package/dist/cli/commands/update.d.ts.map +1 -0
- package/dist/cli/commands/update.js +49 -0
- package/dist/cli/commands/update.js.map +1 -0
- package/dist/cli/commands/whatsapp.d.ts +3 -0
- package/dist/cli/commands/whatsapp.d.ts.map +1 -0
- package/dist/cli/commands/whatsapp.js +281 -0
- package/dist/cli/commands/whatsapp.js.map +1 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +58 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +750 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +109 -0
- package/dist/index.js.map +1 -0
- package/dist/mastra/index.d.ts +4 -0
- package/dist/mastra/index.d.ts.map +1 -0
- package/dist/mastra/index.js +37 -0
- package/dist/mastra/index.js.map +1 -0
- package/dist/mastra/memory.d.ts +9 -0
- package/dist/mastra/memory.d.ts.map +1 -0
- package/dist/mastra/memory.js +92 -0
- package/dist/mastra/memory.js.map +1 -0
- package/dist/processors/index.d.ts +74 -0
- package/dist/processors/index.d.ts.map +1 -0
- package/dist/processors/index.js +153 -0
- package/dist/processors/index.js.map +1 -0
- package/dist/processors/semantic-recall.d.ts +63 -0
- package/dist/processors/semantic-recall.d.ts.map +1 -0
- package/dist/processors/semantic-recall.js +216 -0
- package/dist/processors/semantic-recall.js.map +1 -0
- package/dist/processors/tool-search.d.ts +26 -0
- package/dist/processors/tool-search.d.ts.map +1 -0
- package/dist/processors/tool-search.js +41 -0
- package/dist/processors/tool-search.js.map +1 -0
- package/dist/skills/dynamic/skill-generator.d.ts +169 -0
- package/dist/skills/dynamic/skill-generator.d.ts.map +1 -0
- package/dist/skills/dynamic/skill-generator.js +488 -0
- package/dist/skills/dynamic/skill-generator.js.map +1 -0
- package/dist/tools/agent-delegation-tools.d.ts +142 -0
- package/dist/tools/agent-delegation-tools.d.ts.map +1 -0
- package/dist/tools/agent-delegation-tools.js +263 -0
- package/dist/tools/agent-delegation-tools.js.map +1 -0
- package/dist/tools/browser-tools.d.ts +374 -0
- package/dist/tools/browser-tools.d.ts.map +1 -0
- package/dist/tools/browser-tools.js +752 -0
- package/dist/tools/browser-tools.js.map +1 -0
- package/dist/tools/dynamic/registry.d.ts +61 -0
- package/dist/tools/dynamic/registry.d.ts.map +1 -0
- package/dist/tools/dynamic/registry.js +121 -0
- package/dist/tools/dynamic/registry.js.map +1 -0
- package/dist/tools/dynamic/tool-generator.d.ts +99 -0
- package/dist/tools/dynamic/tool-generator.d.ts.map +1 -0
- package/dist/tools/dynamic/tool-generator.js +367 -0
- package/dist/tools/dynamic/tool-generator.js.map +1 -0
- package/dist/tools/extended-tools.d.ts +176 -0
- package/dist/tools/extended-tools.d.ts.map +1 -0
- package/dist/tools/extended-tools.js +464 -0
- package/dist/tools/extended-tools.js.map +1 -0
- package/dist/tools/library/calendar/index.d.ts +134 -0
- package/dist/tools/library/calendar/index.d.ts.map +1 -0
- package/dist/tools/library/calendar/index.js +160 -0
- package/dist/tools/library/calendar/index.js.map +1 -0
- package/dist/tools/podman-workspace-mcp-cli.d.ts +3 -0
- package/dist/tools/podman-workspace-mcp-cli.d.ts.map +1 -0
- package/dist/tools/podman-workspace-mcp-cli.js +12 -0
- package/dist/tools/podman-workspace-mcp-cli.js.map +1 -0
- package/dist/tools/podman-workspace-mcp.d.ts +247 -0
- package/dist/tools/podman-workspace-mcp.d.ts.map +1 -0
- package/dist/tools/podman-workspace-mcp.js +1093 -0
- package/dist/tools/podman-workspace-mcp.js.map +1 -0
- package/dist/tools/podman-workspace.d.ts +148 -0
- package/dist/tools/podman-workspace.d.ts.map +1 -0
- package/dist/tools/podman-workspace.js +682 -0
- package/dist/tools/podman-workspace.js.map +1 -0
- package/dist/tools/telegram-file-tools.d.ts +78 -0
- package/dist/tools/telegram-file-tools.d.ts.map +1 -0
- package/dist/tools/telegram-file-tools.js +294 -0
- package/dist/tools/telegram-file-tools.js.map +1 -0
- package/dist/tools/tool-registry.d.ts +467 -0
- package/dist/tools/tool-registry.d.ts.map +1 -0
- package/dist/tools/tool-registry.js +156 -0
- package/dist/tools/tool-registry.js.map +1 -0
- package/dist/tools/web-tools.d.ts +77 -0
- package/dist/tools/web-tools.d.ts.map +1 -0
- package/dist/tools/web-tools.js +416 -0
- package/dist/tools/web-tools.js.map +1 -0
- package/dist/tools/whatsapp-autoreply-tools.d.ts +118 -0
- package/dist/tools/whatsapp-autoreply-tools.d.ts.map +1 -0
- package/dist/tools/whatsapp-autoreply-tools.js +503 -0
- package/dist/tools/whatsapp-autoreply-tools.js.map +1 -0
- package/dist/tools/whatsapp-tools.d.ts +175 -0
- package/dist/tools/whatsapp-tools.d.ts.map +1 -0
- package/dist/tools/whatsapp-tools.js +566 -0
- package/dist/tools/whatsapp-tools.js.map +1 -0
- package/dist/utils/logger.d.ts +65 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +307 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/model-config.d.ts +73 -0
- package/dist/utils/model-config.d.ts.map +1 -0
- package/dist/utils/model-config.js +366 -0
- package/dist/utils/model-config.js.map +1 -0
- package/dist/utils/semantic-memory.d.ts +82 -0
- package/dist/utils/semantic-memory.d.ts.map +1 -0
- package/dist/utils/semantic-memory.js +189 -0
- package/dist/utils/semantic-memory.js.map +1 -0
- package/dist/utils/system.d.ts +2 -0
- package/dist/utils/system.d.ts.map +1 -0
- package/dist/utils/system.js +24 -0
- package/dist/utils/system.js.map +1 -0
- package/dist/utils/telegram-auth.d.ts +54 -0
- package/dist/utils/telegram-auth.d.ts.map +1 -0
- package/dist/utils/telegram-auth.js +146 -0
- package/dist/utils/telegram-auth.js.map +1 -0
- package/dist/utils/telegram.d.ts +7 -0
- package/dist/utils/telegram.d.ts.map +1 -0
- package/dist/utils/telegram.js +1494 -0
- package/dist/utils/telegram.js.map +1 -0
- package/dist/utils/whatsapp-client.d.ts +166 -0
- package/dist/utils/whatsapp-client.d.ts.map +1 -0
- package/dist/utils/whatsapp-client.js +722 -0
- package/dist/utils/whatsapp-client.js.map +1 -0
- package/dist/workflows/planner-workflow.d.ts +39 -0
- package/dist/workflows/planner-workflow.d.ts.map +1 -0
- package/dist/workflows/planner-workflow.js +165 -0
- package/dist/workflows/planner-workflow.js.map +1 -0
- package/dist/workflows/skill-builder-workflow.d.ts +16 -0
- package/dist/workflows/skill-builder-workflow.d.ts.map +1 -0
- package/dist/workflows/skill-builder-workflow.js +157 -0
- package/dist/workflows/skill-builder-workflow.js.map +1 -0
- package/dist/workspace/index.d.ts +23 -0
- package/dist/workspace/index.d.ts.map +1 -0
- package/dist/workspace/index.js +64 -0
- package/dist/workspace/index.js.map +1 -0
- package/docs/README.md +140 -0
- package/docs/api/agents.md +481 -0
- package/docs/api/browser-tools.md +469 -0
- package/docs/api/memory.md +629 -0
- package/docs/architecture/agent-networks.md +586 -0
- package/docs/architecture/memory.md +579 -0
- package/docs/architecture/overview.md +436 -0
- package/docs/architecture/tools.md +637 -0
- package/docs/cli-tui.md +367 -0
- package/docs/guides/environment-variables.md +502 -0
- package/docs/guides/troubleshooting.md +882 -0
- package/docs/tutorials/agent-networks.md +432 -0
- package/docs/tutorials/dynamic-tools.md +469 -0
- package/docs/tutorials/getting-started.md +263 -0
- package/docs/tutorials/skills.md +561 -0
- package/docs/tutorials/web-browsing.md +329 -0
- package/mastra.db-shm +0 -0
- package/mastra.db-wal +0 -0
- package/package.json +71 -0
- package/plan.md +601 -0
- package/skills/code-review/SKILL.md +48 -0
- package/skills/task-planning/SKILL.md +55 -0
- package/skills/web-research/SKILL.md +79 -0
- package/skills/whatsapp-management/SKILL.md +78 -0
- package/src/agents/autonomous-agent.ts +626 -0
- package/src/agents/network.ts +1307 -0
- package/src/cli/commands/backup.ts +78 -0
- package/src/cli/commands/config.ts +176 -0
- package/src/cli/commands/doctor.ts +111 -0
- package/src/cli/commands/init.ts +150 -0
- package/src/cli/commands/logs.ts +94 -0
- package/src/cli/commands/otp.ts +162 -0
- package/src/cli/commands/restore.ts +118 -0
- package/src/cli/commands/start.ts +76 -0
- package/src/cli/commands/status.ts +81 -0
- package/src/cli/commands/stop.ts +68 -0
- package/src/cli/commands/update.ts +61 -0
- package/src/cli/commands/whatsapp.ts +322 -0
- package/src/cli/index.ts +69 -0
- package/src/cli.ts +830 -0
- package/src/index.ts +124 -0
- package/src/mastra/index.ts +49 -0
- package/src/mastra/memory.ts +99 -0
- package/src/mastra/public/workspace/plan.md +115 -0
- package/src/mastra/public/workspace/research/react-tailwind/skill.md +47 -0
- package/src/processors/index.ts +170 -0
- package/src/processors/semantic-recall.ts +277 -0
- package/src/processors/tool-search.ts +46 -0
- package/src/skills/dynamic/skill-generator.ts +568 -0
- package/src/tools/agent-delegation-tools.ts +301 -0
- package/src/tools/browser-tools.ts +792 -0
- package/src/tools/dynamic/registry.ts +144 -0
- package/src/tools/dynamic/tool-generator.ts +406 -0
- package/src/tools/extended-tools.ts +498 -0
- package/src/tools/library/calendar/index.ts +172 -0
- package/src/tools/podman-workspace-mcp-cli.ts +14 -0
- package/src/tools/podman-workspace-mcp.ts +1290 -0
- package/src/tools/podman-workspace.ts +858 -0
- package/src/tools/telegram-file-tools.ts +320 -0
- package/src/tools/tool-registry.ts +233 -0
- package/src/tools/web-tools.ts +461 -0
- package/src/tools/whatsapp-autoreply-tools.ts +616 -0
- package/src/tools/whatsapp-tools.ts +602 -0
- package/src/utils/logger.ts +368 -0
- package/src/utils/model-config.ts +437 -0
- package/src/utils/semantic-memory.ts +230 -0
- package/src/utils/system.ts +25 -0
- package/src/utils/telegram-auth.ts +201 -0
- package/src/utils/telegram.ts +1847 -0
- package/src/utils/whatsapp-client.ts +808 -0
- package/src/workflows/planner-workflow.ts +178 -0
- package/src/workflows/skill-builder-workflow.ts +175 -0
- package/src/workspace/index.ts +69 -0
- package/tsconfig.json +22 -0
- package/view-logs.sh +116 -0
- package/whatsapp-session.sh +197 -0
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
import { createTool } from "@mastra/core/tools";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import axios from "axios";
|
|
4
|
+
import * as cheerio from "cheerio";
|
|
5
|
+
import { logger } from "../utils/logger.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Tool: Fetch Web Page Content
|
|
9
|
+
* Fetches and extracts content from a web page URL
|
|
10
|
+
*/
|
|
11
|
+
export const fetchWebContentTool = createTool({
|
|
12
|
+
id: "fetch-web-content",
|
|
13
|
+
description: `
|
|
14
|
+
Fetches and extracts the main content from a web page URL.
|
|
15
|
+
Use this when you need to read articles, documentation, or any web content.
|
|
16
|
+
Returns the content in a clean, readable format with title and main text.
|
|
17
|
+
`,
|
|
18
|
+
inputSchema: z.object({
|
|
19
|
+
url: z.string().url().describe("The URL of the web page to fetch"),
|
|
20
|
+
extractLinks: z.boolean().optional().default(false).describe("Whether to also extract links from the page"),
|
|
21
|
+
}),
|
|
22
|
+
outputSchema: z.object({
|
|
23
|
+
success: z.boolean(),
|
|
24
|
+
url: z.string(),
|
|
25
|
+
title: z.string(),
|
|
26
|
+
content: z.string(),
|
|
27
|
+
excerpt: z.string(),
|
|
28
|
+
links: z.array(z.object({
|
|
29
|
+
text: z.string(),
|
|
30
|
+
url: z.string(),
|
|
31
|
+
})).optional(),
|
|
32
|
+
error: z.string().optional(),
|
|
33
|
+
}),
|
|
34
|
+
execute: async (inputData) => {
|
|
35
|
+
const startTime = Date.now();
|
|
36
|
+
const { url, extractLinks } = inputData;
|
|
37
|
+
|
|
38
|
+
logger.info("WEB_TOOL", `Fetching web content: ${url}`, {
|
|
39
|
+
extractLinks,
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
// Fetch the HTML with proper headers
|
|
44
|
+
const response = await axios.get(url, {
|
|
45
|
+
timeout: 15000,
|
|
46
|
+
headers: {
|
|
47
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
|
|
48
|
+
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
|
|
49
|
+
"Accept-Language": "en-US,en;q=0.5",
|
|
50
|
+
},
|
|
51
|
+
maxRedirects: 5,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const html = response.data;
|
|
55
|
+
const $ = cheerio.load(html);
|
|
56
|
+
|
|
57
|
+
// Remove script and style elements
|
|
58
|
+
$("script, style, nav, footer, iframe, noscript").remove();
|
|
59
|
+
|
|
60
|
+
// Extract title
|
|
61
|
+
const title = $("title").text().trim() || $("h1").first().text().trim() || "Untitled";
|
|
62
|
+
|
|
63
|
+
// Try to find main content area
|
|
64
|
+
let contentArea = $("article, main, [role='main'], .content, #content, .post, .entry").first();
|
|
65
|
+
if (contentArea.length === 0) {
|
|
66
|
+
contentArea = $("body");
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Extract text content
|
|
70
|
+
let content = contentArea.text()
|
|
71
|
+
.replace(/\s+/g, " ")
|
|
72
|
+
.replace(/\n+/g, "\n")
|
|
73
|
+
.trim();
|
|
74
|
+
|
|
75
|
+
// Limit content length
|
|
76
|
+
const maxLength = 8000;
|
|
77
|
+
if (content.length > maxLength) {
|
|
78
|
+
content = content.substring(0, maxLength) + "... [content truncated]";
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Generate excerpt
|
|
82
|
+
const excerpt = content.substring(0, 200) + (content.length > 200 ? "..." : "");
|
|
83
|
+
|
|
84
|
+
// Extract links if requested
|
|
85
|
+
let links: Array<{ text: string; url: string }> | undefined;
|
|
86
|
+
if (extractLinks) {
|
|
87
|
+
links = [];
|
|
88
|
+
contentArea.find("a[href]").each((_, elem) => {
|
|
89
|
+
const linkUrl = $(elem).attr("href");
|
|
90
|
+
const linkText = $(elem).text().trim();
|
|
91
|
+
if (linkUrl && linkText && links && links.length < 20) {
|
|
92
|
+
// Resolve relative URLs
|
|
93
|
+
const absoluteUrl = new URL(linkUrl, url).href;
|
|
94
|
+
links.push({ text: linkText, url: absoluteUrl });
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const result = {
|
|
100
|
+
success: true,
|
|
101
|
+
url,
|
|
102
|
+
title,
|
|
103
|
+
content,
|
|
104
|
+
excerpt,
|
|
105
|
+
links: extractLinks ? links : undefined,
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const duration = Date.now() - startTime;
|
|
109
|
+
logger.info("WEB_TOOL", `Fetched web content successfully`, {
|
|
110
|
+
url,
|
|
111
|
+
title,
|
|
112
|
+
contentLength: content.length,
|
|
113
|
+
linksCount: links?.length || 0,
|
|
114
|
+
duration: `${duration}ms`,
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
return result;
|
|
118
|
+
} catch (error) {
|
|
119
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
120
|
+
const duration = Date.now() - startTime;
|
|
121
|
+
|
|
122
|
+
logger.error("WEB_TOOL", `Failed to fetch web content: ${errorMessage}`, {
|
|
123
|
+
url,
|
|
124
|
+
error: errorMessage,
|
|
125
|
+
duration: `${duration}ms`,
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
return {
|
|
129
|
+
success: false,
|
|
130
|
+
url: inputData.url,
|
|
131
|
+
title: "Error",
|
|
132
|
+
content: "",
|
|
133
|
+
excerpt: "",
|
|
134
|
+
error: errorMessage,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Tool: Search the Web
|
|
142
|
+
* Performs a web search using DuckDuckGo (no API key required)
|
|
143
|
+
*/
|
|
144
|
+
export const searchWebTool = createTool({
|
|
145
|
+
id: "search-web",
|
|
146
|
+
description: `
|
|
147
|
+
Searches the web for information on a given query.
|
|
148
|
+
Use this when you need to find current information, research topics, or discover web pages.
|
|
149
|
+
Returns search results with titles, snippets, and URLs.
|
|
150
|
+
`,
|
|
151
|
+
inputSchema: z.object({
|
|
152
|
+
query: z.string().describe("The search query"),
|
|
153
|
+
numResults: z.number().min(1).max(10).optional().describe("Number of results to return (1-10)"),
|
|
154
|
+
}),
|
|
155
|
+
outputSchema: z.object({
|
|
156
|
+
success: z.boolean(),
|
|
157
|
+
query: z.string(),
|
|
158
|
+
results: z.array(z.object({
|
|
159
|
+
title: z.string(),
|
|
160
|
+
snippet: z.string(),
|
|
161
|
+
url: z.string(),
|
|
162
|
+
})),
|
|
163
|
+
error: z.string().optional(),
|
|
164
|
+
}),
|
|
165
|
+
execute: async (inputData) => {
|
|
166
|
+
const startTime = Date.now();
|
|
167
|
+
const { query, numResults } = inputData;
|
|
168
|
+
const limit = Math.min(Math.max(numResults ?? 5, 1), 10);
|
|
169
|
+
|
|
170
|
+
logger.info("WEB_TOOL", `Searching web: "${query}"`, {
|
|
171
|
+
numResults: limit,
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
try {
|
|
175
|
+
// Use DuckDuckGo HTML search
|
|
176
|
+
const searchUrl = `https://html.duckduckgo.com/html/?q=${encodeURIComponent(query)}`;
|
|
177
|
+
|
|
178
|
+
const response = await axios.get(searchUrl, {
|
|
179
|
+
timeout: 10000,
|
|
180
|
+
headers: {
|
|
181
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
|
|
182
|
+
},
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
const $ = cheerio.load(response.data);
|
|
186
|
+
const results: Array<{ title: string; snippet: string; url: string }> = [];
|
|
187
|
+
|
|
188
|
+
// Parse search results
|
|
189
|
+
$(".result").each((i, elem) => {
|
|
190
|
+
if (results.length >= limit) return;
|
|
191
|
+
|
|
192
|
+
const titleElem = $(elem).find(".result__a").first();
|
|
193
|
+
const snippetElem = $(elem).find(".result__snippet").first();
|
|
194
|
+
const urlElem = $(elem).find(".result__url").first();
|
|
195
|
+
|
|
196
|
+
const title = titleElem.text().trim();
|
|
197
|
+
const snippet = snippetElem.text().trim();
|
|
198
|
+
let url = urlElem.text().trim();
|
|
199
|
+
|
|
200
|
+
// If URL not found in result__url, try to get from title link
|
|
201
|
+
if (!url && titleElem.length) {
|
|
202
|
+
const href = titleElem.attr("href");
|
|
203
|
+
if (href) {
|
|
204
|
+
// DuckDuckGo uses redirects, extract actual URL
|
|
205
|
+
const match = href.match(/uddg=([^&]+)/);
|
|
206
|
+
if (match) {
|
|
207
|
+
url = decodeURIComponent(match[1]);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (title && url) {
|
|
213
|
+
results.push({ title, snippet, url });
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
const duration = Date.now() - startTime;
|
|
218
|
+
logger.info("WEB_TOOL", `Web search completed`, {
|
|
219
|
+
query,
|
|
220
|
+
resultsCount: results.length,
|
|
221
|
+
duration: `${duration}ms`,
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
return {
|
|
225
|
+
success: true,
|
|
226
|
+
query,
|
|
227
|
+
results,
|
|
228
|
+
};
|
|
229
|
+
} catch (error) {
|
|
230
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
231
|
+
const duration = Date.now() - startTime;
|
|
232
|
+
|
|
233
|
+
logger.error("WEB_TOOL", `Web search failed: ${errorMessage}`, {
|
|
234
|
+
query,
|
|
235
|
+
error: errorMessage,
|
|
236
|
+
duration: `${duration}ms`,
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
return {
|
|
240
|
+
success: false,
|
|
241
|
+
query: inputData.query,
|
|
242
|
+
results: [],
|
|
243
|
+
error: errorMessage,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Tool: Extract Structured Data from Web Page
|
|
251
|
+
* Extracts specific data from a web page using CSS selectors
|
|
252
|
+
*/
|
|
253
|
+
export const extractStructuredDataTool = createTool({
|
|
254
|
+
id: "extract-structured-data",
|
|
255
|
+
description: `
|
|
256
|
+
Extracts structured data from a web page using CSS selectors.
|
|
257
|
+
Use this when you need to scrape specific elements like prices, ratings, product info, etc.
|
|
258
|
+
Specify the URL and a map of fields with their CSS selectors.
|
|
259
|
+
`,
|
|
260
|
+
inputSchema: z.object({
|
|
261
|
+
url: z.string().url().describe("The URL of the web page to scrape"),
|
|
262
|
+
fields: z.record(z.object({
|
|
263
|
+
selector: z.string().describe("CSS selector to extract the field"),
|
|
264
|
+
attribute: z.string().optional().describe("Attribute to extract (e.g., 'href', 'src'). Leave empty for text content"),
|
|
265
|
+
multiple: z.boolean().optional().default(false).describe("Whether to extract multiple values"),
|
|
266
|
+
})).describe("Map of field names to extraction rules"),
|
|
267
|
+
}),
|
|
268
|
+
outputSchema: z.object({
|
|
269
|
+
success: z.boolean(),
|
|
270
|
+
url: z.string(),
|
|
271
|
+
data: z.record(z.any()),
|
|
272
|
+
error: z.string().optional(),
|
|
273
|
+
}),
|
|
274
|
+
execute: async (inputData) => {
|
|
275
|
+
const startTime = Date.now();
|
|
276
|
+
const { url, fields } = inputData;
|
|
277
|
+
|
|
278
|
+
logger.info("WEB_TOOL", `Extracting structured data from: ${url}`, {
|
|
279
|
+
fields: Object.keys(fields),
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
try {
|
|
283
|
+
const response = await axios.get(url, {
|
|
284
|
+
timeout: 15000,
|
|
285
|
+
headers: {
|
|
286
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
|
|
287
|
+
},
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
const $ = cheerio.load(response.data);
|
|
291
|
+
const data: Record<string, any> = {};
|
|
292
|
+
|
|
293
|
+
for (const [fieldName, config] of Object.entries(fields)) {
|
|
294
|
+
const { selector, attribute, multiple } = config;
|
|
295
|
+
|
|
296
|
+
if (multiple) {
|
|
297
|
+
// Extract multiple values
|
|
298
|
+
const values: string[] = [];
|
|
299
|
+
$(selector).each((_, elem) => {
|
|
300
|
+
const value = attribute
|
|
301
|
+
? $(elem).attr(attribute)
|
|
302
|
+
: $(elem).text().trim();
|
|
303
|
+
if (value) values.push(value);
|
|
304
|
+
});
|
|
305
|
+
data[fieldName] = values;
|
|
306
|
+
} else {
|
|
307
|
+
// Extract single value
|
|
308
|
+
const elem = $(selector).first();
|
|
309
|
+
const value = attribute
|
|
310
|
+
? elem.attr(attribute)
|
|
311
|
+
: elem.text().trim();
|
|
312
|
+
data[fieldName] = value || null;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
const duration = Date.now() - startTime;
|
|
317
|
+
logger.info("WEB_TOOL", `Structured data extraction completed`, {
|
|
318
|
+
url,
|
|
319
|
+
fieldsCount: Object.keys(data).length,
|
|
320
|
+
duration: `${duration}ms`,
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
return {
|
|
324
|
+
success: true,
|
|
325
|
+
url,
|
|
326
|
+
data,
|
|
327
|
+
};
|
|
328
|
+
} catch (error) {
|
|
329
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
330
|
+
const duration = Date.now() - startTime;
|
|
331
|
+
|
|
332
|
+
logger.error("WEB_TOOL", `Structured data extraction failed: ${errorMessage}`, {
|
|
333
|
+
url,
|
|
334
|
+
error: errorMessage,
|
|
335
|
+
duration: `${duration}ms`,
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
return {
|
|
339
|
+
success: false,
|
|
340
|
+
url: inputData.url,
|
|
341
|
+
data: {},
|
|
342
|
+
error: errorMessage,
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
},
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Tool: Deep Web Research
|
|
350
|
+
* Performs comprehensive research by searching and reading multiple pages
|
|
351
|
+
*/
|
|
352
|
+
export const deepResearchTool = createTool({
|
|
353
|
+
id: "deep-research",
|
|
354
|
+
description: `
|
|
355
|
+
Performs comprehensive web research on a topic.
|
|
356
|
+
This tool searches the web, reads relevant pages, and synthesizes information.
|
|
357
|
+
Use this for thorough research on any topic.
|
|
358
|
+
`,
|
|
359
|
+
inputSchema: z.object({
|
|
360
|
+
topic: z.string().describe("The research topic or question"),
|
|
361
|
+
depth: z.enum(["basic", "standard", "deep"]).optional().default("standard").describe("Research depth"),
|
|
362
|
+
}),
|
|
363
|
+
outputSchema: z.object({
|
|
364
|
+
success: z.boolean(),
|
|
365
|
+
topic: z.string(),
|
|
366
|
+
summary: z.string(),
|
|
367
|
+
sources: z.array(z.object({
|
|
368
|
+
title: z.string(),
|
|
369
|
+
url: z.string(),
|
|
370
|
+
relevance: z.string(),
|
|
371
|
+
})),
|
|
372
|
+
error: z.string().optional(),
|
|
373
|
+
}),
|
|
374
|
+
execute: async (inputData) => {
|
|
375
|
+
const startTime = Date.now();
|
|
376
|
+
const { topic, depth } = inputData;
|
|
377
|
+
const numSources = depth === "basic" ? 3 : depth === "standard" ? 5 : 8;
|
|
378
|
+
|
|
379
|
+
logger.info("WEB_TOOL", `Starting deep research on: "${topic}"`, {
|
|
380
|
+
depth,
|
|
381
|
+
targetSources: numSources,
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
try {
|
|
385
|
+
// Search for the topic
|
|
386
|
+
const searchUrl = `https://html.duckduckgo.com/html/?q=${encodeURIComponent(topic)}`;
|
|
387
|
+
const response = await axios.get(searchUrl, {
|
|
388
|
+
timeout: 10000,
|
|
389
|
+
headers: {
|
|
390
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
|
|
391
|
+
},
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
const $ = cheerio.load(response.data);
|
|
395
|
+
const sources: Array<{ title: string; url: string; relevance: string }> = [];
|
|
396
|
+
|
|
397
|
+
$(".result").each((i, elem) => {
|
|
398
|
+
if (sources.length >= numSources) return;
|
|
399
|
+
|
|
400
|
+
const titleElem = $(elem).find(".result__a").first();
|
|
401
|
+
const snippetElem = $(elem).find(".result__snippet").first();
|
|
402
|
+
|
|
403
|
+
const title = titleElem.text().trim();
|
|
404
|
+
const snippet = snippetElem.text().trim();
|
|
405
|
+
|
|
406
|
+
let url = "";
|
|
407
|
+
const href = titleElem.attr("href");
|
|
408
|
+
if (href) {
|
|
409
|
+
const match = href.match(/uddg=([^&]+)/);
|
|
410
|
+
if (match) {
|
|
411
|
+
url = decodeURIComponent(match[1]);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
if (title && url) {
|
|
416
|
+
sources.push({
|
|
417
|
+
title,
|
|
418
|
+
url,
|
|
419
|
+
relevance: snippet.substring(0, 150),
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
// Create summary
|
|
425
|
+
const summary = `Found ${sources.length} relevant sources for "${topic}". ` +
|
|
426
|
+
`These sources include ${sources.map(s => s.title).slice(0, 3).join(", ")}` +
|
|
427
|
+
(sources.length > 3 ? ` and ${sources.length - 3} others.` : ".");
|
|
428
|
+
|
|
429
|
+
const duration = Date.now() - startTime;
|
|
430
|
+
logger.info("WEB_TOOL", `Deep research completed`, {
|
|
431
|
+
topic,
|
|
432
|
+
sourcesFound: sources.length,
|
|
433
|
+
duration: `${duration}ms`,
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
return {
|
|
437
|
+
success: true,
|
|
438
|
+
topic,
|
|
439
|
+
summary,
|
|
440
|
+
sources,
|
|
441
|
+
};
|
|
442
|
+
} catch (error) {
|
|
443
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
444
|
+
const duration = Date.now() - startTime;
|
|
445
|
+
|
|
446
|
+
logger.error("WEB_TOOL", `Deep research failed: ${errorMessage}`, {
|
|
447
|
+
topic,
|
|
448
|
+
error: errorMessage,
|
|
449
|
+
duration: `${duration}ms`,
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
return {
|
|
453
|
+
success: false,
|
|
454
|
+
topic: inputData.topic,
|
|
455
|
+
summary: "",
|
|
456
|
+
sources: [],
|
|
457
|
+
error: errorMessage,
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
},
|
|
461
|
+
});
|