cmdr-agent 1.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/LICENSE +21 -0
- package/README.md +238 -0
- package/dist/bin/cmdr.d.ts +9 -0
- package/dist/bin/cmdr.d.ts.map +1 -0
- package/dist/bin/cmdr.js +49 -0
- package/dist/bin/cmdr.js.map +1 -0
- package/dist/src/cli/args.d.ts +19 -0
- package/dist/src/cli/args.d.ts.map +1 -0
- package/dist/src/cli/args.js +89 -0
- package/dist/src/cli/args.js.map +1 -0
- package/dist/src/cli/commands.d.ts +12 -0
- package/dist/src/cli/commands.d.ts.map +1 -0
- package/dist/src/cli/commands.js +400 -0
- package/dist/src/cli/commands.js.map +1 -0
- package/dist/src/cli/renderer.d.ts +8 -0
- package/dist/src/cli/renderer.d.ts.map +1 -0
- package/dist/src/cli/renderer.js +47 -0
- package/dist/src/cli/renderer.js.map +1 -0
- package/dist/src/cli/repl.d.ts +18 -0
- package/dist/src/cli/repl.d.ts.map +1 -0
- package/dist/src/cli/repl.js +751 -0
- package/dist/src/cli/repl.js.map +1 -0
- package/dist/src/cli/spinner.d.ts +16 -0
- package/dist/src/cli/spinner.d.ts.map +1 -0
- package/dist/src/cli/spinner.js +233 -0
- package/dist/src/cli/spinner.js.map +1 -0
- package/dist/src/cli/theme.d.ts +95 -0
- package/dist/src/cli/theme.d.ts.map +1 -0
- package/dist/src/cli/theme.js +178 -0
- package/dist/src/cli/theme.js.map +1 -0
- package/dist/src/communication/message-bus.d.ts +35 -0
- package/dist/src/communication/message-bus.d.ts.map +1 -0
- package/dist/src/communication/message-bus.js +60 -0
- package/dist/src/communication/message-bus.js.map +1 -0
- package/dist/src/communication/shared-memory.d.ts +19 -0
- package/dist/src/communication/shared-memory.d.ts.map +1 -0
- package/dist/src/communication/shared-memory.js +37 -0
- package/dist/src/communication/shared-memory.js.map +1 -0
- package/dist/src/communication/task-queue.d.ts +50 -0
- package/dist/src/communication/task-queue.d.ts.map +1 -0
- package/dist/src/communication/task-queue.js +158 -0
- package/dist/src/communication/task-queue.js.map +1 -0
- package/dist/src/config/config-loader.d.ts +23 -0
- package/dist/src/config/config-loader.d.ts.map +1 -0
- package/dist/src/config/config-loader.js +91 -0
- package/dist/src/config/config-loader.js.map +1 -0
- package/dist/src/config/defaults.d.ts +6 -0
- package/dist/src/config/defaults.d.ts.map +1 -0
- package/dist/src/config/defaults.js +21 -0
- package/dist/src/config/defaults.js.map +1 -0
- package/dist/src/config/schema.d.ts +135 -0
- package/dist/src/config/schema.d.ts.map +1 -0
- package/dist/src/config/schema.js +35 -0
- package/dist/src/config/schema.js.map +1 -0
- package/dist/src/config/telemetry.d.ts +41 -0
- package/dist/src/config/telemetry.d.ts.map +1 -0
- package/dist/src/config/telemetry.js +57 -0
- package/dist/src/config/telemetry.js.map +1 -0
- package/dist/src/core/agent-pool.d.ts +40 -0
- package/dist/src/core/agent-pool.d.ts.map +1 -0
- package/dist/src/core/agent-pool.js +66 -0
- package/dist/src/core/agent-pool.js.map +1 -0
- package/dist/src/core/agent-runner.d.ts +51 -0
- package/dist/src/core/agent-runner.d.ts.map +1 -0
- package/dist/src/core/agent-runner.js +251 -0
- package/dist/src/core/agent-runner.js.map +1 -0
- package/dist/src/core/agent.d.ts +34 -0
- package/dist/src/core/agent.d.ts.map +1 -0
- package/dist/src/core/agent.js +143 -0
- package/dist/src/core/agent.js.map +1 -0
- package/dist/src/core/intent.d.ts +33 -0
- package/dist/src/core/intent.d.ts.map +1 -0
- package/dist/src/core/intent.js +91 -0
- package/dist/src/core/intent.js.map +1 -0
- package/dist/src/core/orchestrator.d.ts +43 -0
- package/dist/src/core/orchestrator.d.ts.map +1 -0
- package/dist/src/core/orchestrator.js +115 -0
- package/dist/src/core/orchestrator.js.map +1 -0
- package/dist/src/core/permissions.d.ts +36 -0
- package/dist/src/core/permissions.d.ts.map +1 -0
- package/dist/src/core/permissions.js +129 -0
- package/dist/src/core/permissions.js.map +1 -0
- package/dist/src/core/presets.d.ts +12 -0
- package/dist/src/core/presets.d.ts.map +1 -0
- package/dist/src/core/presets.js +148 -0
- package/dist/src/core/presets.js.map +1 -0
- package/dist/src/core/team.d.ts +44 -0
- package/dist/src/core/team.d.ts.map +1 -0
- package/dist/src/core/team.js +156 -0
- package/dist/src/core/team.js.map +1 -0
- package/dist/src/core/types.d.ts +257 -0
- package/dist/src/core/types.d.ts.map +1 -0
- package/dist/src/core/types.js +7 -0
- package/dist/src/core/types.js.map +1 -0
- package/dist/src/index.d.ts +44 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +45 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/llm/adapter.d.ts +5 -0
- package/dist/src/llm/adapter.d.ts.map +1 -0
- package/dist/src/llm/adapter.js +5 -0
- package/dist/src/llm/adapter.js.map +1 -0
- package/dist/src/llm/model-registry.d.ts +14 -0
- package/dist/src/llm/model-registry.d.ts.map +1 -0
- package/dist/src/llm/model-registry.js +30 -0
- package/dist/src/llm/model-registry.js.map +1 -0
- package/dist/src/llm/ollama.d.ts +26 -0
- package/dist/src/llm/ollama.d.ts.map +1 -0
- package/dist/src/llm/ollama.js +375 -0
- package/dist/src/llm/ollama.js.map +1 -0
- package/dist/src/llm/token-counter.d.ts +11 -0
- package/dist/src/llm/token-counter.d.ts.map +1 -0
- package/dist/src/llm/token-counter.js +35 -0
- package/dist/src/llm/token-counter.js.map +1 -0
- package/dist/src/plugins/mcp-client.d.ts +38 -0
- package/dist/src/plugins/mcp-client.d.ts.map +1 -0
- package/dist/src/plugins/mcp-client.js +113 -0
- package/dist/src/plugins/mcp-client.js.map +1 -0
- package/dist/src/plugins/plugin-manager.d.ts +37 -0
- package/dist/src/plugins/plugin-manager.d.ts.map +1 -0
- package/dist/src/plugins/plugin-manager.js +146 -0
- package/dist/src/plugins/plugin-manager.js.map +1 -0
- package/dist/src/scheduling/semaphore.d.ts +20 -0
- package/dist/src/scheduling/semaphore.d.ts.map +1 -0
- package/dist/src/scheduling/semaphore.js +52 -0
- package/dist/src/scheduling/semaphore.js.map +1 -0
- package/dist/src/scheduling/strategies.d.ts +39 -0
- package/dist/src/scheduling/strategies.d.ts.map +1 -0
- package/dist/src/scheduling/strategies.js +88 -0
- package/dist/src/scheduling/strategies.js.map +1 -0
- package/dist/src/session/compaction.d.ts +32 -0
- package/dist/src/session/compaction.d.ts.map +1 -0
- package/dist/src/session/compaction.js +172 -0
- package/dist/src/session/compaction.js.map +1 -0
- package/dist/src/session/cost-tracker.d.ts +41 -0
- package/dist/src/session/cost-tracker.d.ts.map +1 -0
- package/dist/src/session/cost-tracker.js +76 -0
- package/dist/src/session/cost-tracker.js.map +1 -0
- package/dist/src/session/project-context.d.ts +6 -0
- package/dist/src/session/project-context.d.ts.map +1 -0
- package/dist/src/session/project-context.js +147 -0
- package/dist/src/session/project-context.js.map +1 -0
- package/dist/src/session/prompt-builder.d.ts +11 -0
- package/dist/src/session/prompt-builder.d.ts.map +1 -0
- package/dist/src/session/prompt-builder.js +30 -0
- package/dist/src/session/prompt-builder.js.map +1 -0
- package/dist/src/session/session-manager.d.ts +32 -0
- package/dist/src/session/session-manager.d.ts.map +1 -0
- package/dist/src/session/session-manager.js +84 -0
- package/dist/src/session/session-manager.js.map +1 -0
- package/dist/src/session/session-persistence.d.ts +44 -0
- package/dist/src/session/session-persistence.d.ts.map +1 -0
- package/dist/src/session/session-persistence.js +150 -0
- package/dist/src/session/session-persistence.js.map +1 -0
- package/dist/src/session/undo-manager.d.ts +35 -0
- package/dist/src/session/undo-manager.d.ts.map +1 -0
- package/dist/src/session/undo-manager.js +79 -0
- package/dist/src/session/undo-manager.js.map +1 -0
- package/dist/src/tools/built-in/ask-user.d.ts +7 -0
- package/dist/src/tools/built-in/ask-user.d.ts.map +1 -0
- package/dist/src/tools/built-in/ask-user.js +28 -0
- package/dist/src/tools/built-in/ask-user.js.map +1 -0
- package/dist/src/tools/built-in/bash.d.ts +9 -0
- package/dist/src/tools/built-in/bash.d.ts.map +1 -0
- package/dist/src/tools/built-in/bash.js +67 -0
- package/dist/src/tools/built-in/bash.js.map +1 -0
- package/dist/src/tools/built-in/file-edit.d.ts +9 -0
- package/dist/src/tools/built-in/file-edit.d.ts.map +1 -0
- package/dist/src/tools/built-in/file-edit.js +39 -0
- package/dist/src/tools/built-in/file-edit.js.map +1 -0
- package/dist/src/tools/built-in/file-read.d.ts +9 -0
- package/dist/src/tools/built-in/file-read.d.ts.map +1 -0
- package/dist/src/tools/built-in/file-read.js +41 -0
- package/dist/src/tools/built-in/file-read.js.map +1 -0
- package/dist/src/tools/built-in/file-write.d.ts +8 -0
- package/dist/src/tools/built-in/file-write.d.ts.map +1 -0
- package/dist/src/tools/built-in/file-write.js +29 -0
- package/dist/src/tools/built-in/file-write.js.map +1 -0
- package/dist/src/tools/built-in/git-commit.d.ts +12 -0
- package/dist/src/tools/built-in/git-commit.d.ts.map +1 -0
- package/dist/src/tools/built-in/git-commit.js +96 -0
- package/dist/src/tools/built-in/git-commit.js.map +1 -0
- package/dist/src/tools/built-in/git-diff.d.ts +8 -0
- package/dist/src/tools/built-in/git-diff.d.ts.map +1 -0
- package/dist/src/tools/built-in/git-diff.js +43 -0
- package/dist/src/tools/built-in/git-diff.js.map +1 -0
- package/dist/src/tools/built-in/git-log.d.ts +8 -0
- package/dist/src/tools/built-in/git-log.d.ts.map +1 -0
- package/dist/src/tools/built-in/git-log.js +39 -0
- package/dist/src/tools/built-in/git-log.js.map +1 -0
- package/dist/src/tools/built-in/glob.d.ts +8 -0
- package/dist/src/tools/built-in/glob.d.ts.map +1 -0
- package/dist/src/tools/built-in/glob.js +60 -0
- package/dist/src/tools/built-in/glob.js.map +1 -0
- package/dist/src/tools/built-in/grep.d.ts +9 -0
- package/dist/src/tools/built-in/grep.d.ts.map +1 -0
- package/dist/src/tools/built-in/grep.js +115 -0
- package/dist/src/tools/built-in/grep.js.map +1 -0
- package/dist/src/tools/built-in/index.d.ts +21 -0
- package/dist/src/tools/built-in/index.d.ts.map +1 -0
- package/dist/src/tools/built-in/index.js +30 -0
- package/dist/src/tools/built-in/index.js.map +1 -0
- package/dist/src/tools/built-in/think.d.ts +7 -0
- package/dist/src/tools/built-in/think.d.ts.map +1 -0
- package/dist/src/tools/built-in/think.js +18 -0
- package/dist/src/tools/built-in/think.js.map +1 -0
- package/dist/src/tools/built-in/web-fetch.d.ts +11 -0
- package/dist/src/tools/built-in/web-fetch.d.ts.map +1 -0
- package/dist/src/tools/built-in/web-fetch.js +70 -0
- package/dist/src/tools/built-in/web-fetch.js.map +1 -0
- package/dist/src/tools/executor.d.ts +25 -0
- package/dist/src/tools/executor.d.ts.map +1 -0
- package/dist/src/tools/executor.js +61 -0
- package/dist/src/tools/executor.js.map +1 -0
- package/dist/src/tools/registry.d.ts +25 -0
- package/dist/src/tools/registry.d.ts.map +1 -0
- package/dist/src/tools/registry.js +135 -0
- package/dist/src/tools/registry.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentRunner — the core conversation loop engine for cmdr.
|
|
3
|
+
*
|
|
4
|
+
* Drives: LLM call -> tool extraction -> parallel execution -> tool results -> loop
|
|
5
|
+
*/
|
|
6
|
+
import { classifyIntent, filterToolsByIntent } from './intent.js';
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Helpers
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
function extractText(content) {
|
|
11
|
+
return content
|
|
12
|
+
.filter((b) => b.type === 'text')
|
|
13
|
+
.map(b => b.text)
|
|
14
|
+
.join('');
|
|
15
|
+
}
|
|
16
|
+
function extractToolUseBlocks(content) {
|
|
17
|
+
return content.filter((b) => b.type === 'tool_use');
|
|
18
|
+
}
|
|
19
|
+
function addTokenUsage(a, b) {
|
|
20
|
+
return {
|
|
21
|
+
input_tokens: a.input_tokens + b.input_tokens,
|
|
22
|
+
output_tokens: a.output_tokens + b.output_tokens,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
const ZERO_USAGE = { input_tokens: 0, output_tokens: 0 };
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// AgentRunner
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
export class AgentRunner {
|
|
30
|
+
adapter;
|
|
31
|
+
toolRegistry;
|
|
32
|
+
toolExecutor;
|
|
33
|
+
options;
|
|
34
|
+
permissionManager;
|
|
35
|
+
maxTurns;
|
|
36
|
+
constructor(adapter, toolRegistry, toolExecutor, options, permissionManager) {
|
|
37
|
+
this.adapter = adapter;
|
|
38
|
+
this.toolRegistry = toolRegistry;
|
|
39
|
+
this.toolExecutor = toolExecutor;
|
|
40
|
+
this.options = options;
|
|
41
|
+
this.permissionManager = permissionManager;
|
|
42
|
+
this.maxTurns = options.maxTurns ?? 10;
|
|
43
|
+
}
|
|
44
|
+
/** Run a complete conversation, collecting all stream events internally. */
|
|
45
|
+
async run(messages, callbacks = {}) {
|
|
46
|
+
let result = {
|
|
47
|
+
messages: [],
|
|
48
|
+
output: '',
|
|
49
|
+
toolCalls: [],
|
|
50
|
+
tokenUsage: ZERO_USAGE,
|
|
51
|
+
turns: 0,
|
|
52
|
+
};
|
|
53
|
+
for await (const event of this.stream(messages, callbacks)) {
|
|
54
|
+
if (event.type === 'done') {
|
|
55
|
+
result = event.data;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
/** Run the conversation and yield StreamEvents incrementally.
|
|
61
|
+
* Uses the adapter's stream() for real-time token-by-token output. */
|
|
62
|
+
async *stream(initialMessages, callbacks = {}) {
|
|
63
|
+
const conversationMessages = [...initialMessages];
|
|
64
|
+
let totalUsage = ZERO_USAGE;
|
|
65
|
+
const allToolCalls = [];
|
|
66
|
+
let finalOutput = '';
|
|
67
|
+
let turns = 0;
|
|
68
|
+
// Build the full tool set (may be narrowed per-turn by intent)
|
|
69
|
+
const allDefs = this.toolRegistry.toToolDefs();
|
|
70
|
+
const fullToolDefs = this.options.allowedTools
|
|
71
|
+
? allDefs.filter(d => this.options.allowedTools.includes(d.name))
|
|
72
|
+
: allDefs;
|
|
73
|
+
// Extract latest user text for intent classification
|
|
74
|
+
const lastUserMsg = [...conversationMessages]
|
|
75
|
+
.reverse()
|
|
76
|
+
.find(m => m.role === 'user');
|
|
77
|
+
const lastUserText = lastUserMsg
|
|
78
|
+
? lastUserMsg.content
|
|
79
|
+
.filter((b) => b.type === 'text')
|
|
80
|
+
.map(b => b.text)
|
|
81
|
+
.join('')
|
|
82
|
+
: '';
|
|
83
|
+
const intent = classifyIntent(lastUserText);
|
|
84
|
+
try {
|
|
85
|
+
while (true) {
|
|
86
|
+
if (this.options.abortSignal?.aborted)
|
|
87
|
+
break;
|
|
88
|
+
if (turns >= this.maxTurns)
|
|
89
|
+
break;
|
|
90
|
+
turns++;
|
|
91
|
+
// Dynamic tool injection:
|
|
92
|
+
// Turn 1 uses intent-filtered tools (may be empty for chat).
|
|
93
|
+
// Turns 2+ (model is mid-agentic-loop after tool results) get full tools.
|
|
94
|
+
const turnTools = turns === 1
|
|
95
|
+
? filterToolsByIntent(intent, fullToolDefs)
|
|
96
|
+
: fullToolDefs;
|
|
97
|
+
const turnChatOptions = {
|
|
98
|
+
model: this.options.model,
|
|
99
|
+
tools: turnTools.length > 0 ? turnTools : undefined,
|
|
100
|
+
maxTokens: this.options.maxTokens,
|
|
101
|
+
temperature: this.options.temperature,
|
|
102
|
+
systemPrompt: this.options.systemPrompt,
|
|
103
|
+
abortSignal: this.options.abortSignal,
|
|
104
|
+
};
|
|
105
|
+
// Step 1: Stream from LLM — yield text tokens in real-time
|
|
106
|
+
const turnContent = [];
|
|
107
|
+
let turnText = '';
|
|
108
|
+
const pendingToolUse = [];
|
|
109
|
+
let turnUsage = ZERO_USAGE;
|
|
110
|
+
for await (const event of this.adapter.stream(conversationMessages, turnChatOptions)) {
|
|
111
|
+
if (event.type === 'text') {
|
|
112
|
+
const chunk = event.data;
|
|
113
|
+
turnText += chunk;
|
|
114
|
+
yield { type: 'text', data: chunk };
|
|
115
|
+
callbacks.onText?.(chunk);
|
|
116
|
+
}
|
|
117
|
+
else if (event.type === 'tool_use') {
|
|
118
|
+
const block = event.data;
|
|
119
|
+
pendingToolUse.push(block);
|
|
120
|
+
yield { type: 'tool_use', data: block };
|
|
121
|
+
}
|
|
122
|
+
else if (event.type === 'done') {
|
|
123
|
+
const response = event.data;
|
|
124
|
+
turnUsage = response.usage;
|
|
125
|
+
}
|
|
126
|
+
else if (event.type === 'error') {
|
|
127
|
+
yield event;
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
totalUsage = addTokenUsage(totalUsage, turnUsage);
|
|
132
|
+
// Build assistant content blocks
|
|
133
|
+
if (turnText) {
|
|
134
|
+
turnContent.push({ type: 'text', text: turnText });
|
|
135
|
+
}
|
|
136
|
+
for (const block of pendingToolUse) {
|
|
137
|
+
turnContent.push(block);
|
|
138
|
+
}
|
|
139
|
+
// Step 2: Build assistant message
|
|
140
|
+
const assistantMessage = {
|
|
141
|
+
role: 'assistant',
|
|
142
|
+
content: turnContent,
|
|
143
|
+
};
|
|
144
|
+
conversationMessages.push(assistantMessage);
|
|
145
|
+
callbacks.onMessage?.(assistantMessage);
|
|
146
|
+
// Step 3: No tools? We're done.
|
|
147
|
+
if (pendingToolUse.length === 0) {
|
|
148
|
+
finalOutput = turnText;
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
// Step 4: Execute all tool calls in parallel
|
|
152
|
+
const toolContext = {
|
|
153
|
+
agent: {
|
|
154
|
+
name: this.options.agentName ?? 'cmdr',
|
|
155
|
+
role: this.options.agentRole ?? 'assistant',
|
|
156
|
+
model: this.options.model,
|
|
157
|
+
},
|
|
158
|
+
cwd: this.options.cwd,
|
|
159
|
+
abortSignal: this.options.abortSignal,
|
|
160
|
+
};
|
|
161
|
+
const executionPromises = pendingToolUse.map(async (block) => {
|
|
162
|
+
callbacks.onToolCall?.(block.name, block.input);
|
|
163
|
+
// --- HITL gate: check permissions before executing ---
|
|
164
|
+
if (this.permissionManager && callbacks.onToolApproval) {
|
|
165
|
+
const decision = await this.permissionManager.gate(block.name, block.input, callbacks.onToolApproval);
|
|
166
|
+
if (decision === 'deny') {
|
|
167
|
+
const deniedResult = {
|
|
168
|
+
data: `Tool "${block.name}" was denied by the user.`,
|
|
169
|
+
isError: true,
|
|
170
|
+
};
|
|
171
|
+
callbacks.onToolResult?.(block.name, deniedResult);
|
|
172
|
+
const resultBlock = {
|
|
173
|
+
type: 'tool_result',
|
|
174
|
+
tool_use_id: block.id,
|
|
175
|
+
content: deniedResult.data,
|
|
176
|
+
is_error: true,
|
|
177
|
+
};
|
|
178
|
+
return { resultBlock, record: {
|
|
179
|
+
toolName: block.name,
|
|
180
|
+
input: block.input,
|
|
181
|
+
output: deniedResult.data,
|
|
182
|
+
duration: 0,
|
|
183
|
+
} };
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
const startTime = Date.now();
|
|
187
|
+
let result;
|
|
188
|
+
try {
|
|
189
|
+
result = await this.toolExecutor.execute(block.name, block.input, toolContext);
|
|
190
|
+
}
|
|
191
|
+
catch (err) {
|
|
192
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
193
|
+
result = { data: message, isError: true };
|
|
194
|
+
}
|
|
195
|
+
const duration = Date.now() - startTime;
|
|
196
|
+
callbacks.onToolResult?.(block.name, result);
|
|
197
|
+
const record = {
|
|
198
|
+
toolName: block.name,
|
|
199
|
+
input: block.input,
|
|
200
|
+
output: result.data,
|
|
201
|
+
duration,
|
|
202
|
+
};
|
|
203
|
+
const resultBlock = {
|
|
204
|
+
type: 'tool_result',
|
|
205
|
+
tool_use_id: block.id,
|
|
206
|
+
content: result.data,
|
|
207
|
+
is_error: result.isError,
|
|
208
|
+
};
|
|
209
|
+
return { resultBlock, record };
|
|
210
|
+
});
|
|
211
|
+
const executions = await Promise.all(executionPromises);
|
|
212
|
+
// Step 5: Accumulate results
|
|
213
|
+
const toolResultBlocks = executions.map(e => e.resultBlock);
|
|
214
|
+
for (const { record, resultBlock } of executions) {
|
|
215
|
+
allToolCalls.push(record);
|
|
216
|
+
yield { type: 'tool_result', data: resultBlock };
|
|
217
|
+
}
|
|
218
|
+
const toolResultMessage = {
|
|
219
|
+
role: 'user',
|
|
220
|
+
content: toolResultBlocks,
|
|
221
|
+
};
|
|
222
|
+
conversationMessages.push(toolResultMessage);
|
|
223
|
+
callbacks.onMessage?.(toolResultMessage);
|
|
224
|
+
// Loop back — send updated conversation to LLM
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
catch (err) {
|
|
228
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
229
|
+
yield { type: 'error', data: error };
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
// If loop exited due to maxTurns, use last text
|
|
233
|
+
if (finalOutput === '' && conversationMessages.length > 0) {
|
|
234
|
+
const lastAssistant = [...conversationMessages]
|
|
235
|
+
.reverse()
|
|
236
|
+
.find(m => m.role === 'assistant');
|
|
237
|
+
if (lastAssistant) {
|
|
238
|
+
finalOutput = extractText(lastAssistant.content);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
const runResult = {
|
|
242
|
+
messages: conversationMessages.slice(initialMessages.length),
|
|
243
|
+
output: finalOutput,
|
|
244
|
+
toolCalls: allToolCalls,
|
|
245
|
+
tokenUsage: totalUsage,
|
|
246
|
+
turns,
|
|
247
|
+
};
|
|
248
|
+
yield { type: 'done', data: runResult };
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=agent-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-runner.js","sourceRoot":"","sources":["../../../src/core/agent-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent — high-level wrapper around AgentRunner.
|
|
3
|
+
*
|
|
4
|
+
* Provides persistent conversation (prompt), fresh-conversation (run), and streaming.
|
|
5
|
+
*/
|
|
6
|
+
import type { LLMAdapter, LLMMessage, AgentConfig, AgentState, AgentRunResult, StreamEvent } from './types.js';
|
|
7
|
+
import { type RunCallbacks } from './agent-runner.js';
|
|
8
|
+
import { ToolRegistry } from '../tools/registry.js';
|
|
9
|
+
import type { PermissionManager } from './permissions.js';
|
|
10
|
+
export declare class Agent {
|
|
11
|
+
readonly config: AgentConfig;
|
|
12
|
+
private readonly adapter;
|
|
13
|
+
private readonly toolRegistry;
|
|
14
|
+
private readonly toolExecutor;
|
|
15
|
+
private readonly permissionManager?;
|
|
16
|
+
private state;
|
|
17
|
+
private cwd;
|
|
18
|
+
constructor(config: AgentConfig, adapter: LLMAdapter, toolRegistry: ToolRegistry, cwd?: string, permissionManager?: PermissionManager);
|
|
19
|
+
/** Fresh conversation — does not carry history. */
|
|
20
|
+
run(task: string, callbacks?: RunCallbacks): Promise<AgentRunResult>;
|
|
21
|
+
/** Persistent conversation — appends to history. */
|
|
22
|
+
prompt(message: string, callbacks?: RunCallbacks): Promise<AgentRunResult>;
|
|
23
|
+
/** Streaming prompt — yields events in real time. */
|
|
24
|
+
stream(message: string, callbacks?: RunCallbacks): AsyncGenerator<StreamEvent>;
|
|
25
|
+
getState(): AgentState;
|
|
26
|
+
getHistory(): LLMMessage[];
|
|
27
|
+
reset(): void;
|
|
28
|
+
/** Replace internal message history (used after compaction). */
|
|
29
|
+
replaceMessages(messages: LLMMessage[]): void;
|
|
30
|
+
setCwd(cwd: string): void;
|
|
31
|
+
private createRunner;
|
|
32
|
+
private toAgentResult;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../../src/core/agent.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAC/C,cAAc,EAAc,WAAW,EACxC,MAAM,YAAY,CAAA;AACnB,OAAO,EAAe,KAAK,YAAY,EAAkB,MAAM,mBAAmB,CAAA;AAClF,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAEnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAIzD,qBAAa,KAAK;IAChB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;IAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAY;IACpC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAc;IAC3C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAc;IAC3C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAmB;IACtD,OAAO,CAAC,KAAK,CAAY;IACzB,OAAO,CAAC,GAAG,CAAQ;gBAGjB,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,UAAU,EACnB,YAAY,EAAE,YAAY,EAC1B,GAAG,CAAC,EAAE,MAAM,EACZ,iBAAiB,CAAC,EAAE,iBAAiB;IAevC,mDAAmD;IAC7C,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC;IAkB1E,oDAAoD;IAC9C,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC;IA8BhF,qDAAqD;IAC9C,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,YAAY,GAAG,cAAc,CAAC,WAAW,CAAC;IAkCrF,QAAQ,IAAI,UAAU;IACtB,UAAU,IAAI,UAAU,EAAE;IAE1B,KAAK,IAAI,IAAI;IAIb,gEAAgE;IAChE,eAAe,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI;IAI7C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIzB,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,aAAa;CAStB"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent — high-level wrapper around AgentRunner.
|
|
3
|
+
*
|
|
4
|
+
* Provides persistent conversation (prompt), fresh-conversation (run), and streaming.
|
|
5
|
+
*/
|
|
6
|
+
import { AgentRunner } from './agent-runner.js';
|
|
7
|
+
import { ToolExecutor } from '../tools/executor.js';
|
|
8
|
+
const ZERO_USAGE = { input_tokens: 0, output_tokens: 0 };
|
|
9
|
+
export class Agent {
|
|
10
|
+
config;
|
|
11
|
+
adapter;
|
|
12
|
+
toolRegistry;
|
|
13
|
+
toolExecutor;
|
|
14
|
+
permissionManager;
|
|
15
|
+
state;
|
|
16
|
+
cwd;
|
|
17
|
+
constructor(config, adapter, toolRegistry, cwd, permissionManager) {
|
|
18
|
+
this.config = config;
|
|
19
|
+
this.adapter = adapter;
|
|
20
|
+
this.toolRegistry = toolRegistry;
|
|
21
|
+
this.toolExecutor = new ToolExecutor(toolRegistry);
|
|
22
|
+
this.permissionManager = permissionManager;
|
|
23
|
+
this.cwd = cwd ?? process.cwd();
|
|
24
|
+
this.state = {
|
|
25
|
+
status: 'idle',
|
|
26
|
+
messages: [],
|
|
27
|
+
tokenUsage: ZERO_USAGE,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/** Fresh conversation — does not carry history. */
|
|
31
|
+
async run(task, callbacks) {
|
|
32
|
+
const messages = [
|
|
33
|
+
{ role: 'user', content: [{ type: 'text', text: task }] },
|
|
34
|
+
];
|
|
35
|
+
this.state.status = 'running';
|
|
36
|
+
try {
|
|
37
|
+
const runner = this.createRunner();
|
|
38
|
+
const result = await runner.run(messages, callbacks);
|
|
39
|
+
this.state.status = 'completed';
|
|
40
|
+
return this.toAgentResult(result);
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
this.state.status = 'error';
|
|
44
|
+
this.state.error = err instanceof Error ? err : new Error(String(err));
|
|
45
|
+
throw err;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/** Persistent conversation — appends to history. */
|
|
49
|
+
async prompt(message, callbacks) {
|
|
50
|
+
this.state.messages.push({
|
|
51
|
+
role: 'user',
|
|
52
|
+
content: [{ type: 'text', text: message }],
|
|
53
|
+
});
|
|
54
|
+
this.state.status = 'running';
|
|
55
|
+
try {
|
|
56
|
+
const runner = this.createRunner();
|
|
57
|
+
const result = await runner.run(this.state.messages, callbacks);
|
|
58
|
+
// Append new messages to history
|
|
59
|
+
for (const msg of result.messages) {
|
|
60
|
+
this.state.messages.push(msg);
|
|
61
|
+
}
|
|
62
|
+
this.state.tokenUsage = {
|
|
63
|
+
input_tokens: this.state.tokenUsage.input_tokens + result.tokenUsage.input_tokens,
|
|
64
|
+
output_tokens: this.state.tokenUsage.output_tokens + result.tokenUsage.output_tokens,
|
|
65
|
+
};
|
|
66
|
+
this.state.status = 'completed';
|
|
67
|
+
return this.toAgentResult(result);
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
this.state.status = 'error';
|
|
71
|
+
this.state.error = err instanceof Error ? err : new Error(String(err));
|
|
72
|
+
throw err;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/** Streaming prompt — yields events in real time. */
|
|
76
|
+
async *stream(message, callbacks) {
|
|
77
|
+
this.state.messages.push({
|
|
78
|
+
role: 'user',
|
|
79
|
+
content: [{ type: 'text', text: message }],
|
|
80
|
+
});
|
|
81
|
+
this.state.status = 'running';
|
|
82
|
+
const runner = this.createRunner();
|
|
83
|
+
try {
|
|
84
|
+
for await (const event of runner.stream(this.state.messages, callbacks)) {
|
|
85
|
+
yield event;
|
|
86
|
+
if (event.type === 'done') {
|
|
87
|
+
const result = event.data;
|
|
88
|
+
for (const msg of result.messages) {
|
|
89
|
+
this.state.messages.push(msg);
|
|
90
|
+
}
|
|
91
|
+
this.state.tokenUsage = {
|
|
92
|
+
input_tokens: this.state.tokenUsage.input_tokens + result.tokenUsage.input_tokens,
|
|
93
|
+
output_tokens: this.state.tokenUsage.output_tokens + result.tokenUsage.output_tokens,
|
|
94
|
+
};
|
|
95
|
+
this.state.status = 'completed';
|
|
96
|
+
}
|
|
97
|
+
else if (event.type === 'error') {
|
|
98
|
+
this.state.status = 'error';
|
|
99
|
+
this.state.error = event.data;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
this.state.status = 'error';
|
|
105
|
+
this.state.error = err instanceof Error ? err : new Error(String(err));
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
getState() { return { ...this.state }; }
|
|
109
|
+
getHistory() { return [...this.state.messages]; }
|
|
110
|
+
reset() {
|
|
111
|
+
this.state = { status: 'idle', messages: [], tokenUsage: ZERO_USAGE };
|
|
112
|
+
}
|
|
113
|
+
/** Replace internal message history (used after compaction). */
|
|
114
|
+
replaceMessages(messages) {
|
|
115
|
+
this.state.messages = [...messages];
|
|
116
|
+
}
|
|
117
|
+
setCwd(cwd) {
|
|
118
|
+
this.cwd = cwd;
|
|
119
|
+
}
|
|
120
|
+
createRunner() {
|
|
121
|
+
return new AgentRunner(this.adapter, this.toolRegistry, this.toolExecutor, {
|
|
122
|
+
model: this.config.model ?? 'qwen2.5-coder:14b',
|
|
123
|
+
systemPrompt: this.config.systemPrompt,
|
|
124
|
+
maxTurns: this.config.maxTurns ?? 30,
|
|
125
|
+
maxTokens: this.config.maxTokens,
|
|
126
|
+
temperature: this.config.temperature,
|
|
127
|
+
allowedTools: this.config.tools,
|
|
128
|
+
agentName: this.config.name,
|
|
129
|
+
agentRole: 'assistant',
|
|
130
|
+
cwd: this.cwd,
|
|
131
|
+
}, this.permissionManager);
|
|
132
|
+
}
|
|
133
|
+
toAgentResult(result) {
|
|
134
|
+
return {
|
|
135
|
+
success: true,
|
|
136
|
+
output: result.output,
|
|
137
|
+
messages: result.messages,
|
|
138
|
+
tokenUsage: result.tokenUsage,
|
|
139
|
+
toolCalls: result.toolCalls,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../../src/core/agent.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,EAAE,WAAW,EAAqC,MAAM,mBAAmB,CAAA;AAElF,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAGnD,MAAM,UAAU,GAAe,EAAE,YAAY,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,CAAA;AAEpE,MAAM,OAAO,KAAK;IACP,MAAM,CAAa;IACX,OAAO,CAAY;IACnB,YAAY,CAAc;IAC1B,YAAY,CAAc;IAC1B,iBAAiB,CAAoB;IAC9C,KAAK,CAAY;IACjB,GAAG,CAAQ;IAEnB,YACE,MAAmB,EACnB,OAAmB,EACnB,YAA0B,EAC1B,GAAY,EACZ,iBAAqC;QAErC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAA;QAChC,IAAI,CAAC,YAAY,GAAG,IAAI,YAAY,CAAC,YAAY,CAAC,CAAA;QAClD,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAA;QAC1C,IAAI,CAAC,GAAG,GAAG,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;QAC/B,IAAI,CAAC,KAAK,GAAG;YACX,MAAM,EAAE,MAAM;YACd,QAAQ,EAAE,EAAE;YACZ,UAAU,EAAE,UAAU;SACvB,CAAA;IACH,CAAC;IAED,mDAAmD;IACnD,KAAK,CAAC,GAAG,CAAC,IAAY,EAAE,SAAwB;QAC9C,MAAM,QAAQ,GAAiB;YAC7B,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE;SAC1D,CAAA;QAED,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,SAAS,CAAA;QAC7B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,CAAA;YAClC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAA;YACpD,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,WAAW,CAAA;YAC/B,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAA;QACnC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,OAAO,CAAA;YAC3B,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;YACtE,MAAM,GAAG,CAAA;QACX,CAAC;IACH,CAAC;IAED,oDAAoD;IACpD,KAAK,CAAC,MAAM,CAAC,OAAe,EAAE,SAAwB;QACpD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;YACvB,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;SAC3C,CAAC,CAAA;QAEF,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,SAAS,CAAA;QAC7B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,CAAA;YAClC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAA;YAE/D,iCAAiC;YACjC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;gBAClC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YAC/B,CAAC;YAED,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG;gBACtB,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,YAAY,GAAG,MAAM,CAAC,UAAU,CAAC,YAAY;gBACjF,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,aAAa,GAAG,MAAM,CAAC,UAAU,CAAC,aAAa;aACrF,CAAA;YAED,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,WAAW,CAAA;YAC/B,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAA;QACnC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,OAAO,CAAA;YAC3B,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;YACtE,MAAM,GAAG,CAAA;QACX,CAAC;IACH,CAAC;IAED,qDAAqD;IACrD,KAAK,CAAC,CAAC,MAAM,CAAC,OAAe,EAAE,SAAwB;QACrD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;YACvB,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;SAC3C,CAAC,CAAA;QAEF,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,SAAS,CAAA;QAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,CAAA;QAElC,IAAI,CAAC;YACH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,CAAC;gBACxE,MAAM,KAAK,CAAA;gBAEX,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;oBAC1B,MAAM,MAAM,GAAG,KAAK,CAAC,IAAiB,CAAA;oBACtC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;wBAClC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;oBAC/B,CAAC;oBACD,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG;wBACtB,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,YAAY,GAAG,MAAM,CAAC,UAAU,CAAC,YAAY;wBACjF,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,aAAa,GAAG,MAAM,CAAC,UAAU,CAAC,aAAa;qBACrF,CAAA;oBACD,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,WAAW,CAAA;gBACjC,CAAC;qBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBAClC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,OAAO,CAAA;oBAC3B,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,IAAa,CAAA;gBACxC,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,OAAO,CAAA;YAC3B,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;QACxE,CAAC;IACH,CAAC;IAED,QAAQ,KAAiB,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAA,CAAC,CAAC;IACnD,UAAU,KAAmB,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA,CAAC,CAAC;IAE9D,KAAK;QACH,IAAI,CAAC,KAAK,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,CAAA;IACvE,CAAC;IAED,gEAAgE;IAChE,eAAe,CAAC,QAAsB;QACpC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAA;IACrC,CAAC;IAED,MAAM,CAAC,GAAW;QAChB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAA;IAChB,CAAC;IAEO,YAAY;QAClB,OAAO,IAAI,WAAW,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE;YACzE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,mBAAmB;YAC/C,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,YAAY;YACtC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE;YACpC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS;YAChC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW;YACpC,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,KAA6B;YACvD,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;YAC3B,SAAS,EAAE,WAAW;YACtB,GAAG,EAAE,IAAI,CAAC,GAAG;SACd,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAA;IAC5B,CAAC;IAEO,aAAa,CAAC,MAAiB;QACrC,OAAO;YACL,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,SAAS,EAAE,MAAM,CAAC,SAAS;SAC5B,CAAA;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Intent classifier — determines what tools the model should receive
|
|
3
|
+
* based on the user's message.
|
|
4
|
+
*
|
|
5
|
+
* Inspired by claw-code's `simple_mode` pattern: don't tell the model
|
|
6
|
+
* about tools it doesn't need. When someone says "hi", the model gets
|
|
7
|
+
* zero tools, so it physically cannot start running glob/git_log.
|
|
8
|
+
*
|
|
9
|
+
* Three tiers:
|
|
10
|
+
* conversational → no tools (just chat)
|
|
11
|
+
* exploratory → read-only tools (file_read, grep, glob, git_diff, git_log)
|
|
12
|
+
* actionable → full tool suite
|
|
13
|
+
*/
|
|
14
|
+
import type { LLMToolDef } from './types.js';
|
|
15
|
+
export type UserIntent = 'conversational' | 'exploratory' | 'actionable';
|
|
16
|
+
/**
|
|
17
|
+
* Classify the user's latest message to determine tool availability.
|
|
18
|
+
*
|
|
19
|
+
* The classifier is intentionally conservative — when in doubt it
|
|
20
|
+
* escalates to a higher tier (more tools). False negatives (giving
|
|
21
|
+
* tools when not needed) are less harmful than false positives
|
|
22
|
+
* (withholding tools when the user needs them).
|
|
23
|
+
*/
|
|
24
|
+
export declare function classifyIntent(message: string): UserIntent;
|
|
25
|
+
/**
|
|
26
|
+
* Filter tool definitions based on intent.
|
|
27
|
+
*
|
|
28
|
+
* - conversational: returns empty array (no tools)
|
|
29
|
+
* - exploratory: returns only read-only tools
|
|
30
|
+
* - actionable: returns all tools
|
|
31
|
+
*/
|
|
32
|
+
export declare function filterToolsByIntent(intent: UserIntent, allTools: readonly LLMToolDef[]): LLMToolDef[];
|
|
33
|
+
//# sourceMappingURL=intent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intent.d.ts","sourceRoot":"","sources":["../../../src/core/intent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,MAAM,MAAM,UAAU,GAAG,gBAAgB,GAAG,aAAa,GAAG,YAAY,CAAA;AA+BxE;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CA8B1D;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,SAAS,UAAU,EAAE,GAC9B,UAAU,EAAE,CASd"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Intent classifier — determines what tools the model should receive
|
|
3
|
+
* based on the user's message.
|
|
4
|
+
*
|
|
5
|
+
* Inspired by claw-code's `simple_mode` pattern: don't tell the model
|
|
6
|
+
* about tools it doesn't need. When someone says "hi", the model gets
|
|
7
|
+
* zero tools, so it physically cannot start running glob/git_log.
|
|
8
|
+
*
|
|
9
|
+
* Three tiers:
|
|
10
|
+
* conversational → no tools (just chat)
|
|
11
|
+
* exploratory → read-only tools (file_read, grep, glob, git_diff, git_log)
|
|
12
|
+
* actionable → full tool suite
|
|
13
|
+
*/
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// Read-only tool set (exploratory tier)
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
const EXPLORATORY_TOOLS = new Set([
|
|
18
|
+
'file_read',
|
|
19
|
+
'grep',
|
|
20
|
+
'glob',
|
|
21
|
+
'git_diff',
|
|
22
|
+
'git_log',
|
|
23
|
+
'think',
|
|
24
|
+
]);
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// Intent detection heuristics
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
/** Words/phrases that signal the user wants the model to *do* something. */
|
|
29
|
+
const ACTION_SIGNALS = /\b(fix|create|write|edit|add|remove|delete|refactor|implement|build|update|change|modify|rename|move|install|run|execute|deploy|migrate|convert|replace|rewrite|debug|patch|test|commit|push|merge|undo)\b/i;
|
|
30
|
+
/** Words/phrases that signal the user wants to understand something. */
|
|
31
|
+
const EXPLORE_SIGNALS = /\b(what is|what are|explain|describe|show me|how does|how do|where is|where are|find|search|look at|read|list|check|can you show|tell me about|look for|walk me through|overview)\b/i;
|
|
32
|
+
/** Very short messages that are almost certainly conversational. */
|
|
33
|
+
const GREETING_PATTERNS = /^(hi|hey|hello|yo|sup|thanks|thank you|ok|okay|cool|nice|great|good|sure|yep|nope|no|yes|bye|goodbye|cheers|what'?s up|how are you|how'?s it going|hm+|ah+)\b/i;
|
|
34
|
+
/** Questions about the assistant itself — conversational, not actionable. */
|
|
35
|
+
const META_PATTERNS = /\b(who are you|what are you|which model|what model|your name|what can you do|are you|tell me about yourself)\b/i;
|
|
36
|
+
/**
|
|
37
|
+
* Classify the user's latest message to determine tool availability.
|
|
38
|
+
*
|
|
39
|
+
* The classifier is intentionally conservative — when in doubt it
|
|
40
|
+
* escalates to a higher tier (more tools). False negatives (giving
|
|
41
|
+
* tools when not needed) are less harmful than false positives
|
|
42
|
+
* (withholding tools when the user needs them).
|
|
43
|
+
*/
|
|
44
|
+
export function classifyIntent(message) {
|
|
45
|
+
const trimmed = message.trim();
|
|
46
|
+
// Empty or very short greetings → conversational
|
|
47
|
+
if (trimmed.length === 0)
|
|
48
|
+
return 'conversational';
|
|
49
|
+
if (GREETING_PATTERNS.test(trimmed))
|
|
50
|
+
return 'conversational';
|
|
51
|
+
if (META_PATTERNS.test(trimmed))
|
|
52
|
+
return 'conversational';
|
|
53
|
+
// Short messages (< 15 chars) with no action/explore signals → conversational
|
|
54
|
+
if (trimmed.length < 15 && !ACTION_SIGNALS.test(trimmed) && !EXPLORE_SIGNALS.test(trimmed)) {
|
|
55
|
+
return 'conversational';
|
|
56
|
+
}
|
|
57
|
+
// Clear action verbs → full tool suite
|
|
58
|
+
if (ACTION_SIGNALS.test(trimmed))
|
|
59
|
+
return 'actionable';
|
|
60
|
+
// Exploration language → read-only tools
|
|
61
|
+
if (EXPLORE_SIGNALS.test(trimmed))
|
|
62
|
+
return 'exploratory';
|
|
63
|
+
// Messages mentioning file paths or code constructs → actionable
|
|
64
|
+
if (/\.(ts|js|py|rs|go|java|c|cpp|h|json|yaml|yml|toml|md|html|css|sql)\b/.test(trimmed)) {
|
|
65
|
+
return 'actionable';
|
|
66
|
+
}
|
|
67
|
+
// Longer messages without clear signals → default to actionable
|
|
68
|
+
// (conservative: don't withhold tools on ambiguous requests)
|
|
69
|
+
if (trimmed.length >= 40)
|
|
70
|
+
return 'actionable';
|
|
71
|
+
// Medium-length messages that don't match anything → exploratory
|
|
72
|
+
return 'exploratory';
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Filter tool definitions based on intent.
|
|
76
|
+
*
|
|
77
|
+
* - conversational: returns empty array (no tools)
|
|
78
|
+
* - exploratory: returns only read-only tools
|
|
79
|
+
* - actionable: returns all tools
|
|
80
|
+
*/
|
|
81
|
+
export function filterToolsByIntent(intent, allTools) {
|
|
82
|
+
switch (intent) {
|
|
83
|
+
case 'conversational':
|
|
84
|
+
return [];
|
|
85
|
+
case 'exploratory':
|
|
86
|
+
return allTools.filter(t => EXPLORATORY_TOOLS.has(t.name));
|
|
87
|
+
case 'actionable':
|
|
88
|
+
return [...allTools];
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=intent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intent.js","sourceRoot":"","sources":["../../../src/core/intent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,8EAA8E;AAC9E,wCAAwC;AACxC,8EAA8E;AAE9E,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IAChC,WAAW;IACX,MAAM;IACN,MAAM;IACN,UAAU;IACV,SAAS;IACT,OAAO;CACR,CAAC,CAAA;AAEF,8EAA8E;AAC9E,8BAA8B;AAC9B,8EAA8E;AAE9E,4EAA4E;AAC5E,MAAM,cAAc,GAAG,6MAA6M,CAAA;AAEpO,wEAAwE;AACxE,MAAM,eAAe,GAAG,sLAAsL,CAAA;AAE9M,oEAAoE;AACpE,MAAM,iBAAiB,GAAG,gKAAgK,CAAA;AAE1L,6EAA6E;AAC7E,MAAM,aAAa,GAAG,iHAAiH,CAAA;AAEvI;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAA;IAE9B,iDAAiD;IACjD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,gBAAgB,CAAA;IACjD,IAAI,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,gBAAgB,CAAA;IAC5D,IAAI,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,gBAAgB,CAAA;IAExD,8EAA8E;IAC9E,IAAI,OAAO,CAAC,MAAM,GAAG,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3F,OAAO,gBAAgB,CAAA;IACzB,CAAC;IAED,uCAAuC;IACvC,IAAI,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,YAAY,CAAA;IAErD,yCAAyC;IACzC,IAAI,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,aAAa,CAAA;IAEvD,iEAAiE;IACjE,IAAI,sEAAsE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACzF,OAAO,YAAY,CAAA;IACrB,CAAC;IAED,gEAAgE;IAChE,6DAA6D;IAC7D,IAAI,OAAO,CAAC,MAAM,IAAI,EAAE;QAAE,OAAO,YAAY,CAAA;IAE7C,iEAAiE;IACjE,OAAO,aAAa,CAAA;AACtB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAAkB,EAClB,QAA+B;IAE/B,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,gBAAgB;YACnB,OAAO,EAAE,CAAA;QACX,KAAK,aAAa;YAChB,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;QAC5D,KAAK,YAAY;YACf,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAA;IACxB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orchestrator — top-level coordinator for multi-agent workflows.
|
|
3
|
+
*
|
|
4
|
+
* Provides runAgent(), runTeam(), and runTasks() entry points.
|
|
5
|
+
*/
|
|
6
|
+
import type { AgentConfig, AgentRunResult, TeamConfig, TeamRunResult, Task, LLMAdapter, OrchestratorConfig, TokenUsage } from './types.js';
|
|
7
|
+
import type { ToolRegistry } from '../tools/registry.js';
|
|
8
|
+
import type { PermissionManager } from './permissions.js';
|
|
9
|
+
import { Team } from './team.js';
|
|
10
|
+
import { TaskQueue } from '../communication/task-queue.js';
|
|
11
|
+
export declare class Orchestrator {
|
|
12
|
+
private readonly adapter;
|
|
13
|
+
private readonly toolRegistry;
|
|
14
|
+
private readonly config;
|
|
15
|
+
private readonly permissionManager?;
|
|
16
|
+
private readonly cwd;
|
|
17
|
+
private activeTeam?;
|
|
18
|
+
constructor(adapter: LLMAdapter, toolRegistry: ToolRegistry, config?: OrchestratorConfig, cwd?: string, permissionManager?: PermissionManager);
|
|
19
|
+
/** Run a single agent on a task. */
|
|
20
|
+
runAgent(agentConfig: AgentConfig, task: string): Promise<AgentRunResult>;
|
|
21
|
+
/** Run a team on a goal. Returns aggregated results from all agents. */
|
|
22
|
+
runTeam(teamConfig: TeamConfig, goal: string): Promise<TeamRunResult>;
|
|
23
|
+
/**
|
|
24
|
+
* Run a set of tasks with dependency resolution and agent assignment.
|
|
25
|
+
* Uses topological ordering and semaphore-controlled parallelism.
|
|
26
|
+
*/
|
|
27
|
+
runTasks(tasks: Task[], agentConfigs: readonly AgentConfig[]): Promise<{
|
|
28
|
+
results: Map<string, AgentRunResult>;
|
|
29
|
+
totalUsage: TokenUsage;
|
|
30
|
+
}>;
|
|
31
|
+
/** Get the active team (if any). */
|
|
32
|
+
getActiveTeam(): Team | undefined;
|
|
33
|
+
/** Get status of the active team. */
|
|
34
|
+
getStatus(): {
|
|
35
|
+
agents: Array<{
|
|
36
|
+
name: string;
|
|
37
|
+
status: string;
|
|
38
|
+
}>;
|
|
39
|
+
tasks?: ReturnType<TaskQueue['summary']>;
|
|
40
|
+
} | null;
|
|
41
|
+
private emit;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=orchestrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../../src/core/orchestrator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,WAAW,EAAE,cAAc,EAAE,UAAU,EAAE,aAAa,EACtD,IAAI,EAAE,UAAU,EAAE,kBAAkB,EAAqB,UAAU,EACpE,MAAM,YAAY,CAAA;AACnB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAEzD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAA;AAK1D,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAY;IACpC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAc;IAC3C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;IAC3C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAmB;IACtD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAC5B,OAAO,CAAC,UAAU,CAAC,CAAM;gBAGvB,OAAO,EAAE,UAAU,EACnB,YAAY,EAAE,YAAY,EAC1B,MAAM,GAAE,kBAAuB,EAC/B,GAAG,CAAC,EAAE,MAAM,EACZ,iBAAiB,CAAC,EAAE,iBAAiB;IASvC,oCAAoC;IAC9B,QAAQ,CAAC,WAAW,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAgB/E,wEAAwE;IAClE,OAAO,CAAC,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAkB3E;;;OAGG;IACG,QAAQ,CACZ,KAAK,EAAE,IAAI,EAAE,EACb,YAAY,EAAE,SAAS,WAAW,EAAE,GACnC,OAAO,CAAC;QAAE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAAC,UAAU,EAAE,UAAU,CAAA;KAAE,CAAC;IAwD5E,oCAAoC;IACpC,aAAa,IAAI,IAAI,GAAG,SAAS;IAIjC,qCAAqC;IACrC,SAAS,IAAI;QAAE,MAAM,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAAC,KAAK,CAAC,EAAE,UAAU,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAA;KAAE,GAAG,IAAI;IAKjH,OAAO,CAAC,IAAI;CAGb"}
|