@poping/yome 0.0.2
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/README.md +54 -0
- package/bin/yome.js +2 -0
- package/dist/agent.d.ts +43 -0
- package/dist/agent.js +140 -0
- package/dist/agent.js.map +1 -0
- package/dist/config.d.ts +41 -0
- package/dist/config.js +108 -0
- package/dist/config.js.map +1 -0
- package/dist/context.d.ts +1 -0
- package/dist/context.js +101 -0
- package/dist/context.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +65 -0
- package/dist/index.js.map +1 -0
- package/dist/llm.d.ts +13 -0
- package/dist/llm.js +317 -0
- package/dist/llm.js.map +1 -0
- package/dist/loops/chain.d.ts +15 -0
- package/dist/loops/chain.js +105 -0
- package/dist/loops/chain.js.map +1 -0
- package/dist/loops/evaluator.d.ts +12 -0
- package/dist/loops/evaluator.js +100 -0
- package/dist/loops/evaluator.js.map +1 -0
- package/dist/loops/index.d.ts +12 -0
- package/dist/loops/index.js +39 -0
- package/dist/loops/index.js.map +1 -0
- package/dist/loops/orchestrator.d.ts +13 -0
- package/dist/loops/orchestrator.js +107 -0
- package/dist/loops/orchestrator.js.map +1 -0
- package/dist/loops/parallel.d.ts +6 -0
- package/dist/loops/parallel.js +48 -0
- package/dist/loops/parallel.js.map +1 -0
- package/dist/loops/route.d.ts +13 -0
- package/dist/loops/route.js +88 -0
- package/dist/loops/route.js.map +1 -0
- package/dist/loops/simple.d.ts +6 -0
- package/dist/loops/simple.js +46 -0
- package/dist/loops/simple.js.map +1 -0
- package/dist/loops/types.d.ts +32 -0
- package/dist/loops/types.js +9 -0
- package/dist/loops/types.js.map +1 -0
- package/dist/permissions/checker.d.ts +18 -0
- package/dist/permissions/checker.js +89 -0
- package/dist/permissions/checker.js.map +1 -0
- package/dist/permissions/index.d.ts +4 -0
- package/dist/permissions/index.js +4 -0
- package/dist/permissions/index.js.map +1 -0
- package/dist/permissions/loader.d.ts +22 -0
- package/dist/permissions/loader.js +104 -0
- package/dist/permissions/loader.js.map +1 -0
- package/dist/permissions/ruleParser.d.ts +23 -0
- package/dist/permissions/ruleParser.js +59 -0
- package/dist/permissions/ruleParser.js.map +1 -0
- package/dist/permissions/types.d.ts +37 -0
- package/dist/permissions/types.js +2 -0
- package/dist/permissions/types.js.map +1 -0
- package/dist/sessions.d.ts +20 -0
- package/dist/sessions.js +119 -0
- package/dist/sessions.js.map +1 -0
- package/dist/skills/index.d.ts +2 -0
- package/dist/skills/index.js +2 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/skills/loader.d.ts +4 -0
- package/dist/skills/loader.js +125 -0
- package/dist/skills/loader.js.map +1 -0
- package/dist/skills/types.d.ts +22 -0
- package/dist/skills/types.js +2 -0
- package/dist/skills/types.js.map +1 -0
- package/dist/subagent/agentTool.d.ts +7 -0
- package/dist/subagent/agentTool.js +121 -0
- package/dist/subagent/agentTool.js.map +1 -0
- package/dist/subagent/builtinAgents.d.ts +3 -0
- package/dist/subagent/builtinAgents.js +23 -0
- package/dist/subagent/builtinAgents.js.map +1 -0
- package/dist/subagent/index.d.ts +6 -0
- package/dist/subagent/index.js +5 -0
- package/dist/subagent/index.js.map +1 -0
- package/dist/subagent/loadAgents.d.ts +2 -0
- package/dist/subagent/loadAgents.js +98 -0
- package/dist/subagent/loadAgents.js.map +1 -0
- package/dist/subagent/runAgent.d.ts +18 -0
- package/dist/subagent/runAgent.js +115 -0
- package/dist/subagent/runAgent.js.map +1 -0
- package/dist/subagent/types.d.ts +20 -0
- package/dist/subagent/types.js +2 -0
- package/dist/subagent/types.js.map +1 -0
- package/dist/toggleState.d.ts +6 -0
- package/dist/toggleState.js +58 -0
- package/dist/toggleState.js.map +1 -0
- package/dist/tools/bash.d.ts +2 -0
- package/dist/tools/bash.js +78 -0
- package/dist/tools/bash.js.map +1 -0
- package/dist/tools/edit.d.ts +2 -0
- package/dist/tools/edit.js +103 -0
- package/dist/tools/edit.js.map +1 -0
- package/dist/tools/glob.d.ts +2 -0
- package/dist/tools/glob.js +44 -0
- package/dist/tools/glob.js.map +1 -0
- package/dist/tools/grep.d.ts +2 -0
- package/dist/tools/grep.js +89 -0
- package/dist/tools/grep.js.map +1 -0
- package/dist/tools/index.d.ts +15 -0
- package/dist/tools/index.js +99 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/ls.d.ts +2 -0
- package/dist/tools/ls.js +47 -0
- package/dist/tools/ls.js.map +1 -0
- package/dist/tools/read.d.ts +2 -0
- package/dist/tools/read.js +52 -0
- package/dist/tools/read.js.map +1 -0
- package/dist/tools/write.d.ts +2 -0
- package/dist/tools/write.js +46 -0
- package/dist/tools/write.js.map +1 -0
- package/dist/types.d.ts +82 -0
- package/dist/types.js +13 -0
- package/dist/types.js.map +1 -0
- package/dist/ui/AgentPicker.d.ts +12 -0
- package/dist/ui/AgentPicker.js +32 -0
- package/dist/ui/AgentPicker.js.map +1 -0
- package/dist/ui/App.d.ts +6 -0
- package/dist/ui/App.js +327 -0
- package/dist/ui/App.js.map +1 -0
- package/dist/ui/Banner.d.ts +1 -0
- package/dist/ui/Banner.js +14 -0
- package/dist/ui/Banner.js.map +1 -0
- package/dist/ui/InputBar.d.ts +17 -0
- package/dist/ui/InputBar.js +93 -0
- package/dist/ui/InputBar.js.map +1 -0
- package/dist/ui/Markdown.d.ts +4 -0
- package/dist/ui/Markdown.js +97 -0
- package/dist/ui/Markdown.js.map +1 -0
- package/dist/ui/MessageList.d.ts +17 -0
- package/dist/ui/MessageList.js +50 -0
- package/dist/ui/MessageList.js.map +1 -0
- package/dist/ui/ModelPicker.d.ts +9 -0
- package/dist/ui/ModelPicker.js +70 -0
- package/dist/ui/ModelPicker.js.map +1 -0
- package/dist/ui/PermissionPrompt.d.ts +10 -0
- package/dist/ui/PermissionPrompt.js +37 -0
- package/dist/ui/PermissionPrompt.js.map +1 -0
- package/dist/ui/SessionPicker.d.ts +8 -0
- package/dist/ui/SessionPicker.js +64 -0
- package/dist/ui/SessionPicker.js.map +1 -0
- package/dist/ui/Spinner.d.ts +3 -0
- package/dist/ui/Spinner.js +15 -0
- package/dist/ui/Spinner.js.map +1 -0
- package/dist/ui/TogglePicker.d.ts +16 -0
- package/dist/ui/TogglePicker.js +35 -0
- package/dist/ui/TogglePicker.js.map +1 -0
- package/dist/ui/ToolResult.d.ts +6 -0
- package/dist/ui/ToolResult.js +59 -0
- package/dist/ui/ToolResult.js.map +1 -0
- package/dist/utils/imagePaste.d.ts +12 -0
- package/dist/utils/imagePaste.js +54 -0
- package/dist/utils/imagePaste.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { AgentLoop, AgentLoopContext, AgentLoopCallbacks, UserInput } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Orchestrator-Workers: a central LLM dynamically breaks down the task,
|
|
4
|
+
* delegates subtasks to worker LLM calls (with tools), then synthesizes results.
|
|
5
|
+
*
|
|
6
|
+
* Flow: In → Orchestrator → [Worker1, Worker2, ...] (parallel) → Synthesizer → Out
|
|
7
|
+
*/
|
|
8
|
+
export declare class OrchestratorAgentLoop implements AgentLoop {
|
|
9
|
+
readonly name = "orchestrator";
|
|
10
|
+
readonly description = "Orchestrator-workers: decompose, delegate in parallel, synthesize";
|
|
11
|
+
run(userMessage: UserInput, ctx: AgentLoopContext, cb: AgentLoopCallbacks): Promise<void>;
|
|
12
|
+
private runWorker;
|
|
13
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { callLLM, extractText, callLLMStream } from '../llm.js';
|
|
2
|
+
import { userInputAsText } from './types.js';
|
|
3
|
+
const MAX_WORKER_ITERATIONS = 15;
|
|
4
|
+
/**
|
|
5
|
+
* Orchestrator-Workers: a central LLM dynamically breaks down the task,
|
|
6
|
+
* delegates subtasks to worker LLM calls (with tools), then synthesizes results.
|
|
7
|
+
*
|
|
8
|
+
* Flow: In → Orchestrator → [Worker1, Worker2, ...] (parallel) → Synthesizer → Out
|
|
9
|
+
*/
|
|
10
|
+
export class OrchestratorAgentLoop {
|
|
11
|
+
name = 'orchestrator';
|
|
12
|
+
description = 'Orchestrator-workers: decompose, delegate in parallel, synthesize';
|
|
13
|
+
async run(userMessage, ctx, cb) {
|
|
14
|
+
ctx.messages.push({ role: 'user', content: userMessage });
|
|
15
|
+
let totalInput = 0;
|
|
16
|
+
let totalOutput = 0;
|
|
17
|
+
try {
|
|
18
|
+
// Step 1: Orchestrator decomposes the task
|
|
19
|
+
const decomposeResponse = await callLLM(ctx.config, ctx.systemPrompt, [
|
|
20
|
+
...ctx.messages,
|
|
21
|
+
{
|
|
22
|
+
role: 'user',
|
|
23
|
+
content: 'Break this task into independent subtasks that can be executed in parallel. ' +
|
|
24
|
+
'Output ONLY a JSON array of objects: [{"id": 1, "task": "description"}, ...]. ' +
|
|
25
|
+
'Keep it to 2-5 subtasks. No other text.',
|
|
26
|
+
},
|
|
27
|
+
]);
|
|
28
|
+
totalInput += decomposeResponse.usage.input_tokens;
|
|
29
|
+
totalOutput += decomposeResponse.usage.output_tokens;
|
|
30
|
+
const decomposeText = extractText(decomposeResponse);
|
|
31
|
+
let subtasks;
|
|
32
|
+
try {
|
|
33
|
+
const match = decomposeText.match(/\[[\s\S]*\]/);
|
|
34
|
+
subtasks = match ? JSON.parse(match[0]) : [{ id: 1, task: userInputAsText(userMessage) }];
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
subtasks = [{ id: 1, task: userInputAsText(userMessage) }];
|
|
38
|
+
}
|
|
39
|
+
cb.onTextDelta(`**Orchestrator** dispatching ${subtasks.length} workers:\n`);
|
|
40
|
+
subtasks.forEach((s) => cb.onTextDelta(`- Worker ${s.id}: ${s.task}\n`));
|
|
41
|
+
cb.onTextDelta('\n');
|
|
42
|
+
// Step 2: Execute workers in parallel
|
|
43
|
+
const workerResults = await Promise.all(subtasks.map((subtask) => this.runWorker(subtask, ctx, cb).then((r) => {
|
|
44
|
+
totalInput += r.inputTokens;
|
|
45
|
+
totalOutput += r.outputTokens;
|
|
46
|
+
return r;
|
|
47
|
+
})));
|
|
48
|
+
// Step 3: Synthesizer combines results
|
|
49
|
+
cb.onTextDelta('\n---\n**Synthesizing results...**\n\n');
|
|
50
|
+
const synthesisContext = `Original task: ${userMessage}\n\n` +
|
|
51
|
+
workerResults
|
|
52
|
+
.map((r) => `## Worker ${r.id} (${r.task})\n${r.result}`)
|
|
53
|
+
.join('\n\n');
|
|
54
|
+
const synthesizeMessages = [
|
|
55
|
+
...ctx.messages,
|
|
56
|
+
{
|
|
57
|
+
role: 'user',
|
|
58
|
+
content: `Here are the results from parallel workers. Synthesize them into a coherent final answer.\n\n${synthesisContext}`,
|
|
59
|
+
},
|
|
60
|
+
];
|
|
61
|
+
const synthResponse = await callLLMStream(ctx.config, ctx.systemPrompt, synthesizeMessages, [], (event) => {
|
|
62
|
+
if (event.type === 'text_delta' && event.text) {
|
|
63
|
+
cb.onTextDelta(event.text);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
totalInput += synthResponse.usage.input_tokens;
|
|
67
|
+
totalOutput += synthResponse.usage.output_tokens;
|
|
68
|
+
ctx.messages.push({ role: 'assistant', content: synthResponse.content });
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
cb.onError(err);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
cb.onDone({ inputTokens: totalInput, outputTokens: totalOutput });
|
|
75
|
+
}
|
|
76
|
+
async runWorker(subtask, ctx, cb) {
|
|
77
|
+
const workerMessages = [
|
|
78
|
+
{ role: 'user', content: `Execute this subtask: ${subtask.task}\nBe concise and focused.` },
|
|
79
|
+
];
|
|
80
|
+
let inputTokens = 0;
|
|
81
|
+
let outputTokens = 0;
|
|
82
|
+
let resultText = '';
|
|
83
|
+
for (let i = 0; i < MAX_WORKER_ITERATIONS; i++) {
|
|
84
|
+
const response = await callLLMStream(ctx.config, ctx.systemPrompt, workerMessages, ctx.tools, (event) => {
|
|
85
|
+
if (event.type === 'text_delta' && event.text) {
|
|
86
|
+
resultText += event.text;
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
inputTokens += response.usage.input_tokens;
|
|
90
|
+
outputTokens += response.usage.output_tokens;
|
|
91
|
+
workerMessages.push({ role: 'assistant', content: response.content });
|
|
92
|
+
const toolUseBlocks = response.content.filter((b) => b.type === 'tool_use');
|
|
93
|
+
if (toolUseBlocks.length === 0 || response.stop_reason === 'end_turn')
|
|
94
|
+
break;
|
|
95
|
+
const toolResults = [];
|
|
96
|
+
for (const block of toolUseBlocks) {
|
|
97
|
+
cb.onToolUse(block.name, block.input);
|
|
98
|
+
const result = await ctx.executeTool(block.name, block.input);
|
|
99
|
+
cb.onToolResult(block.name, result);
|
|
100
|
+
toolResults.push({ type: 'tool_result', tool_use_id: block.id, content: result });
|
|
101
|
+
}
|
|
102
|
+
workerMessages.push({ role: 'user', content: toolResults });
|
|
103
|
+
}
|
|
104
|
+
return { id: subtask.id, task: subtask.task, result: resultText || '(no output)', inputTokens, outputTokens };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=orchestrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../src/loops/orchestrator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { AgentLoop, AgentLoopContext, AgentLoopCallbacks, UserInput } from './types.js';
|
|
2
|
+
export declare class ParallelAgentLoop implements AgentLoop {
|
|
3
|
+
readonly name = "parallel";
|
|
4
|
+
readonly description = "Parallel tool execution loop";
|
|
5
|
+
run(userMessage: UserInput, ctx: AgentLoopContext, cb: AgentLoopCallbacks): Promise<void>;
|
|
6
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { callLLMStream } from '../llm.js';
|
|
2
|
+
const MAX_ITERATIONS = 30;
|
|
3
|
+
export class ParallelAgentLoop {
|
|
4
|
+
name = 'parallel';
|
|
5
|
+
description = 'Parallel tool execution loop';
|
|
6
|
+
async run(userMessage, ctx, cb) {
|
|
7
|
+
ctx.messages.push({ role: 'user', content: userMessage });
|
|
8
|
+
let totalInput = 0;
|
|
9
|
+
let totalOutput = 0;
|
|
10
|
+
for (let i = 0; i < MAX_ITERATIONS; i++) {
|
|
11
|
+
try {
|
|
12
|
+
const response = await callLLMStream(ctx.config, ctx.systemPrompt, ctx.messages, ctx.tools, (event) => {
|
|
13
|
+
if (event.type === 'text_delta' && event.text) {
|
|
14
|
+
cb.onTextDelta(event.text);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
totalInput += response.usage.input_tokens;
|
|
18
|
+
totalOutput += response.usage.output_tokens;
|
|
19
|
+
ctx.messages.push({ role: 'assistant', content: response.content });
|
|
20
|
+
const toolUseBlocks = response.content.filter((b) => b.type === 'tool_use');
|
|
21
|
+
if (toolUseBlocks.length === 0 || response.stop_reason === 'end_turn') {
|
|
22
|
+
cb.onDone({ inputTokens: totalInput, outputTokens: totalOutput });
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
// Execute all tools in parallel
|
|
26
|
+
for (const block of toolUseBlocks) {
|
|
27
|
+
cb.onToolUse(block.name, block.input);
|
|
28
|
+
}
|
|
29
|
+
const results = await Promise.all(toolUseBlocks.map((block) => ctx.executeTool(block.name, block.input)));
|
|
30
|
+
const toolResults = toolUseBlocks.map((block, idx) => {
|
|
31
|
+
cb.onToolResult(block.name, results[idx]);
|
|
32
|
+
return {
|
|
33
|
+
type: 'tool_result',
|
|
34
|
+
tool_use_id: block.id,
|
|
35
|
+
content: results[idx],
|
|
36
|
+
};
|
|
37
|
+
});
|
|
38
|
+
ctx.messages.push({ role: 'user', content: toolResults });
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
cb.onError(err);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
cb.onDone({ inputTokens: totalInput, outputTokens: totalOutput });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=parallel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parallel.js","sourceRoot":"","sources":["../../src/loops/parallel.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { AgentLoop, AgentLoopContext, AgentLoopCallbacks, UserInput } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Routing: classify input then dispatch to a specialized handler.
|
|
4
|
+
*
|
|
5
|
+
* Flow: In → LLM Router → [route1 | route2 | route3 | ...] → Out
|
|
6
|
+
*
|
|
7
|
+
* Each route has a specialized system prompt so the LLM focuses on that domain.
|
|
8
|
+
*/
|
|
9
|
+
export declare class RouteAgentLoop implements AgentLoop {
|
|
10
|
+
readonly name = "route";
|
|
11
|
+
readonly description = "Routing: classify input then dispatch to specialized handler";
|
|
12
|
+
run(userMessage: UserInput, ctx: AgentLoopContext, cb: AgentLoopCallbacks): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { callLLM, extractText, callLLMStream } from '../llm.js';
|
|
2
|
+
const MAX_ITERATIONS = 30;
|
|
3
|
+
const ROUTES = [
|
|
4
|
+
{
|
|
5
|
+
name: 'code',
|
|
6
|
+
description: 'Writing, editing, debugging, or refactoring code',
|
|
7
|
+
systemPrompt: 'You are a coding specialist. Focus on writing clean, correct code. ' +
|
|
8
|
+
'Read files before editing. Use tools to verify your changes compile/run.',
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
name: 'analyze',
|
|
12
|
+
description: 'Reading, understanding, explaining, or reviewing code/files',
|
|
13
|
+
systemPrompt: 'You are an analysis specialist. Focus on reading and understanding code. ' +
|
|
14
|
+
'Provide clear explanations. Use Read/Grep/Glob to gather information before answering.',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
name: 'shell',
|
|
18
|
+
description: 'Running commands, managing files, git operations, build/test tasks',
|
|
19
|
+
systemPrompt: 'You are a shell operations specialist. Focus on running commands efficiently. ' +
|
|
20
|
+
'Prefer Bash tool for system operations. Be careful with destructive commands.',
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: 'general',
|
|
24
|
+
description: 'General questions, planning, brainstorming, or anything else',
|
|
25
|
+
systemPrompt: 'You are a helpful assistant. Answer the user concisely and accurately. ' +
|
|
26
|
+
'Use tools only when needed to verify facts or gather information.',
|
|
27
|
+
},
|
|
28
|
+
];
|
|
29
|
+
/**
|
|
30
|
+
* Routing: classify input then dispatch to a specialized handler.
|
|
31
|
+
*
|
|
32
|
+
* Flow: In → LLM Router → [route1 | route2 | route3 | ...] → Out
|
|
33
|
+
*
|
|
34
|
+
* Each route has a specialized system prompt so the LLM focuses on that domain.
|
|
35
|
+
*/
|
|
36
|
+
export class RouteAgentLoop {
|
|
37
|
+
name = 'route';
|
|
38
|
+
description = 'Routing: classify input then dispatch to specialized handler';
|
|
39
|
+
async run(userMessage, ctx, cb) {
|
|
40
|
+
ctx.messages.push({ role: 'user', content: userMessage });
|
|
41
|
+
let totalInput = 0;
|
|
42
|
+
let totalOutput = 0;
|
|
43
|
+
try {
|
|
44
|
+
// Step 1: Classify
|
|
45
|
+
const routeList = ROUTES.map((r) => `- ${r.name}: ${r.description}`).join('\n');
|
|
46
|
+
const classifyResponse = await callLLM(ctx.config, 'You are a router.', [
|
|
47
|
+
{
|
|
48
|
+
role: 'user',
|
|
49
|
+
content: `Classify this request into exactly one category. Reply with ONLY the category name.\n\nCategories:\n${routeList}\n\nRequest: ${userMessage}`,
|
|
50
|
+
},
|
|
51
|
+
]);
|
|
52
|
+
totalInput += classifyResponse.usage.input_tokens;
|
|
53
|
+
totalOutput += classifyResponse.usage.output_tokens;
|
|
54
|
+
const classification = extractText(classifyResponse).trim().toLowerCase();
|
|
55
|
+
const route = ROUTES.find((r) => classification.includes(r.name)) ?? ROUTES[ROUTES.length - 1];
|
|
56
|
+
cb.onTextDelta(`*[routed to: ${route.name}]*\n\n`);
|
|
57
|
+
// Step 2: Execute with specialized system prompt
|
|
58
|
+
const specializedPrompt = `${route.systemPrompt}\n\n${ctx.systemPrompt}`;
|
|
59
|
+
for (let i = 0; i < MAX_ITERATIONS; i++) {
|
|
60
|
+
const response = await callLLMStream(ctx.config, specializedPrompt, ctx.messages, ctx.tools, (event) => {
|
|
61
|
+
if (event.type === 'text_delta' && event.text) {
|
|
62
|
+
cb.onTextDelta(event.text);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
totalInput += response.usage.input_tokens;
|
|
66
|
+
totalOutput += response.usage.output_tokens;
|
|
67
|
+
ctx.messages.push({ role: 'assistant', content: response.content });
|
|
68
|
+
const toolUseBlocks = response.content.filter((b) => b.type === 'tool_use');
|
|
69
|
+
if (toolUseBlocks.length === 0 || response.stop_reason === 'end_turn')
|
|
70
|
+
break;
|
|
71
|
+
const toolResults = [];
|
|
72
|
+
for (const block of toolUseBlocks) {
|
|
73
|
+
cb.onToolUse(block.name, block.input);
|
|
74
|
+
const result = await ctx.executeTool(block.name, block.input);
|
|
75
|
+
cb.onToolResult(block.name, result);
|
|
76
|
+
toolResults.push({ type: 'tool_result', tool_use_id: block.id, content: result });
|
|
77
|
+
}
|
|
78
|
+
ctx.messages.push({ role: 'user', content: toolResults });
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
cb.onError(err);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
cb.onDone({ inputTokens: totalInput, outputTokens: totalOutput });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=route.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route.js","sourceRoot":"","sources":["../../src/loops/route.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { AgentLoop, AgentLoopContext, AgentLoopCallbacks, UserInput } from './types.js';
|
|
2
|
+
export declare class SimpleAgentLoop implements AgentLoop {
|
|
3
|
+
readonly name = "simple";
|
|
4
|
+
readonly description = "Sequential tool-call loop (default)";
|
|
5
|
+
run(userMessage: UserInput, ctx: AgentLoopContext, cb: AgentLoopCallbacks): Promise<void>;
|
|
6
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { callLLMStream } from '../llm.js';
|
|
2
|
+
const MAX_ITERATIONS = 30;
|
|
3
|
+
export class SimpleAgentLoop {
|
|
4
|
+
name = 'simple';
|
|
5
|
+
description = 'Sequential tool-call loop (default)';
|
|
6
|
+
async run(userMessage, ctx, cb) {
|
|
7
|
+
ctx.messages.push({ role: 'user', content: userMessage });
|
|
8
|
+
let totalInput = 0;
|
|
9
|
+
let totalOutput = 0;
|
|
10
|
+
for (let i = 0; i < MAX_ITERATIONS; i++) {
|
|
11
|
+
try {
|
|
12
|
+
const response = await callLLMStream(ctx.config, ctx.systemPrompt, ctx.messages, ctx.tools, (event) => {
|
|
13
|
+
if (event.type === 'text_delta' && event.text) {
|
|
14
|
+
cb.onTextDelta(event.text);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
totalInput += response.usage.input_tokens;
|
|
18
|
+
totalOutput += response.usage.output_tokens;
|
|
19
|
+
ctx.messages.push({ role: 'assistant', content: response.content });
|
|
20
|
+
const toolUseBlocks = response.content.filter((b) => b.type === 'tool_use');
|
|
21
|
+
if (toolUseBlocks.length === 0 || response.stop_reason === 'end_turn') {
|
|
22
|
+
cb.onDone({ inputTokens: totalInput, outputTokens: totalOutput });
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const toolResults = [];
|
|
26
|
+
for (const block of toolUseBlocks) {
|
|
27
|
+
cb.onToolUse(block.name, block.input);
|
|
28
|
+
const result = await ctx.executeTool(block.name, block.input);
|
|
29
|
+
cb.onToolResult(block.name, result);
|
|
30
|
+
toolResults.push({
|
|
31
|
+
type: 'tool_result',
|
|
32
|
+
tool_use_id: block.id,
|
|
33
|
+
content: result,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
ctx.messages.push({ role: 'user', content: toolResults });
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
cb.onError(err);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
cb.onDone({ inputTokens: totalInput, outputTokens: totalOutput });
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=simple.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simple.js","sourceRoot":"","sources":["../../src/loops/simple.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAI1C,MAAM,cAAc,GAAG,EAAE,CAAC;AAE1B,MAAM,OAAO,eAAe;IACjB,IAAI,GAAG,QAAQ,CAAC;IAChB,WAAW,GAAG,qCAAqC,CAAC;IAE7D,KAAK,CAAC,GAAG,CACP,WAAsB,EACtB,GAAqB,EACrB,EAAsB;QAEtB,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;QAE1D,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,IAAI,WAAW,GAAG,CAAC,CAAC;QAEpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,cAAc,EAAE,CAAC,EAAE,EAAE,CAAC;YACxC,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,aAAa,CAClC,GAAG,CAAC,MAAM,EACV,GAAG,CAAC,YAAY,EAChB,GAAG,CAAC,QAAQ,EACZ,GAAG,CAAC,KAAK,EACT,CAAC,KAAK,EAAE,EAAE;oBACR,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;wBAC9C,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAC7B,CAAC;gBACH,CAAC,CACF,CAAC;gBAEF,UAAU,IAAI,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC;gBAC1C,WAAW,IAAI,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC;gBAC5C,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;gBAEpE,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAC3C,CAAC,CAAC,EAA4C,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CACvE,CAAC;gBAEF,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;oBACtE,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC;oBAClE,OAAO;gBACT,CAAC;gBAED,MAAM,WAAW,GAAmB,EAAE,CAAC;gBACvC,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;oBAClC,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;oBACtC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;oBAC9D,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;oBACpC,WAAW,CAAC,IAAI,CAAC;wBACf,IAAI,EAAE,aAAa;wBACnB,WAAW,EAAE,KAAK,CAAC,EAAE;wBACrB,OAAO,EAAE,MAAM;qBAChB,CAAC,CAAC;gBACL,CAAC;gBAED,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;YAC5D,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;gBAChB,OAAO;YACT,CAAC;QACH,CAAC;QAED,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC;IACpE,CAAC;CACF"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { YomeConfig } from '../config.js';
|
|
2
|
+
import type { ContentBlock, AgentMessage, AnthropicTool } from '../types.js';
|
|
3
|
+
export interface AgentLoopCallbacks {
|
|
4
|
+
onTextDelta: (text: string) => void;
|
|
5
|
+
onToolUse: (name: string, input: Record<string, unknown>) => void;
|
|
6
|
+
onToolResult: (name: string, result: string) => void;
|
|
7
|
+
onDone: (usage: {
|
|
8
|
+
inputTokens: number;
|
|
9
|
+
outputTokens: number;
|
|
10
|
+
}) => void;
|
|
11
|
+
onError: (error: Error) => void;
|
|
12
|
+
}
|
|
13
|
+
export interface AgentLoopContext {
|
|
14
|
+
config: YomeConfig;
|
|
15
|
+
systemPrompt: string;
|
|
16
|
+
messages: AgentMessage[];
|
|
17
|
+
tools: AnthropicTool[];
|
|
18
|
+
executeTool: (name: string, input: Record<string, unknown>) => Promise<string>;
|
|
19
|
+
}
|
|
20
|
+
export type UserInput = string | ContentBlock[];
|
|
21
|
+
export declare function userInputAsText(input: UserInput): string;
|
|
22
|
+
export interface AgentLoop {
|
|
23
|
+
readonly name: string;
|
|
24
|
+
readonly description: string;
|
|
25
|
+
run(userMessage: UserInput, context: AgentLoopContext, callbacks: AgentLoopCallbacks): Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
export interface AgentLoopRegistry {
|
|
28
|
+
get(name: string): AgentLoop | undefined;
|
|
29
|
+
list(): AgentLoop[];
|
|
30
|
+
register(loop: AgentLoop): void;
|
|
31
|
+
default(): AgentLoop;
|
|
32
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/loops/types.ts"],"names":[],"mappings":"AAqBA,MAAM,UAAU,eAAe,CAAC,KAAgB;IAC9C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,OAAO,KAAK;SACT,MAAM,CAAC,CAAC,CAAC,EAAwC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC;SACtE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;SAClB,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ToolPermissionContext, PermissionDecision, PermissionResult } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Check if a specific command/path is allowed by a content-specific rule.
|
|
4
|
+
*/
|
|
5
|
+
export declare function isContentAllowed(ctx: ToolPermissionContext, toolName: string, content: string): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Check if a specific command/path is denied by a content-specific rule.
|
|
8
|
+
*/
|
|
9
|
+
export declare function isContentDenied(ctx: ToolPermissionContext, toolName: string, content: string): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Main permission check for a tool invocation.
|
|
12
|
+
*
|
|
13
|
+
* @param toolName - The tool being invoked
|
|
14
|
+
* @param isReadOnly - Whether the tool is read-only
|
|
15
|
+
* @param ctx - Current permission context
|
|
16
|
+
* @param toolResult - Optional result from the tool's own checkPermissions()
|
|
17
|
+
*/
|
|
18
|
+
export declare function checkPermission(toolName: string, isReadOnly: boolean, ctx: ToolPermissionContext, toolResult?: PermissionResult): PermissionDecision;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { parseRuleValue, toolMatchesRule, contentMatchesRule } from './ruleParser.js';
|
|
2
|
+
const RULE_SOURCES = ['cliArg', 'session', 'userSettings', 'projectSettings'];
|
|
3
|
+
function getAllowRules(ctx) {
|
|
4
|
+
return RULE_SOURCES.flatMap((source) => (ctx.allowRules[source] ?? []).map((s) => ({
|
|
5
|
+
source,
|
|
6
|
+
ruleBehavior: 'allow',
|
|
7
|
+
ruleValue: parseRuleValue(s),
|
|
8
|
+
})));
|
|
9
|
+
}
|
|
10
|
+
function getDenyRules(ctx) {
|
|
11
|
+
return RULE_SOURCES.flatMap((source) => (ctx.denyRules[source] ?? []).map((s) => ({
|
|
12
|
+
source,
|
|
13
|
+
ruleBehavior: 'deny',
|
|
14
|
+
ruleValue: parseRuleValue(s),
|
|
15
|
+
})));
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Check if the entire tool is denied by a rule.
|
|
19
|
+
*/
|
|
20
|
+
function isToolDenied(ctx, toolName) {
|
|
21
|
+
return getDenyRules(ctx).some((r) => toolMatchesRule(toolName, r.ruleValue));
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Check if the entire tool is allowed by a rule.
|
|
25
|
+
*/
|
|
26
|
+
function isToolAllowed(ctx, toolName) {
|
|
27
|
+
return getAllowRules(ctx).some((r) => toolMatchesRule(toolName, r.ruleValue));
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Check if a specific command/path is allowed by a content-specific rule.
|
|
31
|
+
*/
|
|
32
|
+
export function isContentAllowed(ctx, toolName, content) {
|
|
33
|
+
return getAllowRules(ctx).some((r) => contentMatchesRule(toolName, content, r.ruleValue));
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Check if a specific command/path is denied by a content-specific rule.
|
|
37
|
+
*/
|
|
38
|
+
export function isContentDenied(ctx, toolName, content) {
|
|
39
|
+
return getDenyRules(ctx).some((r) => contentMatchesRule(toolName, content, r.ruleValue));
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Main permission check for a tool invocation.
|
|
43
|
+
*
|
|
44
|
+
* @param toolName - The tool being invoked
|
|
45
|
+
* @param isReadOnly - Whether the tool is read-only
|
|
46
|
+
* @param ctx - Current permission context
|
|
47
|
+
* @param toolResult - Optional result from the tool's own checkPermissions()
|
|
48
|
+
*/
|
|
49
|
+
export function checkPermission(toolName, isReadOnly, ctx, toolResult) {
|
|
50
|
+
// 1. Check deny rules (always respected)
|
|
51
|
+
if (isToolDenied(ctx, toolName)) {
|
|
52
|
+
return { behavior: 'deny', message: `Permission to use ${toolName} has been denied.` };
|
|
53
|
+
}
|
|
54
|
+
// 2. Tool-specific deny
|
|
55
|
+
if (toolResult?.behavior === 'deny') {
|
|
56
|
+
return toolResult;
|
|
57
|
+
}
|
|
58
|
+
// 3. Bypass mode allows everything
|
|
59
|
+
if (ctx.mode === 'bypassPermissions') {
|
|
60
|
+
return { behavior: 'allow' };
|
|
61
|
+
}
|
|
62
|
+
// 4. Accept-edits mode: allow read-only tools + file edit tools
|
|
63
|
+
if (ctx.mode === 'acceptEdits') {
|
|
64
|
+
if (isReadOnly)
|
|
65
|
+
return { behavior: 'allow' };
|
|
66
|
+
const editTools = ['Edit', 'Write'];
|
|
67
|
+
if (editTools.includes(toolName))
|
|
68
|
+
return { behavior: 'allow' };
|
|
69
|
+
// Bash still needs ask unless explicitly allowed
|
|
70
|
+
}
|
|
71
|
+
// 5. Explicit allow rules
|
|
72
|
+
if (isToolAllowed(ctx, toolName)) {
|
|
73
|
+
return { behavior: 'allow' };
|
|
74
|
+
}
|
|
75
|
+
// 6. Tool-specific ask/allow
|
|
76
|
+
if (toolResult?.behavior === 'allow') {
|
|
77
|
+
return toolResult;
|
|
78
|
+
}
|
|
79
|
+
if (toolResult?.behavior === 'ask') {
|
|
80
|
+
return toolResult;
|
|
81
|
+
}
|
|
82
|
+
// 7. Read-only tools are always allowed
|
|
83
|
+
if (isReadOnly) {
|
|
84
|
+
return { behavior: 'allow' };
|
|
85
|
+
}
|
|
86
|
+
// 8. Default: ask for write operations
|
|
87
|
+
return { behavior: 'ask', message: `Allow ${toolName} to proceed?` };
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=checker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checker.js","sourceRoot":"","sources":["../../src/permissions/checker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export type { PermissionMode, PermissionBehavior, PermissionRule, PermissionRuleValue, PermissionRuleSource, PermissionDecision, PermissionResult, ToolPermissionContext, PermissionRulesBySource, } from './types.js';
|
|
2
|
+
export { parseRuleValue, serializeRuleValue, toolMatchesRule, contentMatchesRule } from './ruleParser.js';
|
|
3
|
+
export { loadAllPermissionRules, loadDefaultMode, initializePermissionContext, addPermissionRuleToUserSettings } from './loader.js';
|
|
4
|
+
export { checkPermission, isContentAllowed, isContentDenied } from './checker.js';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { parseRuleValue, serializeRuleValue, toolMatchesRule, contentMatchesRule } from './ruleParser.js';
|
|
2
|
+
export { loadAllPermissionRules, loadDefaultMode, initializePermissionContext, addPermissionRuleToUserSettings } from './loader.js';
|
|
3
|
+
export { checkPermission, isContentAllowed, isContentDenied } from './checker.js';
|
|
4
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/permissions/index.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1G,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,2BAA2B,EAAE,+BAA+B,EAAE,MAAM,aAAa,CAAC;AACpI,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { PermissionBehavior, PermissionRule, PermissionMode, ToolPermissionContext } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Load all permission rules from user settings (~/.yome/settings.json)
|
|
4
|
+
* and project settings (.yome/settings.json).
|
|
5
|
+
*/
|
|
6
|
+
export declare function loadAllPermissionRules(): PermissionRule[];
|
|
7
|
+
/**
|
|
8
|
+
* Load the default permission mode from settings.
|
|
9
|
+
*/
|
|
10
|
+
export declare function loadDefaultMode(): PermissionMode;
|
|
11
|
+
/**
|
|
12
|
+
* Build an initial ToolPermissionContext from disk settings and CLI args.
|
|
13
|
+
*/
|
|
14
|
+
export declare function initializePermissionContext(opts?: {
|
|
15
|
+
allowedTools?: string[];
|
|
16
|
+
disallowedTools?: string[];
|
|
17
|
+
mode?: PermissionMode;
|
|
18
|
+
}): ToolPermissionContext;
|
|
19
|
+
/**
|
|
20
|
+
* Persist a new allow/deny rule to user settings.
|
|
21
|
+
*/
|
|
22
|
+
export declare function addPermissionRuleToUserSettings(ruleString: string, behavior: PermissionBehavior): void;
|