genesis-ai-cli 7.4.5
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.example +78 -0
- package/README.md +282 -0
- package/dist/src/active-inference/actions.d.ts +75 -0
- package/dist/src/active-inference/actions.js +250 -0
- package/dist/src/active-inference/autonomous-loop.d.ts +103 -0
- package/dist/src/active-inference/autonomous-loop.js +289 -0
- package/dist/src/active-inference/core.d.ts +85 -0
- package/dist/src/active-inference/core.js +555 -0
- package/dist/src/active-inference/demo-autonomous-loop.d.ts +8 -0
- package/dist/src/active-inference/demo-autonomous-loop.js +338 -0
- package/dist/src/active-inference/demo-value-integration.d.ts +8 -0
- package/dist/src/active-inference/demo-value-integration.js +174 -0
- package/dist/src/active-inference/index.d.ts +32 -0
- package/dist/src/active-inference/index.js +88 -0
- package/dist/src/active-inference/integration.d.ts +114 -0
- package/dist/src/active-inference/integration.js +698 -0
- package/dist/src/active-inference/memory-integration.d.ts +51 -0
- package/dist/src/active-inference/memory-integration.js +232 -0
- package/dist/src/active-inference/observations.d.ts +67 -0
- package/dist/src/active-inference/observations.js +147 -0
- package/dist/src/active-inference/test-active-inference.d.ts +8 -0
- package/dist/src/active-inference/test-active-inference.js +320 -0
- package/dist/src/active-inference/test-value-integration.d.ts +6 -0
- package/dist/src/active-inference/test-value-integration.js +168 -0
- package/dist/src/active-inference/types.d.ts +150 -0
- package/dist/src/active-inference/types.js +59 -0
- package/dist/src/active-inference/value-integration.d.ts +164 -0
- package/dist/src/active-inference/value-integration.js +459 -0
- package/dist/src/agents/base-agent.d.ts +53 -0
- package/dist/src/agents/base-agent.js +178 -0
- package/dist/src/agents/builder.d.ts +67 -0
- package/dist/src/agents/builder.js +537 -0
- package/dist/src/agents/critic.d.ts +35 -0
- package/dist/src/agents/critic.js +322 -0
- package/dist/src/agents/ethicist.d.ts +54 -0
- package/dist/src/agents/ethicist.js +393 -0
- package/dist/src/agents/explorer.d.ts +26 -0
- package/dist/src/agents/explorer.js +216 -0
- package/dist/src/agents/feeling.d.ts +41 -0
- package/dist/src/agents/feeling.js +320 -0
- package/dist/src/agents/index.d.ts +111 -0
- package/dist/src/agents/index.js +222 -0
- package/dist/src/agents/memory.d.ts +69 -0
- package/dist/src/agents/memory.js +404 -0
- package/dist/src/agents/message-bus.d.ts +88 -0
- package/dist/src/agents/message-bus.js +267 -0
- package/dist/src/agents/narrator.d.ts +90 -0
- package/dist/src/agents/narrator.js +473 -0
- package/dist/src/agents/planner.d.ts +38 -0
- package/dist/src/agents/planner.js +341 -0
- package/dist/src/agents/predictor.d.ts +73 -0
- package/dist/src/agents/predictor.js +506 -0
- package/dist/src/agents/sensor.d.ts +88 -0
- package/dist/src/agents/sensor.js +377 -0
- package/dist/src/agents/test-agents.d.ts +6 -0
- package/dist/src/agents/test-agents.js +73 -0
- package/dist/src/agents/types.d.ts +194 -0
- package/dist/src/agents/types.js +7 -0
- package/dist/src/brain/index.d.ts +185 -0
- package/dist/src/brain/index.js +843 -0
- package/dist/src/brain/trace.d.ts +91 -0
- package/dist/src/brain/trace.js +327 -0
- package/dist/src/brain/types.d.ts +165 -0
- package/dist/src/brain/types.js +51 -0
- package/dist/src/cli/chat.d.ts +237 -0
- package/dist/src/cli/chat.js +1959 -0
- package/dist/src/cli/dispatcher.d.ts +182 -0
- package/dist/src/cli/dispatcher.js +718 -0
- package/dist/src/cli/human-loop.d.ts +170 -0
- package/dist/src/cli/human-loop.js +543 -0
- package/dist/src/cli/index.d.ts +12 -0
- package/dist/src/cli/index.js +28 -0
- package/dist/src/cli/interactive.d.ts +141 -0
- package/dist/src/cli/interactive.js +757 -0
- package/dist/src/cli/ui.d.ts +205 -0
- package/dist/src/cli/ui.js +632 -0
- package/dist/src/consciousness/attention-schema.d.ts +154 -0
- package/dist/src/consciousness/attention-schema.js +432 -0
- package/dist/src/consciousness/global-workspace.d.ts +149 -0
- package/dist/src/consciousness/global-workspace.js +422 -0
- package/dist/src/consciousness/index.d.ts +186 -0
- package/dist/src/consciousness/index.js +476 -0
- package/dist/src/consciousness/phi-calculator.d.ts +119 -0
- package/dist/src/consciousness/phi-calculator.js +445 -0
- package/dist/src/consciousness/phi-decisions.d.ts +169 -0
- package/dist/src/consciousness/phi-decisions.js +383 -0
- package/dist/src/consciousness/phi-monitor.d.ts +153 -0
- package/dist/src/consciousness/phi-monitor.js +465 -0
- package/dist/src/consciousness/types.d.ts +260 -0
- package/dist/src/consciousness/types.js +44 -0
- package/dist/src/daemon/dream-mode.d.ts +115 -0
- package/dist/src/daemon/dream-mode.js +470 -0
- package/dist/src/daemon/index.d.ts +162 -0
- package/dist/src/daemon/index.js +542 -0
- package/dist/src/daemon/maintenance.d.ts +139 -0
- package/dist/src/daemon/maintenance.js +549 -0
- package/dist/src/daemon/process.d.ts +82 -0
- package/dist/src/daemon/process.js +442 -0
- package/dist/src/daemon/scheduler.d.ts +90 -0
- package/dist/src/daemon/scheduler.js +494 -0
- package/dist/src/daemon/types.d.ts +213 -0
- package/dist/src/daemon/types.js +50 -0
- package/dist/src/epistemic/index.d.ts +74 -0
- package/dist/src/epistemic/index.js +225 -0
- package/dist/src/grounding/epistemic-stack.d.ts +100 -0
- package/dist/src/grounding/epistemic-stack.js +408 -0
- package/dist/src/grounding/feedback.d.ts +98 -0
- package/dist/src/grounding/feedback.js +276 -0
- package/dist/src/grounding/index.d.ts +123 -0
- package/dist/src/grounding/index.js +224 -0
- package/dist/src/grounding/verifier.d.ts +149 -0
- package/dist/src/grounding/verifier.js +484 -0
- package/dist/src/healing/detector.d.ts +110 -0
- package/dist/src/healing/detector.js +436 -0
- package/dist/src/healing/fixer.d.ts +138 -0
- package/dist/src/healing/fixer.js +572 -0
- package/dist/src/healing/index.d.ts +23 -0
- package/dist/src/healing/index.js +43 -0
- package/dist/src/hooks/index.d.ts +135 -0
- package/dist/src/hooks/index.js +317 -0
- package/dist/src/index.d.ts +23 -0
- package/dist/src/index.js +1266 -0
- package/dist/src/kernel/index.d.ts +155 -0
- package/dist/src/kernel/index.js +795 -0
- package/dist/src/kernel/invariants.d.ts +153 -0
- package/dist/src/kernel/invariants.js +355 -0
- package/dist/src/kernel/test-kernel.d.ts +6 -0
- package/dist/src/kernel/test-kernel.js +108 -0
- package/dist/src/kernel/test-real-mcp.d.ts +10 -0
- package/dist/src/kernel/test-real-mcp.js +295 -0
- package/dist/src/llm/index.d.ts +146 -0
- package/dist/src/llm/index.js +428 -0
- package/dist/src/llm/router.d.ts +136 -0
- package/dist/src/llm/router.js +510 -0
- package/dist/src/mcp/index.d.ts +85 -0
- package/dist/src/mcp/index.js +657 -0
- package/dist/src/mcp/resilient.d.ts +139 -0
- package/dist/src/mcp/resilient.js +417 -0
- package/dist/src/memory/cache.d.ts +118 -0
- package/dist/src/memory/cache.js +356 -0
- package/dist/src/memory/cognitive-workspace.d.ts +231 -0
- package/dist/src/memory/cognitive-workspace.js +521 -0
- package/dist/src/memory/consolidation.d.ts +99 -0
- package/dist/src/memory/consolidation.js +443 -0
- package/dist/src/memory/episodic.d.ts +114 -0
- package/dist/src/memory/episodic.js +394 -0
- package/dist/src/memory/forgetting.d.ts +134 -0
- package/dist/src/memory/forgetting.js +324 -0
- package/dist/src/memory/index.d.ts +211 -0
- package/dist/src/memory/index.js +367 -0
- package/dist/src/memory/indexer.d.ts +123 -0
- package/dist/src/memory/indexer.js +479 -0
- package/dist/src/memory/procedural.d.ts +136 -0
- package/dist/src/memory/procedural.js +479 -0
- package/dist/src/memory/semantic.d.ts +132 -0
- package/dist/src/memory/semantic.js +497 -0
- package/dist/src/memory/types.d.ts +193 -0
- package/dist/src/memory/types.js +15 -0
- package/dist/src/orchestrator.d.ts +65 -0
- package/dist/src/orchestrator.js +317 -0
- package/dist/src/persistence/index.d.ts +257 -0
- package/dist/src/persistence/index.js +763 -0
- package/dist/src/pipeline/executor.d.ts +51 -0
- package/dist/src/pipeline/executor.js +695 -0
- package/dist/src/pipeline/index.d.ts +7 -0
- package/dist/src/pipeline/index.js +11 -0
- package/dist/src/self-production.d.ts +67 -0
- package/dist/src/self-production.js +205 -0
- package/dist/src/subagents/executor.d.ts +58 -0
- package/dist/src/subagents/executor.js +283 -0
- package/dist/src/subagents/index.d.ts +37 -0
- package/dist/src/subagents/index.js +53 -0
- package/dist/src/subagents/registry.d.ts +23 -0
- package/dist/src/subagents/registry.js +167 -0
- package/dist/src/subagents/types.d.ts +79 -0
- package/dist/src/subagents/types.js +14 -0
- package/dist/src/tools/bash.d.ts +139 -0
- package/dist/src/tools/bash.js +583 -0
- package/dist/src/tools/edit.d.ts +125 -0
- package/dist/src/tools/edit.js +424 -0
- package/dist/src/tools/git.d.ts +179 -0
- package/dist/src/tools/git.js +504 -0
- package/dist/src/tools/index.d.ts +21 -0
- package/dist/src/tools/index.js +163 -0
- package/dist/src/types.d.ts +145 -0
- package/dist/src/types.js +7 -0
- package/dist/src/world-model/decoder.d.ts +163 -0
- package/dist/src/world-model/decoder.js +517 -0
- package/dist/src/world-model/digital-twin.d.ts +219 -0
- package/dist/src/world-model/digital-twin.js +695 -0
- package/dist/src/world-model/encoder.d.ts +141 -0
- package/dist/src/world-model/encoder.js +564 -0
- package/dist/src/world-model/index.d.ts +221 -0
- package/dist/src/world-model/index.js +772 -0
- package/dist/src/world-model/predictor.d.ts +161 -0
- package/dist/src/world-model/predictor.js +681 -0
- package/dist/src/world-model/test-value-jepa.d.ts +8 -0
- package/dist/src/world-model/test-value-jepa.js +430 -0
- package/dist/src/world-model/types.d.ts +341 -0
- package/dist/src/world-model/types.js +69 -0
- package/dist/src/world-model/value-jepa.d.ts +247 -0
- package/dist/src/world-model/value-jepa.js +622 -0
- package/dist/test/brain.test.d.ts +11 -0
- package/dist/test/brain.test.js +358 -0
- package/dist/test/cli/dispatcher.test.d.ts +4 -0
- package/dist/test/cli/dispatcher.test.js +332 -0
- package/dist/test/cli/human-loop.test.d.ts +4 -0
- package/dist/test/cli/human-loop.test.js +270 -0
- package/dist/test/grounding/feedback.test.d.ts +4 -0
- package/dist/test/grounding/feedback.test.js +462 -0
- package/dist/test/grounding/verifier.test.d.ts +4 -0
- package/dist/test/grounding/verifier.test.js +442 -0
- package/dist/test/grounding.test.d.ts +6 -0
- package/dist/test/grounding.test.js +246 -0
- package/dist/test/healing/detector.test.d.ts +4 -0
- package/dist/test/healing/detector.test.js +266 -0
- package/dist/test/healing/fixer.test.d.ts +4 -0
- package/dist/test/healing/fixer.test.js +369 -0
- package/dist/test/integration.test.d.ts +5 -0
- package/dist/test/integration.test.js +290 -0
- package/dist/test/tools/bash.test.d.ts +4 -0
- package/dist/test/tools/bash.test.js +348 -0
- package/dist/test/tools/edit.test.d.ts +4 -0
- package/dist/test/tools/edit.test.js +350 -0
- package/dist/test/tools/git.test.d.ts +4 -0
- package/dist/test/tools/git.test.js +350 -0
- package/package.json +60 -0
|
@@ -0,0 +1,718 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Genesis 6.0 - Tool Dispatcher
|
|
4
|
+
*
|
|
5
|
+
* Intelligent router that:
|
|
6
|
+
* 1. Parses tool calls from LLM responses
|
|
7
|
+
* 2. Routes to appropriate tools (local or MCP)
|
|
8
|
+
* 3. Supports parallel execution
|
|
9
|
+
* 4. Tracks execution status with progress
|
|
10
|
+
* 5. Feeds results back for continued conversation
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.ToolDispatcher = void 0;
|
|
14
|
+
exports.getDispatcher = getDispatcher;
|
|
15
|
+
exports.resetDispatcher = resetDispatcher;
|
|
16
|
+
exports.dispatchTools = dispatchTools;
|
|
17
|
+
exports.executeTool = executeTool;
|
|
18
|
+
exports.listAllTools = listAllTools;
|
|
19
|
+
const index_js_1 = require("../tools/index.js");
|
|
20
|
+
const index_js_2 = require("../mcp/index.js");
|
|
21
|
+
// ============================================================================
|
|
22
|
+
// Tool Categories for Routing
|
|
23
|
+
// ============================================================================
|
|
24
|
+
const LOCAL_TOOLS = [
|
|
25
|
+
// File tools
|
|
26
|
+
'bash', 'edit', 'write', 'read', 'glob', 'grep',
|
|
27
|
+
// Git tools
|
|
28
|
+
'git_status', 'git_diff', 'git_log', 'git_add', 'git_commit', 'git_push',
|
|
29
|
+
'git_branch', 'git_checkout',
|
|
30
|
+
];
|
|
31
|
+
const MCP_TOOL_MAP = {
|
|
32
|
+
// Knowledge
|
|
33
|
+
'search_arxiv': 'arxiv',
|
|
34
|
+
'parse_paper_content': 'arxiv',
|
|
35
|
+
'get_recent_ai_papers': 'arxiv',
|
|
36
|
+
'search_semantic_scholar': 'semantic-scholar',
|
|
37
|
+
'get_semantic_scholar_paper': 'semantic-scholar',
|
|
38
|
+
'resolve-library-id': 'context7',
|
|
39
|
+
'query-docs': 'context7',
|
|
40
|
+
'wolfram_query': 'wolfram',
|
|
41
|
+
// Research
|
|
42
|
+
'web_search': 'gemini',
|
|
43
|
+
'brave_web_search': 'brave-search',
|
|
44
|
+
'web_search_exa': 'exa',
|
|
45
|
+
'firecrawl_scrape': 'firecrawl',
|
|
46
|
+
'firecrawl_search': 'firecrawl',
|
|
47
|
+
// Creation
|
|
48
|
+
'openai_chat': 'openai',
|
|
49
|
+
'create_repository': 'github',
|
|
50
|
+
'create_issue': 'github',
|
|
51
|
+
'create_pull_request': 'github',
|
|
52
|
+
// Storage - Memory (knowledge graph)
|
|
53
|
+
'create_entities': 'memory',
|
|
54
|
+
'create_relations': 'memory',
|
|
55
|
+
'add_observations': 'memory',
|
|
56
|
+
'search_nodes': 'memory',
|
|
57
|
+
'read_graph': 'memory',
|
|
58
|
+
'read_file': 'filesystem',
|
|
59
|
+
'write_file': 'filesystem',
|
|
60
|
+
'list_directory': 'filesystem',
|
|
61
|
+
// Visual
|
|
62
|
+
'stability-ai-generate-image': 'stability-ai',
|
|
63
|
+
'stability-ai-generate-image-sd35': 'stability-ai',
|
|
64
|
+
};
|
|
65
|
+
// ============================================================================
|
|
66
|
+
// v7.3: Static Tool Schemas (fallback when MCP discovery fails)
|
|
67
|
+
// ============================================================================
|
|
68
|
+
const STATIC_TOOL_SCHEMAS = {
|
|
69
|
+
// Gemini - note: parameter is 'q' not 'query'
|
|
70
|
+
'web_search': {
|
|
71
|
+
description: 'Web search via Gemini AI',
|
|
72
|
+
inputSchema: {
|
|
73
|
+
type: 'object',
|
|
74
|
+
properties: {
|
|
75
|
+
q: { type: 'string', description: 'Search query (required)' },
|
|
76
|
+
mode: { type: 'string', description: 'Search mode: normal or research' },
|
|
77
|
+
},
|
|
78
|
+
required: ['q'],
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
// Brave Search
|
|
82
|
+
'brave_web_search': {
|
|
83
|
+
description: 'Web search via Brave',
|
|
84
|
+
inputSchema: {
|
|
85
|
+
type: 'object',
|
|
86
|
+
properties: {
|
|
87
|
+
query: { type: 'string', description: 'Search query (required)' },
|
|
88
|
+
count: { type: 'number', description: 'Number of results (1-20)' },
|
|
89
|
+
},
|
|
90
|
+
required: ['query'],
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
// arXiv
|
|
94
|
+
'search_arxiv': {
|
|
95
|
+
description: 'Search academic papers on arXiv',
|
|
96
|
+
inputSchema: {
|
|
97
|
+
type: 'object',
|
|
98
|
+
properties: {
|
|
99
|
+
query: { type: 'string', description: 'Search query' },
|
|
100
|
+
maxResults: { type: 'number', description: 'Max results (default 5)' },
|
|
101
|
+
},
|
|
102
|
+
required: ['query'],
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
// OpenAI
|
|
106
|
+
'openai_chat': {
|
|
107
|
+
description: 'Chat completion via GPT-4',
|
|
108
|
+
inputSchema: {
|
|
109
|
+
type: 'object',
|
|
110
|
+
properties: {
|
|
111
|
+
messages: { type: 'array', description: 'Array of {role, content} messages' },
|
|
112
|
+
model: { type: 'string', description: 'Model: gpt-4o, gpt-4o-mini, o1-preview' },
|
|
113
|
+
},
|
|
114
|
+
required: ['messages'],
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
// Filesystem
|
|
118
|
+
'read_file': {
|
|
119
|
+
description: 'Read file contents',
|
|
120
|
+
inputSchema: {
|
|
121
|
+
type: 'object',
|
|
122
|
+
properties: {
|
|
123
|
+
path: { type: 'string', description: 'Absolute file path' },
|
|
124
|
+
},
|
|
125
|
+
required: ['path'],
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
'write_file': {
|
|
129
|
+
description: 'Write content to file',
|
|
130
|
+
inputSchema: {
|
|
131
|
+
type: 'object',
|
|
132
|
+
properties: {
|
|
133
|
+
path: { type: 'string', description: 'Absolute file path' },
|
|
134
|
+
content: { type: 'string', description: 'File content' },
|
|
135
|
+
},
|
|
136
|
+
required: ['path', 'content'],
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
'list_directory': {
|
|
140
|
+
description: 'List directory contents',
|
|
141
|
+
inputSchema: {
|
|
142
|
+
type: 'object',
|
|
143
|
+
properties: {
|
|
144
|
+
path: { type: 'string', description: 'Directory path' },
|
|
145
|
+
},
|
|
146
|
+
required: ['path'],
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
// Memory
|
|
150
|
+
'read_graph': {
|
|
151
|
+
description: 'Read the entire knowledge graph',
|
|
152
|
+
inputSchema: { type: 'object', properties: {} },
|
|
153
|
+
},
|
|
154
|
+
'search_nodes': {
|
|
155
|
+
description: 'Search nodes in knowledge graph',
|
|
156
|
+
inputSchema: {
|
|
157
|
+
type: 'object',
|
|
158
|
+
properties: {
|
|
159
|
+
query: { type: 'string', description: 'Search query' },
|
|
160
|
+
},
|
|
161
|
+
required: ['query'],
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
'create_entities': {
|
|
165
|
+
description: 'Create entities in knowledge graph',
|
|
166
|
+
inputSchema: {
|
|
167
|
+
type: 'object',
|
|
168
|
+
properties: {
|
|
169
|
+
entities: { type: 'array', description: 'Array of {name, entityType, observations}' },
|
|
170
|
+
},
|
|
171
|
+
required: ['entities'],
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
'create_relations': {
|
|
175
|
+
description: 'Create relations between entities in knowledge graph',
|
|
176
|
+
inputSchema: {
|
|
177
|
+
type: 'object',
|
|
178
|
+
properties: {
|
|
179
|
+
relations: { type: 'array', description: 'Array of {from, to, relationType}' },
|
|
180
|
+
},
|
|
181
|
+
required: ['relations'],
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
'add_observations': {
|
|
185
|
+
description: 'Add observations to existing entities',
|
|
186
|
+
inputSchema: {
|
|
187
|
+
type: 'object',
|
|
188
|
+
properties: {
|
|
189
|
+
observations: { type: 'array', description: 'Array of {entityName, contents[]}' },
|
|
190
|
+
},
|
|
191
|
+
required: ['observations'],
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
// GitHub
|
|
195
|
+
'create_repository': {
|
|
196
|
+
description: 'Create GitHub repository',
|
|
197
|
+
inputSchema: {
|
|
198
|
+
type: 'object',
|
|
199
|
+
properties: {
|
|
200
|
+
name: { type: 'string', description: 'Repository name' },
|
|
201
|
+
description: { type: 'string', description: 'Repository description' },
|
|
202
|
+
private: { type: 'boolean', description: 'Private repository' },
|
|
203
|
+
},
|
|
204
|
+
required: ['name'],
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
// Wolfram
|
|
208
|
+
'wolfram_query': {
|
|
209
|
+
description: 'Query Wolfram Alpha for math/science',
|
|
210
|
+
inputSchema: {
|
|
211
|
+
type: 'object',
|
|
212
|
+
properties: {
|
|
213
|
+
query: { type: 'string', description: 'Query in natural language' },
|
|
214
|
+
mode: { type: 'string', description: 'Mode: llm, full, short, simple' },
|
|
215
|
+
},
|
|
216
|
+
required: ['query'],
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
// Firecrawl
|
|
220
|
+
'firecrawl_scrape': {
|
|
221
|
+
description: 'Scrape content from URL',
|
|
222
|
+
inputSchema: {
|
|
223
|
+
type: 'object',
|
|
224
|
+
properties: {
|
|
225
|
+
url: { type: 'string', description: 'URL to scrape' },
|
|
226
|
+
formats: { type: 'array', description: 'Output formats: markdown, html' },
|
|
227
|
+
},
|
|
228
|
+
required: ['url'],
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
'firecrawl_search': {
|
|
232
|
+
description: 'Search the web via Firecrawl',
|
|
233
|
+
inputSchema: {
|
|
234
|
+
type: 'object',
|
|
235
|
+
properties: {
|
|
236
|
+
query: { type: 'string', description: 'Search query' },
|
|
237
|
+
limit: { type: 'number', description: 'Max results' },
|
|
238
|
+
},
|
|
239
|
+
required: ['query'],
|
|
240
|
+
},
|
|
241
|
+
},
|
|
242
|
+
};
|
|
243
|
+
// ============================================================================
|
|
244
|
+
// Default Config
|
|
245
|
+
// ============================================================================
|
|
246
|
+
const DEFAULT_CONFIG = {
|
|
247
|
+
maxParallel: 5,
|
|
248
|
+
timeout: 60000,
|
|
249
|
+
retries: 2,
|
|
250
|
+
verbose: false,
|
|
251
|
+
};
|
|
252
|
+
// ============================================================================
|
|
253
|
+
// Dispatcher Class
|
|
254
|
+
// ============================================================================
|
|
255
|
+
class ToolDispatcher {
|
|
256
|
+
config;
|
|
257
|
+
executionHistory = [];
|
|
258
|
+
constructor(config) {
|
|
259
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Parse tool calls from LLM response
|
|
263
|
+
*/
|
|
264
|
+
parseToolCalls(response) {
|
|
265
|
+
// If already parsed (from OpenAI-style API)
|
|
266
|
+
if (Array.isArray(response)) {
|
|
267
|
+
return response.map(call => this.parseLLMToolCall(call));
|
|
268
|
+
}
|
|
269
|
+
// Parse from text (XML-style)
|
|
270
|
+
return this.parseXMLToolCalls(response);
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Parse OpenAI-style tool call
|
|
274
|
+
*/
|
|
275
|
+
parseLLMToolCall(call) {
|
|
276
|
+
const name = call.function.name;
|
|
277
|
+
let params = {};
|
|
278
|
+
try {
|
|
279
|
+
params = JSON.parse(call.function.arguments);
|
|
280
|
+
}
|
|
281
|
+
catch {
|
|
282
|
+
// Invalid JSON, use empty params
|
|
283
|
+
}
|
|
284
|
+
return {
|
|
285
|
+
id: call.id,
|
|
286
|
+
name,
|
|
287
|
+
params,
|
|
288
|
+
...this.routeTool(name),
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Parse XML-style tool calls from text
|
|
293
|
+
* Example: <tool_use name="bash"><param name="command">ls -la</param></tool_use>
|
|
294
|
+
*/
|
|
295
|
+
parseXMLToolCalls(text) {
|
|
296
|
+
const calls = [];
|
|
297
|
+
// Match <tool_use> or <function_call> or similar patterns
|
|
298
|
+
const patterns = [
|
|
299
|
+
// <tool_use name="...">...</tool_use>
|
|
300
|
+
/<tool_use\s+name="([^"]+)"[^>]*>([\s\S]*?)<\/tool_use>/gi,
|
|
301
|
+
// <invoke name="...">...</invoke>
|
|
302
|
+
/<invoke\s+name="([^"]+)"[^>]*>([\s\S]*?)<\/invoke>/gi,
|
|
303
|
+
// ```tool\n{name: ..., params: {...}}```
|
|
304
|
+
/```tool\s*\n?\{[\s\S]*?"name"\s*:\s*"([^"]+)"[\s\S]*?\}```/gi,
|
|
305
|
+
];
|
|
306
|
+
for (const pattern of patterns) {
|
|
307
|
+
let match;
|
|
308
|
+
while ((match = pattern.exec(text)) !== null) {
|
|
309
|
+
const name = match[1];
|
|
310
|
+
const content = match[2] || '';
|
|
311
|
+
const params = this.parseToolParams(content);
|
|
312
|
+
calls.push({
|
|
313
|
+
id: `call_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
|
314
|
+
name,
|
|
315
|
+
params,
|
|
316
|
+
...this.routeTool(name),
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
// Also check for JSON-style tool calls
|
|
321
|
+
const jsonPattern = /\{\s*"tool"\s*:\s*"([^"]+)"\s*,\s*"params"\s*:\s*(\{[^}]+\})\s*\}/gi;
|
|
322
|
+
let jsonMatch;
|
|
323
|
+
while ((jsonMatch = jsonPattern.exec(text)) !== null) {
|
|
324
|
+
try {
|
|
325
|
+
const name = jsonMatch[1];
|
|
326
|
+
const params = JSON.parse(jsonMatch[2]);
|
|
327
|
+
calls.push({
|
|
328
|
+
id: `call_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
|
329
|
+
name,
|
|
330
|
+
params,
|
|
331
|
+
...this.routeTool(name),
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
catch {
|
|
335
|
+
// Invalid JSON, skip
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
return calls;
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Parse params from tool content
|
|
342
|
+
*/
|
|
343
|
+
parseToolParams(content) {
|
|
344
|
+
const params = {};
|
|
345
|
+
// Try JSON first
|
|
346
|
+
try {
|
|
347
|
+
const trimmed = content.trim();
|
|
348
|
+
if (trimmed.startsWith('{')) {
|
|
349
|
+
return JSON.parse(trimmed);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
catch {
|
|
353
|
+
// Not JSON, continue with XML parsing
|
|
354
|
+
}
|
|
355
|
+
// Parse <param name="...">value</param> OR <parameter name="...">value</parameter>
|
|
356
|
+
// v7.3.2: Support both tag formats (system prompt uses <parameter>, some parsers expect <param>)
|
|
357
|
+
const paramPattern = /<param(?:eter)?\s+name="([^"]+)"[^>]*>([\s\S]*?)<\/param(?:eter)?>/gi;
|
|
358
|
+
let match;
|
|
359
|
+
while ((match = paramPattern.exec(content)) !== null) {
|
|
360
|
+
const name = match[1];
|
|
361
|
+
let value = match[2].trim();
|
|
362
|
+
// Try to parse as JSON if it looks like an object/array
|
|
363
|
+
if (value.startsWith('{') || value.startsWith('[')) {
|
|
364
|
+
try {
|
|
365
|
+
value = JSON.parse(value);
|
|
366
|
+
}
|
|
367
|
+
catch {
|
|
368
|
+
// Keep as string
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
// Try to parse as number
|
|
372
|
+
else if (!isNaN(Number(value))) {
|
|
373
|
+
value = Number(value);
|
|
374
|
+
}
|
|
375
|
+
// Try to parse as boolean
|
|
376
|
+
else if (value === 'true' || value === 'false') {
|
|
377
|
+
value = value === 'true';
|
|
378
|
+
}
|
|
379
|
+
params[name] = value;
|
|
380
|
+
}
|
|
381
|
+
// If no params found, treat whole content as 'input'
|
|
382
|
+
if (Object.keys(params).length === 0 && content.trim()) {
|
|
383
|
+
params.input = content.trim();
|
|
384
|
+
}
|
|
385
|
+
return params;
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Route tool to local or MCP
|
|
389
|
+
*/
|
|
390
|
+
routeTool(name) {
|
|
391
|
+
// Check local tools first
|
|
392
|
+
if (LOCAL_TOOLS.includes(name) || index_js_1.toolRegistry.has(name)) {
|
|
393
|
+
return { source: 'local' };
|
|
394
|
+
}
|
|
395
|
+
// Check MCP tools
|
|
396
|
+
const mcpServer = MCP_TOOL_MAP[name];
|
|
397
|
+
if (mcpServer) {
|
|
398
|
+
return { source: 'mcp', mcpServer };
|
|
399
|
+
}
|
|
400
|
+
// Default to local (will fail gracefully if not found)
|
|
401
|
+
return { source: 'local' };
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Execute tool calls
|
|
405
|
+
*/
|
|
406
|
+
async dispatch(calls) {
|
|
407
|
+
const startTime = Date.now();
|
|
408
|
+
const results = [];
|
|
409
|
+
let parallelCount = 0;
|
|
410
|
+
let sequentialCount = 0;
|
|
411
|
+
this.progress({ phase: 'validating', current: 0, total: calls.length });
|
|
412
|
+
// Validate all calls first
|
|
413
|
+
const validCalls = [];
|
|
414
|
+
for (const call of calls) {
|
|
415
|
+
const validation = this.validateCall(call);
|
|
416
|
+
if (!validation.valid) {
|
|
417
|
+
results.push({
|
|
418
|
+
callId: call.id,
|
|
419
|
+
name: call.name,
|
|
420
|
+
success: false,
|
|
421
|
+
error: validation.reason,
|
|
422
|
+
duration: 0,
|
|
423
|
+
source: call.source,
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
else {
|
|
427
|
+
validCalls.push(call);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
// Group by dependencies (for now, all parallel)
|
|
431
|
+
const groups = this.groupByDependencies(validCalls);
|
|
432
|
+
// Execute each group
|
|
433
|
+
for (let i = 0; i < groups.length; i++) {
|
|
434
|
+
const group = groups[i];
|
|
435
|
+
if (group.length > 1) {
|
|
436
|
+
parallelCount++;
|
|
437
|
+
}
|
|
438
|
+
else {
|
|
439
|
+
sequentialCount++;
|
|
440
|
+
}
|
|
441
|
+
this.progress({
|
|
442
|
+
phase: 'executing',
|
|
443
|
+
current: i + 1,
|
|
444
|
+
total: groups.length,
|
|
445
|
+
message: `Executing group ${i + 1}/${groups.length} (${group.length} tools)`,
|
|
446
|
+
});
|
|
447
|
+
// Execute group in parallel
|
|
448
|
+
const groupResults = await Promise.all(group.map(call => this.executeCall(call)));
|
|
449
|
+
results.push(...groupResults);
|
|
450
|
+
}
|
|
451
|
+
const totalDuration = Date.now() - startTime;
|
|
452
|
+
this.executionHistory.push(...results);
|
|
453
|
+
this.progress({ phase: 'complete', current: calls.length, total: calls.length });
|
|
454
|
+
return {
|
|
455
|
+
success: results.every(r => r.success),
|
|
456
|
+
results,
|
|
457
|
+
totalDuration,
|
|
458
|
+
parallelExecutions: parallelCount,
|
|
459
|
+
sequentialExecutions: sequentialCount,
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Validate a tool call
|
|
464
|
+
*/
|
|
465
|
+
validateCall(call) {
|
|
466
|
+
// Check if tool exists
|
|
467
|
+
if (call.source === 'local') {
|
|
468
|
+
const tool = index_js_1.toolRegistry.get(call.name);
|
|
469
|
+
if (!tool) {
|
|
470
|
+
return { valid: false, reason: `Unknown tool: ${call.name}` };
|
|
471
|
+
}
|
|
472
|
+
// Run tool-specific validation
|
|
473
|
+
if (tool.validate) {
|
|
474
|
+
return tool.validate(call.params);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
else if (call.source === 'mcp') {
|
|
478
|
+
if (!call.mcpServer) {
|
|
479
|
+
return { valid: false, reason: `No MCP server for tool: ${call.name}` };
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
return { valid: true };
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Group calls by dependencies
|
|
486
|
+
* For now, all calls are independent and can run in parallel
|
|
487
|
+
*/
|
|
488
|
+
groupByDependencies(calls) {
|
|
489
|
+
// Simple grouping: max N parallel
|
|
490
|
+
const groups = [];
|
|
491
|
+
for (let i = 0; i < calls.length; i += this.config.maxParallel) {
|
|
492
|
+
groups.push(calls.slice(i, i + this.config.maxParallel));
|
|
493
|
+
}
|
|
494
|
+
return groups;
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Execute a single tool call
|
|
498
|
+
*/
|
|
499
|
+
async executeCall(call) {
|
|
500
|
+
const startTime = Date.now();
|
|
501
|
+
try {
|
|
502
|
+
if (this.config.verbose) {
|
|
503
|
+
console.log(` Executing: ${call.name}`);
|
|
504
|
+
}
|
|
505
|
+
let data;
|
|
506
|
+
if (call.source === 'local') {
|
|
507
|
+
data = await this.executeLocalTool(call);
|
|
508
|
+
}
|
|
509
|
+
else {
|
|
510
|
+
data = await this.executeMCPTool(call);
|
|
511
|
+
}
|
|
512
|
+
return {
|
|
513
|
+
callId: call.id,
|
|
514
|
+
name: call.name,
|
|
515
|
+
success: true,
|
|
516
|
+
data,
|
|
517
|
+
duration: Date.now() - startTime,
|
|
518
|
+
source: call.source,
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
catch (error) {
|
|
522
|
+
return {
|
|
523
|
+
callId: call.id,
|
|
524
|
+
name: call.name,
|
|
525
|
+
success: false,
|
|
526
|
+
error: error instanceof Error ? error.message : String(error),
|
|
527
|
+
duration: Date.now() - startTime,
|
|
528
|
+
source: call.source,
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* Execute local tool
|
|
534
|
+
*/
|
|
535
|
+
async executeLocalTool(call) {
|
|
536
|
+
const tool = index_js_1.toolRegistry.get(call.name);
|
|
537
|
+
if (!tool) {
|
|
538
|
+
throw new Error(`Tool not found: ${call.name}`);
|
|
539
|
+
}
|
|
540
|
+
return tool.execute(call.params);
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* Execute MCP tool
|
|
544
|
+
*/
|
|
545
|
+
async executeMCPTool(call) {
|
|
546
|
+
if (!call.mcpServer) {
|
|
547
|
+
throw new Error(`No MCP server for tool: ${call.name}`);
|
|
548
|
+
}
|
|
549
|
+
const client = (0, index_js_2.getMCPClient)();
|
|
550
|
+
const result = await client.call(call.mcpServer, call.name, call.params);
|
|
551
|
+
if (!result.success) {
|
|
552
|
+
throw new Error(result.error || 'MCP call failed');
|
|
553
|
+
}
|
|
554
|
+
return result.data;
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* Report progress
|
|
558
|
+
*/
|
|
559
|
+
progress(status) {
|
|
560
|
+
if (this.config.onProgress) {
|
|
561
|
+
this.config.onProgress(status);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* Get execution history
|
|
566
|
+
*/
|
|
567
|
+
getHistory() {
|
|
568
|
+
return [...this.executionHistory];
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Clear history
|
|
572
|
+
*/
|
|
573
|
+
clearHistory() {
|
|
574
|
+
this.executionHistory = [];
|
|
575
|
+
}
|
|
576
|
+
/**
|
|
577
|
+
* Update config
|
|
578
|
+
*/
|
|
579
|
+
updateConfig(updates) {
|
|
580
|
+
this.config = { ...this.config, ...updates };
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
* Get available tools (names only, for backward compatibility)
|
|
584
|
+
*/
|
|
585
|
+
listTools() {
|
|
586
|
+
const local = Array.from(index_js_1.toolRegistry.keys());
|
|
587
|
+
const mcp = {};
|
|
588
|
+
for (const [tool, server] of Object.entries(MCP_TOOL_MAP)) {
|
|
589
|
+
if (!mcp[server]) {
|
|
590
|
+
mcp[server] = [];
|
|
591
|
+
}
|
|
592
|
+
mcp[server].push(tool);
|
|
593
|
+
}
|
|
594
|
+
return { local, mcp };
|
|
595
|
+
}
|
|
596
|
+
/**
|
|
597
|
+
* Get available tools with schemas (for dynamic prompt building)
|
|
598
|
+
* Returns tool definitions with name, description, and inputSchema
|
|
599
|
+
* Note: This is the sync version with static fallbacks - use discoverToolsWithSchemas() for real schemas
|
|
600
|
+
*/
|
|
601
|
+
listToolsWithSchemas() {
|
|
602
|
+
// Local tools with basic info from registry
|
|
603
|
+
const local = Array.from(index_js_1.toolRegistry.entries()).map(([name, tool]) => ({
|
|
604
|
+
name,
|
|
605
|
+
description: tool.description,
|
|
606
|
+
}));
|
|
607
|
+
// MCP tools - use static fallback schemas
|
|
608
|
+
const mcp = {};
|
|
609
|
+
for (const [tool, server] of Object.entries(MCP_TOOL_MAP)) {
|
|
610
|
+
if (!mcp[server]) {
|
|
611
|
+
mcp[server] = [];
|
|
612
|
+
}
|
|
613
|
+
mcp[server].push({ name: tool, ...STATIC_TOOL_SCHEMAS[tool] });
|
|
614
|
+
}
|
|
615
|
+
return { local, mcp };
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* v7.3: Discover tools with REAL schemas from MCP servers
|
|
619
|
+
* Falls back to static schemas for servers that fail to connect
|
|
620
|
+
*/
|
|
621
|
+
async discoverToolsWithSchemas() {
|
|
622
|
+
const local = Array.from(index_js_1.toolRegistry.entries()).map(([name, tool]) => ({
|
|
623
|
+
name,
|
|
624
|
+
description: tool.description,
|
|
625
|
+
}));
|
|
626
|
+
// Try to get real schemas from MCP client
|
|
627
|
+
const client = (0, index_js_2.getMCPClient)();
|
|
628
|
+
let realSchemas = {};
|
|
629
|
+
try {
|
|
630
|
+
realSchemas = await client.discoverAllTools();
|
|
631
|
+
}
|
|
632
|
+
catch {
|
|
633
|
+
// Fall back to static schemas
|
|
634
|
+
console.log('[Dispatcher] Failed to discover MCP tools, using static schemas');
|
|
635
|
+
}
|
|
636
|
+
// Merge real schemas with static fallbacks
|
|
637
|
+
const mcp = {};
|
|
638
|
+
for (const [tool, server] of Object.entries(MCP_TOOL_MAP)) {
|
|
639
|
+
if (!mcp[server]) {
|
|
640
|
+
mcp[server] = realSchemas[server] || [];
|
|
641
|
+
}
|
|
642
|
+
// If tool not in real schemas, add static fallback
|
|
643
|
+
if (!mcp[server].find(t => t.name === tool)) {
|
|
644
|
+
mcp[server].push({ name: tool, ...STATIC_TOOL_SCHEMAS[tool] });
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
return { local, mcp };
|
|
648
|
+
}
|
|
649
|
+
/**
|
|
650
|
+
* Format results for LLM context
|
|
651
|
+
*/
|
|
652
|
+
formatResultsForLLM(results) {
|
|
653
|
+
const lines = ['<tool_results>'];
|
|
654
|
+
for (const result of results) {
|
|
655
|
+
lines.push(`<result name="${result.name}" success="${result.success}">`);
|
|
656
|
+
if (result.success) {
|
|
657
|
+
const data = typeof result.data === 'string'
|
|
658
|
+
? result.data
|
|
659
|
+
: JSON.stringify(result.data, null, 2);
|
|
660
|
+
lines.push(data);
|
|
661
|
+
}
|
|
662
|
+
else {
|
|
663
|
+
lines.push(`Error: ${result.error}`);
|
|
664
|
+
}
|
|
665
|
+
lines.push('</result>');
|
|
666
|
+
}
|
|
667
|
+
lines.push('</tool_results>');
|
|
668
|
+
return lines.join('\n');
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
exports.ToolDispatcher = ToolDispatcher;
|
|
672
|
+
// ============================================================================
|
|
673
|
+
// Singleton
|
|
674
|
+
// ============================================================================
|
|
675
|
+
let dispatcherInstance = null;
|
|
676
|
+
function getDispatcher(config) {
|
|
677
|
+
if (!dispatcherInstance) {
|
|
678
|
+
dispatcherInstance = new ToolDispatcher(config);
|
|
679
|
+
}
|
|
680
|
+
else if (config) {
|
|
681
|
+
dispatcherInstance.updateConfig(config);
|
|
682
|
+
}
|
|
683
|
+
return dispatcherInstance;
|
|
684
|
+
}
|
|
685
|
+
function resetDispatcher() {
|
|
686
|
+
dispatcherInstance = null;
|
|
687
|
+
}
|
|
688
|
+
// ============================================================================
|
|
689
|
+
// Convenience Functions
|
|
690
|
+
// ============================================================================
|
|
691
|
+
/**
|
|
692
|
+
* Parse and dispatch tool calls from LLM response
|
|
693
|
+
*/
|
|
694
|
+
async function dispatchTools(response, config) {
|
|
695
|
+
const dispatcher = getDispatcher(config);
|
|
696
|
+
const calls = dispatcher.parseToolCalls(response);
|
|
697
|
+
return dispatcher.dispatch(calls);
|
|
698
|
+
}
|
|
699
|
+
/**
|
|
700
|
+
* Execute a single tool by name
|
|
701
|
+
*/
|
|
702
|
+
async function executeTool(name, params) {
|
|
703
|
+
const dispatcher = getDispatcher();
|
|
704
|
+
const call = {
|
|
705
|
+
id: `call_${Date.now()}`,
|
|
706
|
+
name,
|
|
707
|
+
params,
|
|
708
|
+
...dispatcher['routeTool'](name),
|
|
709
|
+
};
|
|
710
|
+
const result = await dispatcher.dispatch([call]);
|
|
711
|
+
return result.results[0];
|
|
712
|
+
}
|
|
713
|
+
/**
|
|
714
|
+
* List all available tools
|
|
715
|
+
*/
|
|
716
|
+
function listAllTools() {
|
|
717
|
+
return getDispatcher().listTools();
|
|
718
|
+
}
|