cf-claw 3.0.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/agent.d.ts +15 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +262 -0
- package/dist/agent.js.map +1 -0
- package/dist/agents.d.ts +51 -0
- package/dist/agents.d.ts.map +1 -0
- package/dist/agents.js +478 -0
- package/dist/agents.js.map +1 -0
- package/dist/api/routes.d.ts +3 -0
- package/dist/api/routes.d.ts.map +1 -0
- package/dist/api/routes.js +491 -0
- package/dist/api/routes.js.map +1 -0
- package/dist/bot.d.ts +4 -0
- package/dist/bot.d.ts.map +1 -0
- package/dist/bot.js +295 -0
- package/dist/bot.js.map +1 -0
- package/dist/canvas.d.ts +37 -0
- package/dist/canvas.d.ts.map +1 -0
- package/dist/canvas.js +47 -0
- package/dist/canvas.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +202 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands.d.ts +6 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +384 -0
- package/dist/commands.js.map +1 -0
- package/dist/components/TaskList.d.ts +7 -0
- package/dist/components/TaskList.d.ts.map +1 -0
- package/dist/components/TaskList.js +37 -0
- package/dist/components/TaskList.js.map +1 -0
- package/dist/config/encryption.d.ts +10 -0
- package/dist/config/encryption.d.ts.map +1 -0
- package/dist/config/encryption.js +111 -0
- package/dist/config/encryption.js.map +1 -0
- package/dist/config/json-config.d.ts +114 -0
- package/dist/config/json-config.d.ts.map +1 -0
- package/dist/config/json-config.js +388 -0
- package/dist/config/json-config.js.map +1 -0
- package/dist/config.d.ts +51 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +137 -0
- package/dist/config.js.map +1 -0
- package/dist/context/pruning.d.ts +30 -0
- package/dist/context/pruning.d.ts.map +1 -0
- package/dist/context/pruning.js +132 -0
- package/dist/context/pruning.js.map +1 -0
- package/dist/dashboard/404/index.html +1 -0
- package/dist/dashboard/404.html +1 -0
- package/dist/dashboard/_next/static/chunks/117-c657912d4a6fa056.js +2 -0
- package/dist/dashboard/_next/static/chunks/191-a6922264096cb3ad.js +11 -0
- package/dist/dashboard/_next/static/chunks/343-71498a8257bc1e81.js +1 -0
- package/dist/dashboard/_next/static/chunks/app/_not-found/page-15cbe4395e02a084.js +1 -0
- package/dist/dashboard/_next/static/chunks/app/layout-191efbc962809bb4.js +1 -0
- package/dist/dashboard/_next/static/chunks/app/manual/page-3c401ecf89979cd7.js +1 -0
- package/dist/dashboard/_next/static/chunks/app/page-dff55e58941a3c4d.js +1 -0
- package/dist/dashboard/_next/static/chunks/fd9d1056-9583fa19bc194043.js +1 -0
- package/dist/dashboard/_next/static/chunks/framework-f66176bb897dc684.js +1 -0
- package/dist/dashboard/_next/static/chunks/main-2461f93106bcf687.js +1 -0
- package/dist/dashboard/_next/static/chunks/main-app-89f5ec28b3bb0e7f.js +1 -0
- package/dist/dashboard/_next/static/chunks/pages/_app-72b849fbd24ac258.js +1 -0
- package/dist/dashboard/_next/static/chunks/pages/_error-7ba65e1336b92748.js +1 -0
- package/dist/dashboard/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
- package/dist/dashboard/_next/static/chunks/webpack-616e068a201ad621.js +1 -0
- package/dist/dashboard/_next/static/css/baff0f221c10680b.css +3 -0
- package/dist/dashboard/_next/static/pyqPyo6dkz4uTWdfdFAOJ/_buildManifest.js +1 -0
- package/dist/dashboard/_next/static/pyqPyo6dkz4uTWdfdFAOJ/_ssgManifest.js +1 -0
- package/dist/dashboard/index.html +1 -0
- package/dist/dashboard/index.txt +7 -0
- package/dist/dashboard/manual/index.html +1 -0
- package/dist/dashboard/manual/index.txt +7 -0
- package/dist/documents.d.ts +20 -0
- package/dist/documents.d.ts.map +1 -0
- package/dist/documents.js +227 -0
- package/dist/documents.js.map +1 -0
- package/dist/embeddings.d.ts +15 -0
- package/dist/embeddings.d.ts.map +1 -0
- package/dist/embeddings.js +40 -0
- package/dist/embeddings.js.map +1 -0
- package/dist/factory.d.ts +72 -0
- package/dist/factory.d.ts.map +1 -0
- package/dist/factory.js +2010 -0
- package/dist/factory.js.map +1 -0
- package/dist/groups.d.ts +13 -0
- package/dist/groups.d.ts.map +1 -0
- package/dist/groups.js +42 -0
- package/dist/groups.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +223 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/taskStorage.d.ts +4 -0
- package/dist/lib/taskStorage.d.ts.map +1 -0
- package/dist/lib/taskStorage.js +28 -0
- package/dist/lib/taskStorage.js.map +1 -0
- package/dist/llm/anthropic.d.ts +13 -0
- package/dist/llm/anthropic.d.ts.map +1 -0
- package/dist/llm/anthropic.js +96 -0
- package/dist/llm/anthropic.js.map +1 -0
- package/dist/llm/failover.d.ts +13 -0
- package/dist/llm/failover.d.ts.map +1 -0
- package/dist/llm/failover.js +42 -0
- package/dist/llm/failover.js.map +1 -0
- package/dist/llm/google.d.ts +13 -0
- package/dist/llm/google.d.ts.map +1 -0
- package/dist/llm/google.js +112 -0
- package/dist/llm/google.js.map +1 -0
- package/dist/llm/groq.d.ts +8 -0
- package/dist/llm/groq.d.ts.map +1 -0
- package/dist/llm/groq.js +13 -0
- package/dist/llm/groq.js.map +1 -0
- package/dist/llm/index.d.ts +11 -0
- package/dist/llm/index.d.ts.map +1 -0
- package/dist/llm/index.js +10 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/llm/ollama.d.ts +9 -0
- package/dist/llm/ollama.d.ts.map +1 -0
- package/dist/llm/ollama.js +27 -0
- package/dist/llm/ollama.js.map +1 -0
- package/dist/llm/openai-compat.d.ts +17 -0
- package/dist/llm/openai-compat.d.ts.map +1 -0
- package/dist/llm/openai-compat.js +69 -0
- package/dist/llm/openai-compat.js.map +1 -0
- package/dist/llm/openrouter.d.ts +8 -0
- package/dist/llm/openrouter.d.ts.map +1 -0
- package/dist/llm/openrouter.js +20 -0
- package/dist/llm/openrouter.js.map +1 -0
- package/dist/llm/provider.d.ts +41 -0
- package/dist/llm/provider.d.ts.map +1 -0
- package/dist/llm/provider.js +2 -0
- package/dist/llm/provider.js.map +1 -0
- package/dist/llm/registry.d.ts +10 -0
- package/dist/llm/registry.d.ts.map +1 -0
- package/dist/llm/registry.js +90 -0
- package/dist/llm/registry.js.map +1 -0
- package/dist/llm/thinking.d.ts +7 -0
- package/dist/llm/thinking.d.ts.map +1 -0
- package/dist/llm/thinking.js +34 -0
- package/dist/llm/thinking.js.map +1 -0
- package/dist/llm.d.ts +17 -0
- package/dist/llm.d.ts.map +1 -0
- package/dist/llm.js +184 -0
- package/dist/llm.js.map +1 -0
- package/dist/logs.d.ts +11 -0
- package/dist/logs.d.ts.map +1 -0
- package/dist/logs.js +54 -0
- package/dist/logs.js.map +1 -0
- package/dist/memory/knowledge-graph.d.ts +34 -0
- package/dist/memory/knowledge-graph.d.ts.map +1 -0
- package/dist/memory/knowledge-graph.js +137 -0
- package/dist/memory/knowledge-graph.js.map +1 -0
- package/dist/memory.d.ts +73 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +320 -0
- package/dist/memory.js.map +1 -0
- package/dist/mesh.d.ts +18 -0
- package/dist/mesh.d.ts.map +1 -0
- package/dist/mesh.js +120 -0
- package/dist/mesh.js.map +1 -0
- package/dist/paths.d.ts +11 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +51 -0
- package/dist/paths.js.map +1 -0
- package/dist/proactive/heartbeat.d.ts +4 -0
- package/dist/proactive/heartbeat.d.ts.map +1 -0
- package/dist/proactive/heartbeat.js +56 -0
- package/dist/proactive/heartbeat.js.map +1 -0
- package/dist/proactive/recap.d.ts +12 -0
- package/dist/proactive/recap.d.ts.map +1 -0
- package/dist/proactive/recap.js +90 -0
- package/dist/proactive/recap.js.map +1 -0
- package/dist/proactive/recommendations.d.ts +11 -0
- package/dist/proactive/recommendations.d.ts.map +1 -0
- package/dist/proactive/recommendations.js +92 -0
- package/dist/proactive/recommendations.js.map +1 -0
- package/dist/projects.d.ts +44 -0
- package/dist/projects.d.ts.map +1 -0
- package/dist/projects.js +101 -0
- package/dist/projects.js.map +1 -0
- package/dist/scheduler/index.d.ts +17 -0
- package/dist/scheduler/index.d.ts.map +1 -0
- package/dist/scheduler/index.js +116 -0
- package/dist/scheduler/index.js.map +1 -0
- package/dist/sessions.d.ts +19 -0
- package/dist/sessions.d.ts.map +1 -0
- package/dist/sessions.js +176 -0
- package/dist/sessions.js.map +1 -0
- package/dist/skills/index.d.ts +14 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +126 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/swarm.d.ts +18 -0
- package/dist/swarm.d.ts.map +1 -0
- package/dist/swarm.js +146 -0
- package/dist/swarm.js.map +1 -0
- package/dist/taskListWidget.d.ts +76 -0
- package/dist/taskListWidget.d.ts.map +1 -0
- package/dist/taskListWidget.js +312 -0
- package/dist/taskListWidget.js.map +1 -0
- package/dist/tools/browser.d.ts +5 -0
- package/dist/tools/browser.d.ts.map +1 -0
- package/dist/tools/browser.js +104 -0
- package/dist/tools/browser.js.map +1 -0
- package/dist/tools/config-tools.d.ts +4 -0
- package/dist/tools/config-tools.d.ts.map +1 -0
- package/dist/tools/config-tools.js +154 -0
- package/dist/tools/config-tools.js.map +1 -0
- package/dist/tools/files.d.ts +3 -0
- package/dist/tools/files.d.ts.map +1 -0
- package/dist/tools/files.js +208 -0
- package/dist/tools/files.js.map +1 -0
- package/dist/tools/index.d.ts +11 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +1109 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/mcp-bridge.d.ts +5 -0
- package/dist/tools/mcp-bridge.d.ts.map +1 -0
- package/dist/tools/mcp-bridge.js +200 -0
- package/dist/tools/mcp-bridge.js.map +1 -0
- package/dist/tools/shell.d.ts +8 -0
- package/dist/tools/shell.d.ts.map +1 -0
- package/dist/tools/shell.js +78 -0
- package/dist/tools/shell.js.map +1 -0
- package/dist/tools/skills-manage.d.ts +25 -0
- package/dist/tools/skills-manage.d.ts.map +1 -0
- package/dist/tools/skills-manage.js +155 -0
- package/dist/tools/skills-manage.js.map +1 -0
- package/dist/tools/web-search.d.ts +4 -0
- package/dist/tools/web-search.d.ts.map +1 -0
- package/dist/tools/web-search.js +60 -0
- package/dist/tools/web-search.js.map +1 -0
- package/dist/tts.d.ts +6 -0
- package/dist/tts.d.ts.map +1 -0
- package/dist/tts.js +42 -0
- package/dist/tts.js.map +1 -0
- package/dist/types/task.d.ts +7 -0
- package/dist/types/task.d.ts.map +1 -0
- package/dist/types/task.js +2 -0
- package/dist/types/task.js.map +1 -0
- package/dist/typing.d.ts +18 -0
- package/dist/typing.d.ts.map +1 -0
- package/dist/typing.js +63 -0
- package/dist/typing.js.map +1 -0
- package/dist/usage.d.ts +28 -0
- package/dist/usage.d.ts.map +1 -0
- package/dist/usage.js +69 -0
- package/dist/usage.js.map +1 -0
- package/dist/voice.d.ts +6 -0
- package/dist/voice.d.ts.map +1 -0
- package/dist/voice.js +47 -0
- package/dist/voice.js.map +1 -0
- package/dist/webchat/index.d.ts +3 -0
- package/dist/webchat/index.d.ts.map +1 -0
- package/dist/webchat/index.js +3 -0
- package/dist/webchat/index.js.map +1 -0
- package/dist/webchat/public/index.html +344 -0
- package/dist/webchat/public/public/index.html +344 -0
- package/dist/webchat/public/public/task-list-widget.js +410 -0
- package/dist/webchat/public/task-list-widget.js +410 -0
- package/dist/webchat/server.d.ts +3 -0
- package/dist/webchat/server.d.ts.map +1 -0
- package/dist/webchat/server.js +80 -0
- package/dist/webchat/server.js.map +1 -0
- package/dist/webchat/ws.d.ts +4 -0
- package/dist/webchat/ws.d.ts.map +1 -0
- package/dist/webchat/ws.js +232 -0
- package/dist/webchat/ws.js.map +1 -0
- package/dist/webhooks/index.d.ts +14 -0
- package/dist/webhooks/index.d.ts.map +1 -0
- package/dist/webhooks/index.js +86 -0
- package/dist/webhooks/index.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,1109 @@
|
|
|
1
|
+
import { addFact, searchFacts, searchConversations, deleteFact, getAllFacts, } from "../memory.js";
|
|
2
|
+
import { textToSpeech } from "../tts.js";
|
|
3
|
+
import { addEntity, addRelation, getEntity, getEntityRelations, searchEntities, traverseGraph, } from "../memory/knowledge-graph.js";
|
|
4
|
+
import { createTask, listTasks, pauseTask, resumeTask, deleteScheduledTask, } from "../scheduler/index.js";
|
|
5
|
+
import { createWebhook, listWebhooks, deleteWebhook, } from "../webhooks/index.js";
|
|
6
|
+
import { sessionsCreate, sessionsList, sessionsHistory, sessionsSend, sessionsDelete, } from "../sessions.js";
|
|
7
|
+
import { canvasManager } from "../canvas.js";
|
|
8
|
+
import { docSave, docList, docRead, docDelete, docSearch, } from "../documents.js";
|
|
9
|
+
import { createAgent, listAgents, getAgent, deleteAgent, } from "../agents.js";
|
|
10
|
+
import { createSkill, patchSkill, editSkill, deleteSkill, viewSkill, } from "./skills-manage.js";
|
|
11
|
+
import { reloadSkills, listLoadedSkills } from "../skills/index.js";
|
|
12
|
+
import shellExec from "./shell.js";
|
|
13
|
+
import { fileTools } from "./files.js";
|
|
14
|
+
import configTools from "./config-tools.js";
|
|
15
|
+
import browser from "./browser.js";
|
|
16
|
+
import webSearch from "./web-search.js";
|
|
17
|
+
import { getMCPTools } from "./mcp-bridge.js";
|
|
18
|
+
import { sendToTelegram } from "../bot.js";
|
|
19
|
+
import { config } from "../config.js";
|
|
20
|
+
import { factoryCreate, listFactoryProjects, getFactoryProject, getFactoryTasks, setProjectStatus, forceRetryTask, restartFactoryProject, getAgentPipelineRoles, } from "../factory.js";
|
|
21
|
+
const getCurrentTime = {
|
|
22
|
+
name: "get_current_time",
|
|
23
|
+
description: "Returns the current date and time. Use this when the user asks what time it is or needs the current date.",
|
|
24
|
+
input_schema: {
|
|
25
|
+
type: "object",
|
|
26
|
+
properties: {},
|
|
27
|
+
required: [],
|
|
28
|
+
},
|
|
29
|
+
execute: async () => {
|
|
30
|
+
const now = new Date();
|
|
31
|
+
return now.toLocaleString("sv-SE", {
|
|
32
|
+
dateStyle: "full",
|
|
33
|
+
timeStyle: "medium",
|
|
34
|
+
timeZone: "Europe/Stockholm",
|
|
35
|
+
});
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
const remember = {
|
|
39
|
+
name: "remember",
|
|
40
|
+
description: "Manually save a specific fact to long-term memory. Most facts are auto-extracted, but use this for things the auto-extraction might miss or when the user explicitly asks you to remember something.",
|
|
41
|
+
input_schema: {
|
|
42
|
+
type: "object",
|
|
43
|
+
properties: {
|
|
44
|
+
content: {
|
|
45
|
+
type: "string",
|
|
46
|
+
description: "The information to remember. Be specific and self-contained.",
|
|
47
|
+
},
|
|
48
|
+
category: {
|
|
49
|
+
type: "string",
|
|
50
|
+
description: 'Category: "preference", "personal", "decision", "project", "technical", "relationship", or "general"',
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
required: ["content"],
|
|
54
|
+
},
|
|
55
|
+
execute: async (input) => {
|
|
56
|
+
const content = input.content;
|
|
57
|
+
const category = input.category || "general";
|
|
58
|
+
const result = await addFact(content, category);
|
|
59
|
+
return result.updated
|
|
60
|
+
? `🔄 Updated existing fact #${result.id}: "${content}"`
|
|
61
|
+
: `✅ Fact saved (id: ${result.id}): "${content}"`;
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
const recall = {
|
|
65
|
+
name: "recall",
|
|
66
|
+
description: "Search long-term memory for relevant facts using hybrid keyword + semantic search. Use this when you need to find specific information about the user or past decisions.",
|
|
67
|
+
input_schema: {
|
|
68
|
+
type: "object",
|
|
69
|
+
properties: {
|
|
70
|
+
query: {
|
|
71
|
+
type: "string",
|
|
72
|
+
description: "Search query — keywords or a natural phrase.",
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
required: ["query"],
|
|
76
|
+
},
|
|
77
|
+
execute: async (input) => {
|
|
78
|
+
const query = input.query;
|
|
79
|
+
const facts = query.trim()
|
|
80
|
+
? await searchFacts(query)
|
|
81
|
+
: getAllFacts();
|
|
82
|
+
if (facts.length === 0) {
|
|
83
|
+
return "No facts found matching that query.";
|
|
84
|
+
}
|
|
85
|
+
const formatted = facts
|
|
86
|
+
.map((f) => `[id:${f.id}] [${f.category}] ${f.content}`)
|
|
87
|
+
.join("\n");
|
|
88
|
+
return `Found ${facts.length} fact${facts.length === 1 ? "" : "s"}:\n${formatted}`;
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
const forget = {
|
|
92
|
+
name: "forget",
|
|
93
|
+
description: "Delete a specific fact by its ID. Use this when information is outdated, incorrect, or the user asks you to forget something. Use recall first to find the fact ID.",
|
|
94
|
+
input_schema: {
|
|
95
|
+
type: "object",
|
|
96
|
+
properties: {
|
|
97
|
+
id: {
|
|
98
|
+
type: "number",
|
|
99
|
+
description: "The ID of the fact to delete.",
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
required: ["id"],
|
|
103
|
+
},
|
|
104
|
+
execute: async (input) => {
|
|
105
|
+
const id = input.id;
|
|
106
|
+
const deleted = deleteFact(id);
|
|
107
|
+
return deleted
|
|
108
|
+
? `✅ Fact ${id} has been deleted.`
|
|
109
|
+
: `⚠️ No fact found with id ${id}.`;
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
const searchConversationsTool = {
|
|
113
|
+
name: "search_conversations",
|
|
114
|
+
description: "Deep search through the full conversation history using hybrid keyword + semantic search. Use this to find specific past discussions, things the user said, or context from older conversations.",
|
|
115
|
+
input_schema: {
|
|
116
|
+
type: "object",
|
|
117
|
+
properties: {
|
|
118
|
+
query: {
|
|
119
|
+
type: "string",
|
|
120
|
+
description: "Search query — what to look for in past conversations.",
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
required: ["query"],
|
|
124
|
+
},
|
|
125
|
+
execute: async (input) => {
|
|
126
|
+
const query = input.query;
|
|
127
|
+
const results = await searchConversations(query, 10);
|
|
128
|
+
if (results.length === 0) {
|
|
129
|
+
return "No matching conversations found.";
|
|
130
|
+
}
|
|
131
|
+
const formatted = results
|
|
132
|
+
.map((r) => `[${r.role}] ${r.content}`)
|
|
133
|
+
.join("\n---\n");
|
|
134
|
+
return `Found ${results.length} relevant message${results.length === 1 ? "" : "s"}:\n${formatted}`;
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
const speak = {
|
|
138
|
+
name: "speak",
|
|
139
|
+
description: "Send a voice message back to the user using text-to-speech. Use this when the user asks you to speak, reply with voice, send an audio message, or when replying to a voice message and a spoken reply feels natural.",
|
|
140
|
+
input_schema: {
|
|
141
|
+
type: "object",
|
|
142
|
+
properties: {
|
|
143
|
+
text: {
|
|
144
|
+
type: "string",
|
|
145
|
+
description: "The text to speak aloud. Write it as natural speech — no markdown, no bullet points.",
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
required: ["text"],
|
|
149
|
+
},
|
|
150
|
+
execute: async (input) => {
|
|
151
|
+
const text = input.text;
|
|
152
|
+
console.log(`🔊 Speaking: ${text.substring(0, 60)}${text.length > 60 ? "…" : ""}`);
|
|
153
|
+
const audioPath = await textToSpeech(text);
|
|
154
|
+
return `[VOICE:${audioPath}]`;
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
const knowledgeAdd = {
|
|
158
|
+
name: "knowledge_add",
|
|
159
|
+
description: "Add entities and relationships to the knowledge graph. Use to track people, projects, concepts and how they relate.",
|
|
160
|
+
input_schema: {
|
|
161
|
+
type: "object",
|
|
162
|
+
properties: {
|
|
163
|
+
entity_name: { type: "string", description: "Name of the entity." },
|
|
164
|
+
entity_type: { type: "string", description: 'Type (e.g. "person", "project", "concept"). Default: "thing".' },
|
|
165
|
+
relation_to: { type: "string", description: "Name of a related entity." },
|
|
166
|
+
relation_type: { type: "string", description: 'Type of relation (e.g. "works_on", "knows", "part_of").' },
|
|
167
|
+
},
|
|
168
|
+
required: ["entity_name"],
|
|
169
|
+
},
|
|
170
|
+
execute: async (input) => {
|
|
171
|
+
const name = input.entity_name;
|
|
172
|
+
const type = input.entity_type || "thing";
|
|
173
|
+
const results = [];
|
|
174
|
+
const entity = await addEntity(name, type);
|
|
175
|
+
results.push(`✅ Entity "${name}" (${type}) — id: ${entity.id}`);
|
|
176
|
+
if (input.relation_to && input.relation_type) {
|
|
177
|
+
const relResult = await addRelation(name, input.relation_to, input.relation_type);
|
|
178
|
+
if (relResult) {
|
|
179
|
+
results.push(`✅ Relation: ${name} —[${input.relation_type}]→ ${input.relation_to}`);
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
results.push(`⚠️ Could not create relation — "${input.relation_to}" not found. Add it first.`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return results.join("\n");
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
const knowledgeQuery = {
|
|
189
|
+
name: "knowledge_query",
|
|
190
|
+
description: "Search and traverse the knowledge graph. Find entities, their relationships, and connections.",
|
|
191
|
+
input_schema: {
|
|
192
|
+
type: "object",
|
|
193
|
+
properties: {
|
|
194
|
+
query: { type: "string", description: "Entity name or search term." },
|
|
195
|
+
action: {
|
|
196
|
+
type: "string",
|
|
197
|
+
description: '"get" (lookup by name), "search" (fuzzy search), "relations" (get relations), "traverse" (graph traversal). Default: "get"',
|
|
198
|
+
},
|
|
199
|
+
depth: { type: "number", description: "Max traversal depth (for traverse action). Default: 3." },
|
|
200
|
+
},
|
|
201
|
+
required: ["query"],
|
|
202
|
+
},
|
|
203
|
+
execute: async (input) => {
|
|
204
|
+
const query = input.query;
|
|
205
|
+
const action = input.action || "get";
|
|
206
|
+
switch (action) {
|
|
207
|
+
case "search": {
|
|
208
|
+
const entities = searchEntities(query, 10);
|
|
209
|
+
if (entities.length === 0)
|
|
210
|
+
return "No entities found.";
|
|
211
|
+
return entities.map((e) => `- ${e.name} (${e.type})`).join("\n");
|
|
212
|
+
}
|
|
213
|
+
case "relations": {
|
|
214
|
+
const relations = getEntityRelations(query);
|
|
215
|
+
if (relations.outgoing.length === 0 && relations.incoming.length === 0) {
|
|
216
|
+
return `No relations found for "${query}".`;
|
|
217
|
+
}
|
|
218
|
+
const lines = [];
|
|
219
|
+
for (const r of relations.outgoing) {
|
|
220
|
+
lines.push(`${query} —[${r.relation_type}]→ ${r.target_name}`);
|
|
221
|
+
}
|
|
222
|
+
for (const r of relations.incoming) {
|
|
223
|
+
lines.push(`${r.source_name} —[${r.relation_type}]→ ${query}`);
|
|
224
|
+
}
|
|
225
|
+
return lines.join("\n");
|
|
226
|
+
}
|
|
227
|
+
case "traverse": {
|
|
228
|
+
const depth = input.depth || 3;
|
|
229
|
+
const graph = traverseGraph(query, depth);
|
|
230
|
+
if (graph.entities.length === 0)
|
|
231
|
+
return `Entity "${query}" not found.`;
|
|
232
|
+
const entityLines = graph.entities.map((e) => `- ${e.name} (${e.type})`);
|
|
233
|
+
const relLines = graph.relations.map((r) => ` ${r.from} —[${r.type}]→ ${r.to}`);
|
|
234
|
+
return `Entities:\n${entityLines.join("\n")}\nRelations:\n${relLines.join("\n")}`;
|
|
235
|
+
}
|
|
236
|
+
default: {
|
|
237
|
+
const entity = getEntity(query);
|
|
238
|
+
if (!entity)
|
|
239
|
+
return `Entity "${query}" not found. Use action "search" to look for similar entities.`;
|
|
240
|
+
return `Name: ${entity.name}\nType: ${entity.type}\nProperties: ${JSON.stringify(entity.properties)}`;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
};
|
|
245
|
+
const scheduleTask = {
|
|
246
|
+
name: "schedule_task",
|
|
247
|
+
description: "Create a scheduled task. Supports cron expressions (e.g. '30 9 * * *' for 9:30 daily) or natural intervals (e.g. 'every 30 min').",
|
|
248
|
+
input_schema: {
|
|
249
|
+
type: "object",
|
|
250
|
+
properties: {
|
|
251
|
+
name: { type: "string", description: "Name for this task." },
|
|
252
|
+
cron: { type: "string", description: "Cron expression or interval (e.g. '30 9 * * *' or 'every 60 min')." },
|
|
253
|
+
prompt: { type: "string", description: "Prompt to execute when the task fires." },
|
|
254
|
+
},
|
|
255
|
+
required: ["name", "cron", "prompt"],
|
|
256
|
+
},
|
|
257
|
+
execute: async (input) => {
|
|
258
|
+
const task = createTask(input.name, input.cron, input.prompt);
|
|
259
|
+
return `✅ Scheduled task "${task.name}" (id: ${task.id})\nCron: ${task.cron_expr}\nNext run: ${task.next_run}`;
|
|
260
|
+
},
|
|
261
|
+
};
|
|
262
|
+
const scheduleList = {
|
|
263
|
+
name: "schedule_list",
|
|
264
|
+
description: "List all scheduled tasks.",
|
|
265
|
+
input_schema: {
|
|
266
|
+
type: "object",
|
|
267
|
+
properties: {},
|
|
268
|
+
required: [],
|
|
269
|
+
},
|
|
270
|
+
execute: async () => {
|
|
271
|
+
const tasks = listTasks();
|
|
272
|
+
if (tasks.length === 0)
|
|
273
|
+
return "No scheduled tasks.";
|
|
274
|
+
return tasks.map((t) => `[${t.enabled ? "✅" : "⏸"}] #${t.id} "${t.name}" — ${t.cron_expr} (last: ${t.last_run || "never"})`).join("\n");
|
|
275
|
+
},
|
|
276
|
+
};
|
|
277
|
+
const scheduleToggle = {
|
|
278
|
+
name: "schedule_toggle",
|
|
279
|
+
description: "Pause or resume a scheduled task.",
|
|
280
|
+
input_schema: {
|
|
281
|
+
type: "object",
|
|
282
|
+
properties: {
|
|
283
|
+
id: { type: "number", description: "Task ID." },
|
|
284
|
+
action: { type: "string", description: '"pause" or "resume".' },
|
|
285
|
+
},
|
|
286
|
+
required: ["id", "action"],
|
|
287
|
+
},
|
|
288
|
+
execute: async (input) => {
|
|
289
|
+
const id = input.id;
|
|
290
|
+
const action = input.action;
|
|
291
|
+
if (action === "pause") {
|
|
292
|
+
pauseTask(id);
|
|
293
|
+
return `⏸ Task ${id} paused.`;
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
resumeTask(id);
|
|
297
|
+
return `▶️ Task ${id} resumed.`;
|
|
298
|
+
}
|
|
299
|
+
},
|
|
300
|
+
};
|
|
301
|
+
const scheduleDelete = {
|
|
302
|
+
name: "schedule_delete",
|
|
303
|
+
description: "Delete a scheduled task.",
|
|
304
|
+
input_schema: {
|
|
305
|
+
type: "object",
|
|
306
|
+
properties: {
|
|
307
|
+
id: { type: "number", description: "Task ID to delete." },
|
|
308
|
+
},
|
|
309
|
+
required: ["id"],
|
|
310
|
+
},
|
|
311
|
+
execute: async (input) => {
|
|
312
|
+
deleteScheduledTask(input.id);
|
|
313
|
+
return `🗑 Task ${input.id} deleted.`;
|
|
314
|
+
},
|
|
315
|
+
};
|
|
316
|
+
const webhookCreate = {
|
|
317
|
+
name: "webhook_create",
|
|
318
|
+
description: "Create a webhook endpoint. Incoming POST requests will trigger the agent with the configured prompt.",
|
|
319
|
+
input_schema: {
|
|
320
|
+
type: "object",
|
|
321
|
+
properties: {
|
|
322
|
+
name: { type: "string", description: "Webhook name." },
|
|
323
|
+
path: { type: "string", description: "URL path (e.g. 'github-push'). Will be accessible at /webhook/{path}." },
|
|
324
|
+
prompt: { type: "string", description: "Prompt template. Use {{payload}} for the request body." },
|
|
325
|
+
secret: { type: "string", description: "Optional secret for verification (sent as x-webhook-secret header)." },
|
|
326
|
+
},
|
|
327
|
+
required: ["name", "path", "prompt"],
|
|
328
|
+
},
|
|
329
|
+
execute: async (input) => {
|
|
330
|
+
const wh = createWebhook(input.name, input.path, input.prompt, input.secret);
|
|
331
|
+
return `✅ Webhook "${wh.name}" created.\nEndpoint: POST /webhook/${wh.path}\nID: ${wh.id}`;
|
|
332
|
+
},
|
|
333
|
+
};
|
|
334
|
+
const webhookList = {
|
|
335
|
+
name: "webhook_list",
|
|
336
|
+
description: "List all registered webhooks.",
|
|
337
|
+
input_schema: {
|
|
338
|
+
type: "object",
|
|
339
|
+
properties: {},
|
|
340
|
+
required: [],
|
|
341
|
+
},
|
|
342
|
+
execute: async () => {
|
|
343
|
+
const webhooks = listWebhooks();
|
|
344
|
+
if (webhooks.length === 0)
|
|
345
|
+
return "No webhooks registered.";
|
|
346
|
+
return webhooks.map((w) => `- "${w.name}" → POST /webhook/${w.path} (id: ${w.id})`).join("\n");
|
|
347
|
+
},
|
|
348
|
+
};
|
|
349
|
+
const webhookDelete = {
|
|
350
|
+
name: "webhook_delete",
|
|
351
|
+
description: "Delete a webhook endpoint.",
|
|
352
|
+
input_schema: {
|
|
353
|
+
type: "object",
|
|
354
|
+
properties: {
|
|
355
|
+
id: { type: "string", description: "Webhook ID to delete." },
|
|
356
|
+
},
|
|
357
|
+
required: ["id"],
|
|
358
|
+
},
|
|
359
|
+
execute: async (input) => {
|
|
360
|
+
deleteWebhook(input.id);
|
|
361
|
+
return `🗑 Webhook ${input.id} deleted.`;
|
|
362
|
+
},
|
|
363
|
+
};
|
|
364
|
+
const sessionCreate = {
|
|
365
|
+
name: "sessions_create",
|
|
366
|
+
description: "Create a new isolated agent session. Sessions have their own conversation history and optional system prompt. Use this to spawn sub-agents for parallel tasks.",
|
|
367
|
+
input_schema: {
|
|
368
|
+
type: "object",
|
|
369
|
+
properties: {
|
|
370
|
+
name: { type: "string", description: "Name for this session." },
|
|
371
|
+
system_prompt: { type: "string", description: "Optional system prompt to give the session agent a specific role or instructions." },
|
|
372
|
+
},
|
|
373
|
+
required: ["name"],
|
|
374
|
+
},
|
|
375
|
+
execute: async (input) => {
|
|
376
|
+
const session = sessionsCreate(input.name, input.system_prompt);
|
|
377
|
+
return `✅ Session "${session.name}" created (id: ${session.id})`;
|
|
378
|
+
},
|
|
379
|
+
};
|
|
380
|
+
const sessionList = {
|
|
381
|
+
name: "sessions_list",
|
|
382
|
+
description: "List all agent sessions.",
|
|
383
|
+
input_schema: {
|
|
384
|
+
type: "object",
|
|
385
|
+
properties: {},
|
|
386
|
+
required: [],
|
|
387
|
+
},
|
|
388
|
+
execute: async () => {
|
|
389
|
+
const sessions = sessionsList();
|
|
390
|
+
if (sessions.length === 0)
|
|
391
|
+
return "No active sessions.";
|
|
392
|
+
return sessions.map((s) => `- "${s.name}" (id: ${s.id}, last: ${s.lastActive})`).join("\n");
|
|
393
|
+
},
|
|
394
|
+
};
|
|
395
|
+
const sessionHistory = {
|
|
396
|
+
name: "sessions_history",
|
|
397
|
+
description: "Get the conversation history of a specific agent session.",
|
|
398
|
+
input_schema: {
|
|
399
|
+
type: "object",
|
|
400
|
+
properties: {
|
|
401
|
+
session_id: { type: "string", description: "The session ID." },
|
|
402
|
+
limit: { type: "number", description: "Max messages to return. Default: 20." },
|
|
403
|
+
},
|
|
404
|
+
required: ["session_id"],
|
|
405
|
+
},
|
|
406
|
+
execute: async (input) => {
|
|
407
|
+
const msgs = sessionsHistory(input.session_id, input.limit || 20);
|
|
408
|
+
if (msgs.length === 0)
|
|
409
|
+
return "No messages in this session.";
|
|
410
|
+
return msgs.map((m) => `[${m.role}] ${m.content}`).join("\n---\n");
|
|
411
|
+
},
|
|
412
|
+
};
|
|
413
|
+
const sessionSend = {
|
|
414
|
+
name: "sessions_send",
|
|
415
|
+
description: "Send a message to an agent session and get its response. The session runs its own agent loop with tools.",
|
|
416
|
+
input_schema: {
|
|
417
|
+
type: "object",
|
|
418
|
+
properties: {
|
|
419
|
+
session_id: { type: "string", description: "The session ID to send the message to." },
|
|
420
|
+
message: { type: "string", description: "The message to send." },
|
|
421
|
+
},
|
|
422
|
+
required: ["session_id", "message"],
|
|
423
|
+
},
|
|
424
|
+
execute: async (input) => {
|
|
425
|
+
const reply = await sessionsSend(input.session_id, input.message);
|
|
426
|
+
return reply;
|
|
427
|
+
},
|
|
428
|
+
};
|
|
429
|
+
const sessionDelete = {
|
|
430
|
+
name: "sessions_delete",
|
|
431
|
+
description: "Delete an agent session and its history.",
|
|
432
|
+
input_schema: {
|
|
433
|
+
type: "object",
|
|
434
|
+
properties: {
|
|
435
|
+
session_id: { type: "string", description: "The session ID to delete." },
|
|
436
|
+
},
|
|
437
|
+
required: ["session_id"],
|
|
438
|
+
},
|
|
439
|
+
execute: async (input) => {
|
|
440
|
+
const deleted = sessionsDelete(input.session_id);
|
|
441
|
+
return deleted ? `🗑 Session deleted.` : `⚠️ Session not found.`;
|
|
442
|
+
},
|
|
443
|
+
};
|
|
444
|
+
const canvasRender = {
|
|
445
|
+
name: "canvas_render",
|
|
446
|
+
description: "Push an interactive HTML/JS widget to the Live Canvas (WebChat UI). Use for tables, charts, forms, or custom HTML.",
|
|
447
|
+
input_schema: {
|
|
448
|
+
type: "object",
|
|
449
|
+
properties: {
|
|
450
|
+
widget_type: { type: "string", description: 'Type: "html", "table", "chart", or "form".', enum: ["html", "table", "chart", "form"] },
|
|
451
|
+
html: { type: "string", description: "HTML content (for html type)." },
|
|
452
|
+
js: { type: "string", description: "Optional JavaScript to execute after render." },
|
|
453
|
+
headers: { type: "array", items: { type: "string" }, description: "Column headers (for table type)." },
|
|
454
|
+
rows: { type: "array", items: { type: "array", items: { type: "string" } }, description: "Row data (for table type)." },
|
|
455
|
+
},
|
|
456
|
+
required: ["widget_type"],
|
|
457
|
+
},
|
|
458
|
+
execute: async (input) => {
|
|
459
|
+
const widgetType = input.widget_type;
|
|
460
|
+
const sockets = canvasManager.getSocketCount();
|
|
461
|
+
if (sockets === 0) {
|
|
462
|
+
return "⚠️ No active canvas connections. Open the WebChat UI to see canvas widgets.";
|
|
463
|
+
}
|
|
464
|
+
switch (widgetType) {
|
|
465
|
+
case "html":
|
|
466
|
+
canvasManager.pushHtml(input.html, input.js);
|
|
467
|
+
break;
|
|
468
|
+
case "table":
|
|
469
|
+
canvasManager.pushTable(input.headers, input.rows);
|
|
470
|
+
break;
|
|
471
|
+
case "chart":
|
|
472
|
+
canvasManager.pushChart(input);
|
|
473
|
+
break;
|
|
474
|
+
default:
|
|
475
|
+
canvasManager.pushHtml(input.html || `<p>Widget: ${widgetType}</p>`);
|
|
476
|
+
}
|
|
477
|
+
return `✅ Canvas widget (${widgetType}) pushed to ${sockets} client(s).`;
|
|
478
|
+
},
|
|
479
|
+
};
|
|
480
|
+
const docSaveTool = {
|
|
481
|
+
name: "doc_save",
|
|
482
|
+
description: "Save a document to the document store. Supports markdown and HTML. Documents are searchable by content and metadata.",
|
|
483
|
+
input_schema: {
|
|
484
|
+
type: "object",
|
|
485
|
+
properties: {
|
|
486
|
+
title: { type: "string", description: "Document title." },
|
|
487
|
+
content: { type: "string", description: "Document content (markdown or HTML)." },
|
|
488
|
+
category: { type: "string", description: 'Category/folder. Default: "general".' },
|
|
489
|
+
tags: { type: "array", items: { type: "string" }, description: "Tags for search." },
|
|
490
|
+
file_ext: { type: "string", description: 'File extension. Default: ".md". Options: ".md", ".html".' },
|
|
491
|
+
},
|
|
492
|
+
required: ["title", "content"],
|
|
493
|
+
},
|
|
494
|
+
execute: async (input) => {
|
|
495
|
+
const doc = await docSave(input.title, input.content, input.category || "general", input.tags || [], input.file_ext || ".md");
|
|
496
|
+
return `✅ Document saved: "${doc.title}" (id: ${doc.id}, ${doc.fileExt})`;
|
|
497
|
+
},
|
|
498
|
+
};
|
|
499
|
+
const docListTool = {
|
|
500
|
+
name: "doc_list",
|
|
501
|
+
description: "List documents in the document store, optionally filtered by category.",
|
|
502
|
+
input_schema: {
|
|
503
|
+
type: "object",
|
|
504
|
+
properties: {
|
|
505
|
+
category: { type: "string", description: "Optional category filter." },
|
|
506
|
+
},
|
|
507
|
+
required: [],
|
|
508
|
+
},
|
|
509
|
+
execute: async (input) => {
|
|
510
|
+
const docs = docList(input.category);
|
|
511
|
+
if (docs.length === 0)
|
|
512
|
+
return "No documents found.";
|
|
513
|
+
return docs.map((d) => `[${d.id}] "${d.title}" (${d.category}) ${d.fileExt} — ${d.updatedAt}`).join("\n");
|
|
514
|
+
},
|
|
515
|
+
};
|
|
516
|
+
const docReadTool = {
|
|
517
|
+
name: "doc_read",
|
|
518
|
+
description: "Read a document's content by its ID.",
|
|
519
|
+
input_schema: {
|
|
520
|
+
type: "object",
|
|
521
|
+
properties: {
|
|
522
|
+
id: { type: "number", description: "Document ID." },
|
|
523
|
+
},
|
|
524
|
+
required: ["id"],
|
|
525
|
+
},
|
|
526
|
+
execute: async (input) => {
|
|
527
|
+
const content = docRead(input.id);
|
|
528
|
+
if (!content)
|
|
529
|
+
return `⚠️ Document ${input.id} not found.`;
|
|
530
|
+
return content;
|
|
531
|
+
},
|
|
532
|
+
};
|
|
533
|
+
const docDeleteTool = {
|
|
534
|
+
name: "doc_delete",
|
|
535
|
+
description: "Delete a document by its ID.",
|
|
536
|
+
input_schema: {
|
|
537
|
+
type: "object",
|
|
538
|
+
properties: {
|
|
539
|
+
id: { type: "number", description: "Document ID to delete." },
|
|
540
|
+
},
|
|
541
|
+
required: ["id"],
|
|
542
|
+
},
|
|
543
|
+
execute: async (input) => {
|
|
544
|
+
const deleted = docDelete(input.id);
|
|
545
|
+
return deleted ? `🗑 Document ${input.id} deleted.` : `⚠️ Document ${input.id} not found.`;
|
|
546
|
+
},
|
|
547
|
+
};
|
|
548
|
+
const docSearchTool = {
|
|
549
|
+
name: "doc_search",
|
|
550
|
+
description: "Search documents by semantic similarity and keyword matching.",
|
|
551
|
+
input_schema: {
|
|
552
|
+
type: "object",
|
|
553
|
+
properties: {
|
|
554
|
+
query: { type: "string", description: "Search query." },
|
|
555
|
+
limit: { type: "number", description: "Max results. Default: 10." },
|
|
556
|
+
},
|
|
557
|
+
required: ["query"],
|
|
558
|
+
},
|
|
559
|
+
execute: async (input) => {
|
|
560
|
+
const results = await docSearch(input.query, input.limit || 10);
|
|
561
|
+
if (results.length === 0)
|
|
562
|
+
return "No documents found matching that query.";
|
|
563
|
+
return results.map((d) => `[${d.id}] "${d.title}" (${d.category}) — ${d.summary}`).join("\n");
|
|
564
|
+
},
|
|
565
|
+
};
|
|
566
|
+
const agentCreateTool = {
|
|
567
|
+
name: "agent_create",
|
|
568
|
+
description: "Create a new custom agent with a specific role, system prompt, and optional tool restrictions.",
|
|
569
|
+
input_schema: {
|
|
570
|
+
type: "object",
|
|
571
|
+
properties: {
|
|
572
|
+
name: { type: "string", description: "Agent name (lowercase)." },
|
|
573
|
+
role: { type: "string", description: "Short role description." },
|
|
574
|
+
system_prompt: { type: "string", description: "Full system prompt for the agent." },
|
|
575
|
+
description: { type: "string", description: "Longer description of what the agent does." },
|
|
576
|
+
tools: { type: "array", items: { type: "string" }, description: "Tools this agent can use." },
|
|
577
|
+
rules: { type: "array", items: { type: "string" }, description: "Special rules for the agent." },
|
|
578
|
+
tags: { type: "array", items: { type: "string" }, description: "Tags." },
|
|
579
|
+
team: { type: "string", description: 'Team name. Default: "custom".' },
|
|
580
|
+
model: { type: "string", description: "Primary AI model for this agent (e.g. glm-5.1, gpt-4o-mini)." },
|
|
581
|
+
fallback_model: { type: "string", description: "Fallback model if primary fails (optional)." },
|
|
582
|
+
},
|
|
583
|
+
required: ["name", "role", "system_prompt"],
|
|
584
|
+
},
|
|
585
|
+
execute: async (input) => {
|
|
586
|
+
const agent = await createAgent(input.name, input.role, input.system_prompt, {
|
|
587
|
+
description: input.description,
|
|
588
|
+
tools: input.tools,
|
|
589
|
+
rules: input.rules,
|
|
590
|
+
tags: input.tags,
|
|
591
|
+
team: input.team,
|
|
592
|
+
model: input.model,
|
|
593
|
+
fallbackModel: input.fallback_model,
|
|
594
|
+
});
|
|
595
|
+
return `✅ Agent "${agent.name}" (${agent.role}) created in team "${agent.team}".`;
|
|
596
|
+
},
|
|
597
|
+
};
|
|
598
|
+
const agentListTool = {
|
|
599
|
+
name: "agent_list",
|
|
600
|
+
description: "List all registered agents, optionally filtered by team.",
|
|
601
|
+
input_schema: {
|
|
602
|
+
type: "object",
|
|
603
|
+
properties: {
|
|
604
|
+
team: { type: "string", description: "Optional team filter." },
|
|
605
|
+
},
|
|
606
|
+
required: [],
|
|
607
|
+
},
|
|
608
|
+
execute: async (input) => {
|
|
609
|
+
const agents = listAgents(input.team);
|
|
610
|
+
if (agents.length === 0)
|
|
611
|
+
return "No agents found.";
|
|
612
|
+
return agents.map((a) => `[${a.team}] ${a.name} — ${a.role} ${a.builtIn ? "(built-in)" : "(custom)"}`).join("\n");
|
|
613
|
+
},
|
|
614
|
+
};
|
|
615
|
+
const agentShowTool = {
|
|
616
|
+
name: "agent_show",
|
|
617
|
+
description: "Show details of a specific agent by name.",
|
|
618
|
+
input_schema: {
|
|
619
|
+
type: "object",
|
|
620
|
+
properties: {
|
|
621
|
+
name: { type: "string", description: "Agent name." },
|
|
622
|
+
},
|
|
623
|
+
required: ["name"],
|
|
624
|
+
},
|
|
625
|
+
execute: async (input) => {
|
|
626
|
+
const agent = getAgent(input.name);
|
|
627
|
+
if (!agent)
|
|
628
|
+
return `⚠️ Agent "${input.name}" not found.`;
|
|
629
|
+
const lines = [
|
|
630
|
+
`**${agent.name}** (${agent.role})`,
|
|
631
|
+
`Team: ${agent.team}`,
|
|
632
|
+
`Description: ${agent.description}`,
|
|
633
|
+
`Tools: ${agent.tools.length > 0 ? agent.tools.join(", ") : "all"}`,
|
|
634
|
+
`Rules: ${agent.rules.length > 0 ? agent.rules.join("; ") : "none"}`,
|
|
635
|
+
`Tags: ${agent.tags.join(", ") || "none"}`,
|
|
636
|
+
`Built-in: ${agent.builtIn}`,
|
|
637
|
+
];
|
|
638
|
+
return lines.join("\n");
|
|
639
|
+
},
|
|
640
|
+
};
|
|
641
|
+
const agentDeleteTool = {
|
|
642
|
+
name: "agent_delete",
|
|
643
|
+
description: "Delete a custom agent by name. Built-in agents cannot be deleted.",
|
|
644
|
+
input_schema: {
|
|
645
|
+
type: "object",
|
|
646
|
+
properties: {
|
|
647
|
+
name: { type: "string", description: "Agent name to delete." },
|
|
648
|
+
},
|
|
649
|
+
required: ["name"],
|
|
650
|
+
},
|
|
651
|
+
execute: async (input) => {
|
|
652
|
+
const agent = getAgent(input.name);
|
|
653
|
+
if (!agent)
|
|
654
|
+
return `⚠️ Agent "${input.name}" not found.`;
|
|
655
|
+
if (agent.builtIn)
|
|
656
|
+
return `⚠️ Cannot delete built-in agent "${input.name}".`;
|
|
657
|
+
const deleted = deleteAgent(input.name);
|
|
658
|
+
return deleted ? `🗑 Agent "${input.name}" deleted.` : `⚠️ Failed to delete agent.`;
|
|
659
|
+
},
|
|
660
|
+
};
|
|
661
|
+
const skillCreate = {
|
|
662
|
+
name: "skill_create",
|
|
663
|
+
description: "Create a new reusable skill from experience. Skills capture procedures, workflows, and solutions for future reuse. Create a skill after completing a complex task (5+ tool calls), fixing a tricky error, or discovering a non-trivial workflow.",
|
|
664
|
+
input_schema: {
|
|
665
|
+
type: "object",
|
|
666
|
+
properties: {
|
|
667
|
+
name: {
|
|
668
|
+
type: "string",
|
|
669
|
+
description: "Short skill name (lowercase, hyphens). E.g. 'debug-node-errors'",
|
|
670
|
+
},
|
|
671
|
+
description: {
|
|
672
|
+
type: "string",
|
|
673
|
+
description: "Brief description of what this skill does (max 1024 chars).",
|
|
674
|
+
},
|
|
675
|
+
content: {
|
|
676
|
+
type: "string",
|
|
677
|
+
description: "Full skill instructions in markdown. Include steps, pitfalls, and verification.",
|
|
678
|
+
},
|
|
679
|
+
},
|
|
680
|
+
required: ["name", "description", "content"],
|
|
681
|
+
},
|
|
682
|
+
execute: async (input) => {
|
|
683
|
+
const result = createSkill(input.name, input.description, input.content);
|
|
684
|
+
if (result.success)
|
|
685
|
+
reloadSkills();
|
|
686
|
+
return result.success ? `✅ ${result.message}` : `⚠️ ${result.message}`;
|
|
687
|
+
},
|
|
688
|
+
};
|
|
689
|
+
const skillPatch = {
|
|
690
|
+
name: "skill_patch",
|
|
691
|
+
description: "Make a targeted find-and-replace edit to an existing skill. Preferred for small fixes, adding steps, or correcting outdated information. Preserves the rest of the skill.",
|
|
692
|
+
input_schema: {
|
|
693
|
+
type: "object",
|
|
694
|
+
properties: {
|
|
695
|
+
name: {
|
|
696
|
+
type: "string",
|
|
697
|
+
description: "Skill name to patch.",
|
|
698
|
+
},
|
|
699
|
+
old: {
|
|
700
|
+
type: "string",
|
|
701
|
+
description: "Exact text to find and replace.",
|
|
702
|
+
},
|
|
703
|
+
new: {
|
|
704
|
+
type: "string",
|
|
705
|
+
description: "Replacement text.",
|
|
706
|
+
},
|
|
707
|
+
file: {
|
|
708
|
+
type: "string",
|
|
709
|
+
description: "Optional supporting file path (relative to skill dir). Defaults to SKILL.md.",
|
|
710
|
+
},
|
|
711
|
+
},
|
|
712
|
+
required: ["name", "old", "new"],
|
|
713
|
+
},
|
|
714
|
+
execute: async (input) => {
|
|
715
|
+
const result = patchSkill(input.name, input.old, input.new, input.file);
|
|
716
|
+
if (result.success)
|
|
717
|
+
reloadSkills();
|
|
718
|
+
return result.success ? `✅ ${result.message}` : `⚠️ ${result.message}`;
|
|
719
|
+
},
|
|
720
|
+
};
|
|
721
|
+
const skillEdit = {
|
|
722
|
+
name: "skill_edit",
|
|
723
|
+
description: "Rewrite an entire skill's instructions (the body after frontmatter). Use for major overhauls only — prefer skill_patch for small changes.",
|
|
724
|
+
input_schema: {
|
|
725
|
+
type: "object",
|
|
726
|
+
properties: {
|
|
727
|
+
name: {
|
|
728
|
+
type: "string",
|
|
729
|
+
description: "Skill name to rewrite.",
|
|
730
|
+
},
|
|
731
|
+
content: {
|
|
732
|
+
type: "string",
|
|
733
|
+
description: "New full skill instructions in markdown.",
|
|
734
|
+
},
|
|
735
|
+
},
|
|
736
|
+
required: ["name", "content"],
|
|
737
|
+
},
|
|
738
|
+
execute: async (input) => {
|
|
739
|
+
const result = editSkill(input.name, input.content);
|
|
740
|
+
if (result.success)
|
|
741
|
+
reloadSkills();
|
|
742
|
+
return result.success ? `✅ ${result.message}` : `⚠️ ${result.message}`;
|
|
743
|
+
},
|
|
744
|
+
};
|
|
745
|
+
const skillDelete = {
|
|
746
|
+
name: "skill_delete",
|
|
747
|
+
description: "Delete a skill entirely. The skill and all its supporting files are removed.",
|
|
748
|
+
input_schema: {
|
|
749
|
+
type: "object",
|
|
750
|
+
properties: {
|
|
751
|
+
name: {
|
|
752
|
+
type: "string",
|
|
753
|
+
description: "Skill name to delete.",
|
|
754
|
+
},
|
|
755
|
+
},
|
|
756
|
+
required: ["name"],
|
|
757
|
+
},
|
|
758
|
+
execute: async (input) => {
|
|
759
|
+
const result = deleteSkill(input.name);
|
|
760
|
+
if (result.success)
|
|
761
|
+
reloadSkills();
|
|
762
|
+
return result.success ? `🗑 ${result.message}` : `⚠️ ${result.message}`;
|
|
763
|
+
},
|
|
764
|
+
};
|
|
765
|
+
const skillView = {
|
|
766
|
+
name: "skill_view",
|
|
767
|
+
description: "View a skill's full instructions and content. Use this when you need to follow a skill's procedure. Lists supporting files if present.",
|
|
768
|
+
input_schema: {
|
|
769
|
+
type: "object",
|
|
770
|
+
properties: {
|
|
771
|
+
name: {
|
|
772
|
+
type: "string",
|
|
773
|
+
description: "Skill name to view.",
|
|
774
|
+
},
|
|
775
|
+
file: {
|
|
776
|
+
type: "string",
|
|
777
|
+
description: "Optional supporting file to view (e.g. 'references/api.md').",
|
|
778
|
+
},
|
|
779
|
+
},
|
|
780
|
+
required: ["name"],
|
|
781
|
+
},
|
|
782
|
+
execute: async (input) => {
|
|
783
|
+
const result = viewSkill(input.name, input.file);
|
|
784
|
+
return result.content;
|
|
785
|
+
},
|
|
786
|
+
};
|
|
787
|
+
const skillList = {
|
|
788
|
+
name: "skill_list",
|
|
789
|
+
description: "List all available skills with names and descriptions. Compact overview — use skill_view to see full instructions.",
|
|
790
|
+
input_schema: {
|
|
791
|
+
type: "object",
|
|
792
|
+
properties: {},
|
|
793
|
+
required: [],
|
|
794
|
+
},
|
|
795
|
+
execute: async () => {
|
|
796
|
+
const manualSkills = listLoadedSkills().filter((s) => s.source === "manual");
|
|
797
|
+
const agentSkills = listLoadedSkills().filter((s) => s.source === "agent");
|
|
798
|
+
if (manualSkills.length === 0 && agentSkills.length === 0) {
|
|
799
|
+
return "No skills available yet.";
|
|
800
|
+
}
|
|
801
|
+
const parts = [];
|
|
802
|
+
if (manualSkills.length > 0) {
|
|
803
|
+
parts.push("Manual skills:\n" + manualSkills.map((s) => `- 📄 ${s.name}: ${s.description}`).join("\n"));
|
|
804
|
+
}
|
|
805
|
+
if (agentSkills.length > 0) {
|
|
806
|
+
parts.push("Agent-created skills:\n" + agentSkills.map((s) => `- 🧠 ${s.name}: ${s.description}`).join("\n"));
|
|
807
|
+
}
|
|
808
|
+
return parts.join("\n\n");
|
|
809
|
+
},
|
|
810
|
+
};
|
|
811
|
+
const sendMessage = {
|
|
812
|
+
name: "send_message",
|
|
813
|
+
description: "Send a direct message to the user via Telegram. Use this to proactively send notifications, alerts, or responses without waiting for the user to ask. The message will be delivered immediately.",
|
|
814
|
+
input_schema: {
|
|
815
|
+
type: "object",
|
|
816
|
+
properties: {
|
|
817
|
+
message: {
|
|
818
|
+
type: "string",
|
|
819
|
+
description: "The message to send to the user via Telegram.",
|
|
820
|
+
},
|
|
821
|
+
},
|
|
822
|
+
required: ["message"],
|
|
823
|
+
},
|
|
824
|
+
execute: async (input) => {
|
|
825
|
+
const message = input.message;
|
|
826
|
+
const userId = [...config.allowedUserIds][0];
|
|
827
|
+
if (!userId) {
|
|
828
|
+
return "Error: No allowed users configured.";
|
|
829
|
+
}
|
|
830
|
+
try {
|
|
831
|
+
await sendToTelegram(userId, message);
|
|
832
|
+
return "Message sent to Telegram.";
|
|
833
|
+
}
|
|
834
|
+
catch (err) {
|
|
835
|
+
return `Failed to send message: ${err instanceof Error ? err.message : String(err)}`;
|
|
836
|
+
}
|
|
837
|
+
},
|
|
838
|
+
};
|
|
839
|
+
const factoryCreateTool = {
|
|
840
|
+
name: "factory_create",
|
|
841
|
+
description: "Create a new Project Factory workflow. Fredrix (Product Manager) and Stoffe (Systems Architect) will decompose the description into a DAG of tasks assigned to the right agents with dependencies. The factory orchestrator will then execute them automatically.",
|
|
842
|
+
input_schema: {
|
|
843
|
+
type: "object",
|
|
844
|
+
properties: {
|
|
845
|
+
description: {
|
|
846
|
+
type: "string",
|
|
847
|
+
description: "Project description. Be specific about what you want built.",
|
|
848
|
+
},
|
|
849
|
+
},
|
|
850
|
+
required: ["description"],
|
|
851
|
+
},
|
|
852
|
+
execute: async (input) => {
|
|
853
|
+
try {
|
|
854
|
+
const { project, tasks } = await factoryCreate(input.description);
|
|
855
|
+
const taskList = tasks
|
|
856
|
+
.map((t, i) => `${i + 1}. [${t.status}] ${t.title} → @${t.assignedAgent}${t.reviewerAgent ? ` (review: ${t.reviewerAgent})` : ""}${t.dependencies.length > 0 ? ` deps:[${t.dependencies.join(",")}]` : ""}`)
|
|
857
|
+
.join("\n");
|
|
858
|
+
return `🏭 **Factory Project Created**\n\nID: ${project.id}\nTitle: ${project.title}\nTasks: ${tasks.length}\n\n${taskList}\n\nThe factory orchestrator will start executing tasks automatically.`;
|
|
859
|
+
}
|
|
860
|
+
catch (err) {
|
|
861
|
+
return `⚠️ Factory create failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
862
|
+
}
|
|
863
|
+
},
|
|
864
|
+
};
|
|
865
|
+
const factoryStatusTool = {
|
|
866
|
+
name: "factory_status",
|
|
867
|
+
description: "Show the status of a factory project and all its tasks (Kanban board view).",
|
|
868
|
+
input_schema: {
|
|
869
|
+
type: "object",
|
|
870
|
+
properties: {
|
|
871
|
+
project_id: { type: "number", description: "Factory project ID. If omitted, shows the latest project." },
|
|
872
|
+
},
|
|
873
|
+
required: [],
|
|
874
|
+
},
|
|
875
|
+
execute: async (input) => {
|
|
876
|
+
let project;
|
|
877
|
+
if (input.project_id) {
|
|
878
|
+
project = getFactoryProject(input.project_id);
|
|
879
|
+
}
|
|
880
|
+
else {
|
|
881
|
+
const all = listFactoryProjects();
|
|
882
|
+
project = all[0] || null;
|
|
883
|
+
}
|
|
884
|
+
if (!project)
|
|
885
|
+
return "⚠️ No factory project found.";
|
|
886
|
+
const tasks = getFactoryTasks(project.id);
|
|
887
|
+
if (tasks.length === 0)
|
|
888
|
+
return `**${project.title}** (id: ${project.id}) — No tasks.`;
|
|
889
|
+
const statusEmoji = {
|
|
890
|
+
backlog: "📋",
|
|
891
|
+
in_progress: "⚡",
|
|
892
|
+
review: "🔍",
|
|
893
|
+
done: "✅",
|
|
894
|
+
failed: "❌",
|
|
895
|
+
human_intervention: "🚨",
|
|
896
|
+
};
|
|
897
|
+
const grouped = {
|
|
898
|
+
backlog: [],
|
|
899
|
+
in_progress: [],
|
|
900
|
+
review: [],
|
|
901
|
+
done: [],
|
|
902
|
+
failed: [],
|
|
903
|
+
human_intervention: [],
|
|
904
|
+
};
|
|
905
|
+
for (const t of tasks) {
|
|
906
|
+
grouped[t.status]?.push(t);
|
|
907
|
+
}
|
|
908
|
+
const progress = project.taskCount > 0
|
|
909
|
+
? Math.round((project.completedTasks / project.taskCount) * 100)
|
|
910
|
+
: 0;
|
|
911
|
+
const lines = [
|
|
912
|
+
`🏭 **${project.title}** (id: ${project.id})`,
|
|
913
|
+
`Status: ${project.status} | Progress: ${progress}% (${project.completedTasks}/${project.taskCount})`,
|
|
914
|
+
`Workspace: ${project.workspacePath}`,
|
|
915
|
+
"Legend: [impl]=can implement/integrate, [qa]=testing role, [rev]=code-review role, [sec]=security role",
|
|
916
|
+
"",
|
|
917
|
+
];
|
|
918
|
+
for (const [status, statusTasks] of Object.entries(grouped)) {
|
|
919
|
+
if (statusTasks.length === 0)
|
|
920
|
+
continue;
|
|
921
|
+
lines.push(`**${statusEmoji[status] || "❓"} ${status}:**`);
|
|
922
|
+
for (const t of statusTasks) {
|
|
923
|
+
const retry = t.retryCount > 0 ? ` (retry: ${t.retryCount}/${t.maxRetries})` : "";
|
|
924
|
+
const stage = typeof t.contextPayload.stage_id === "string" ? ` [stage:${t.contextPayload.stage_id}]` : "";
|
|
925
|
+
const roleLabelMap = {
|
|
926
|
+
code: "impl",
|
|
927
|
+
implementation: "impl",
|
|
928
|
+
integration: "impl",
|
|
929
|
+
qa: "qa",
|
|
930
|
+
review: "rev",
|
|
931
|
+
"code-review": "rev",
|
|
932
|
+
security: "sec",
|
|
933
|
+
};
|
|
934
|
+
const toRoleLabels = (roles) => Array.from(new Set(roles
|
|
935
|
+
.map((r) => roleLabelMap[r] || "")
|
|
936
|
+
.filter((r) => r.length > 0)));
|
|
937
|
+
const assignedRoles = toRoleLabels(getAgentPipelineRoles(t.assignedAgent));
|
|
938
|
+
const assignedRoleStr = assignedRoles.length > 0 ? ` [${assignedRoles.join(",")}]` : "";
|
|
939
|
+
const reviewer = t.reviewerAgent
|
|
940
|
+
? (() => {
|
|
941
|
+
const reviewerRoles = toRoleLabels(getAgentPipelineRoles(t.reviewerAgent));
|
|
942
|
+
const reviewerRoleStr = reviewerRoles.length > 0 ? ` [${reviewerRoles.join(",")}]` : "";
|
|
943
|
+
return ` → review: ${t.reviewerAgent}${reviewerRoleStr}`;
|
|
944
|
+
})()
|
|
945
|
+
: "";
|
|
946
|
+
const latestFeedback = typeof t.contextPayload.latest_review_feedback === "object"
|
|
947
|
+
&& t.contextPayload.latest_review_feedback !== null
|
|
948
|
+
? t.contextPayload.latest_review_feedback
|
|
949
|
+
: null;
|
|
950
|
+
const reason = latestFeedback && typeof latestFeedback.reason === "string"
|
|
951
|
+
? ` | reason: ${latestFeedback.reason}`
|
|
952
|
+
: "";
|
|
953
|
+
lines.push(` #${t.id} ${t.title}${stage} → @${t.assignedAgent}${assignedRoleStr}${reviewer}${retry}${reason}`);
|
|
954
|
+
}
|
|
955
|
+
lines.push("");
|
|
956
|
+
}
|
|
957
|
+
return lines.join("\n");
|
|
958
|
+
},
|
|
959
|
+
};
|
|
960
|
+
const factoryListTool = {
|
|
961
|
+
name: "factory_list",
|
|
962
|
+
description: "List all factory projects with their progress.",
|
|
963
|
+
input_schema: {
|
|
964
|
+
type: "object",
|
|
965
|
+
properties: {},
|
|
966
|
+
required: [],
|
|
967
|
+
},
|
|
968
|
+
execute: async () => {
|
|
969
|
+
const projects = listFactoryProjects();
|
|
970
|
+
if (projects.length === 0)
|
|
971
|
+
return "No factory projects yet. Use factory_create to start one.";
|
|
972
|
+
return projects
|
|
973
|
+
.map((p) => {
|
|
974
|
+
const progress = p.taskCount > 0 ? Math.round((p.completedTasks / p.taskCount) * 100) : 0;
|
|
975
|
+
return `[${p.id}] ${p.title} — ${p.status} (${progress}%, ${p.completedTasks}/${p.taskCount} tasks)`;
|
|
976
|
+
})
|
|
977
|
+
.join("\n");
|
|
978
|
+
},
|
|
979
|
+
};
|
|
980
|
+
const factoryPauseTool = {
|
|
981
|
+
name: "factory_pause",
|
|
982
|
+
description: "Pause a running factory project. Tasks already in progress will complete but no new ones will start.",
|
|
983
|
+
input_schema: {
|
|
984
|
+
type: "object",
|
|
985
|
+
properties: {
|
|
986
|
+
project_id: { type: "number", description: "Factory project ID to pause." },
|
|
987
|
+
},
|
|
988
|
+
required: ["project_id"],
|
|
989
|
+
},
|
|
990
|
+
execute: async (input) => {
|
|
991
|
+
const ok = setProjectStatus(input.project_id, "paused");
|
|
992
|
+
return ok ? `⏸ Factory project ${input.project_id} paused.` : `⚠️ Project ${input.project_id} not found.`;
|
|
993
|
+
},
|
|
994
|
+
};
|
|
995
|
+
const factoryResumeTool = {
|
|
996
|
+
name: "factory_resume",
|
|
997
|
+
description: "Resume a paused factory project.",
|
|
998
|
+
input_schema: {
|
|
999
|
+
type: "object",
|
|
1000
|
+
properties: {
|
|
1001
|
+
project_id: { type: "number", description: "Factory project ID to resume." },
|
|
1002
|
+
},
|
|
1003
|
+
required: ["project_id"],
|
|
1004
|
+
},
|
|
1005
|
+
execute: async (input) => {
|
|
1006
|
+
const ok = setProjectStatus(input.project_id, "running");
|
|
1007
|
+
return ok ? `▶️ Factory project ${input.project_id} resumed.` : `⚠️ Project ${input.project_id} not found.`;
|
|
1008
|
+
},
|
|
1009
|
+
};
|
|
1010
|
+
const factoryRetryTool = {
|
|
1011
|
+
name: "factory_retry",
|
|
1012
|
+
description: "Force-retry a task that is stuck in human_intervention status.",
|
|
1013
|
+
input_schema: {
|
|
1014
|
+
type: "object",
|
|
1015
|
+
properties: {
|
|
1016
|
+
task_id: { type: "number", description: "Factory task ID to retry." },
|
|
1017
|
+
},
|
|
1018
|
+
required: ["task_id"],
|
|
1019
|
+
},
|
|
1020
|
+
execute: async (input) => {
|
|
1021
|
+
const ok = forceRetryTask(input.task_id);
|
|
1022
|
+
return ok ? `🔄 Task ${input.task_id} reset to backlog. Will be picked up on next tick.` : `⚠️ Task ${input.task_id} not found or not in human_intervention status.`;
|
|
1023
|
+
},
|
|
1024
|
+
};
|
|
1025
|
+
const factoryRestartTool = {
|
|
1026
|
+
name: "factory_restart",
|
|
1027
|
+
description: "Restart a factory project. Default resets non-done tasks; full mode also clears the project workspace.",
|
|
1028
|
+
input_schema: {
|
|
1029
|
+
type: "object",
|
|
1030
|
+
properties: {
|
|
1031
|
+
project_id: { type: "number", description: "Factory project ID to restart." },
|
|
1032
|
+
mode: { type: "string", enum: ["partial", "full"], description: "Restart mode. Default: partial." },
|
|
1033
|
+
},
|
|
1034
|
+
required: ["project_id"],
|
|
1035
|
+
},
|
|
1036
|
+
execute: async (input) => {
|
|
1037
|
+
const mode = input.mode === "full" ? "full" : "partial";
|
|
1038
|
+
const result = restartFactoryProject(input.project_id, mode);
|
|
1039
|
+
if (!result.ok)
|
|
1040
|
+
return `⚠️ ${result.message}`;
|
|
1041
|
+
return `🔄 Project ${result.projectId} restarted (${result.mode}). Reset ${result.resetTasks} tasks. Workspace: ${result.workspacePath}`;
|
|
1042
|
+
},
|
|
1043
|
+
};
|
|
1044
|
+
export function buildTools() {
|
|
1045
|
+
const base = [
|
|
1046
|
+
getCurrentTime,
|
|
1047
|
+
remember,
|
|
1048
|
+
recall,
|
|
1049
|
+
forget,
|
|
1050
|
+
searchConversationsTool,
|
|
1051
|
+
speak,
|
|
1052
|
+
knowledgeAdd,
|
|
1053
|
+
knowledgeQuery,
|
|
1054
|
+
scheduleTask,
|
|
1055
|
+
scheduleList,
|
|
1056
|
+
scheduleToggle,
|
|
1057
|
+
scheduleDelete,
|
|
1058
|
+
webhookCreate,
|
|
1059
|
+
webhookList,
|
|
1060
|
+
webhookDelete,
|
|
1061
|
+
sessionCreate,
|
|
1062
|
+
sessionList,
|
|
1063
|
+
sessionHistory,
|
|
1064
|
+
sessionSend,
|
|
1065
|
+
sessionDelete,
|
|
1066
|
+
canvasRender,
|
|
1067
|
+
docSaveTool,
|
|
1068
|
+
docListTool,
|
|
1069
|
+
docReadTool,
|
|
1070
|
+
docDeleteTool,
|
|
1071
|
+
docSearchTool,
|
|
1072
|
+
agentCreateTool,
|
|
1073
|
+
agentListTool,
|
|
1074
|
+
agentShowTool,
|
|
1075
|
+
agentDeleteTool,
|
|
1076
|
+
skillCreate,
|
|
1077
|
+
skillPatch,
|
|
1078
|
+
skillEdit,
|
|
1079
|
+
skillDelete,
|
|
1080
|
+
skillView,
|
|
1081
|
+
skillList,
|
|
1082
|
+
shellExec,
|
|
1083
|
+
...configTools,
|
|
1084
|
+
...fileTools,
|
|
1085
|
+
browser,
|
|
1086
|
+
webSearch,
|
|
1087
|
+
sendMessage,
|
|
1088
|
+
factoryCreateTool,
|
|
1089
|
+
factoryStatusTool,
|
|
1090
|
+
factoryListTool,
|
|
1091
|
+
factoryPauseTool,
|
|
1092
|
+
factoryResumeTool,
|
|
1093
|
+
factoryRetryTool,
|
|
1094
|
+
factoryRestartTool,
|
|
1095
|
+
];
|
|
1096
|
+
const mcpTools = getMCPTools();
|
|
1097
|
+
return [...base, ...mcpTools];
|
|
1098
|
+
}
|
|
1099
|
+
export const tools = [];
|
|
1100
|
+
export function initializeTools() {
|
|
1101
|
+
const built = buildTools();
|
|
1102
|
+
tools.length = 0;
|
|
1103
|
+
tools.push(...built);
|
|
1104
|
+
console.log(`🔧 ${tools.length} tools registered`);
|
|
1105
|
+
}
|
|
1106
|
+
export function getTool(name) {
|
|
1107
|
+
return tools.find((t) => t.name === name);
|
|
1108
|
+
}
|
|
1109
|
+
//# sourceMappingURL=index.js.map
|