qlogicagent 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent.js +1 -0
- package/dist/cli.js +9 -0
- package/dist/contracts.js +1 -0
- package/dist/index.js +5 -15
- package/dist/orchestration.js +118 -0
- package/package.json +56 -42
- package/dist/agent/agent.js +0 -113
- package/dist/agent/tool-loop.js +0 -575
- package/dist/agent/types.js +0 -14
- package/dist/cli/main.js +0 -23
- package/dist/cli/stdio-server.js +0 -463
- package/dist/config/config.js +0 -21
- package/dist/contracts/hooks.js +0 -7
- package/dist/contracts/index.js +0 -10
- package/dist/contracts/planner.js +0 -2
- package/dist/contracts/skill-candidate.js +0 -195
- package/dist/contracts/todo.js +0 -9
- package/dist/llm/builtin-providers.js +0 -531
- package/dist/llm/index.js +0 -14
- package/dist/llm/llm-client.js +0 -67
- package/dist/llm/model-catalog.js +0 -191
- package/dist/llm/provider-def.js +0 -12
- package/dist/llm/provider-registry.js +0 -147
- package/dist/llm/transport.js +0 -27
- package/dist/llm/transports/anthropic-messages.js +0 -293
- package/dist/llm/transports/openai-chat.js +0 -165
- package/dist/orchestration/agent-registry.js +0 -116
- package/dist/orchestration/approval-aware-tool-plan.js +0 -87
- package/dist/orchestration/context-compression.js +0 -583
- package/dist/orchestration/conversation-repair.js +0 -429
- package/dist/orchestration/curator-scheduler.js +0 -135
- package/dist/orchestration/embedded-failover-policy.js +0 -168
- package/dist/orchestration/error-classification.js +0 -77
- package/dist/orchestration/failover-classification.js +0 -381
- package/dist/orchestration/failover-error.js +0 -198
- package/dist/orchestration/fork-subagent.js +0 -98
- package/dist/orchestration/index.js +0 -267
- package/dist/orchestration/memory-flush-policy.js +0 -85
- package/dist/orchestration/memory-provider.js +0 -2
- package/dist/orchestration/parallel-tool-calls.js +0 -59
- package/dist/orchestration/prompt-cache-strategy.js +0 -228
- package/dist/orchestration/reactive-compact.js +0 -78
- package/dist/orchestration/retry-loop.js +0 -24
- package/dist/orchestration/skill-candidate.js +0 -141
- package/dist/orchestration/skill-consolidation.js +0 -220
- package/dist/orchestration/skill-improvement.js +0 -66
- package/dist/orchestration/skill-similarity.js +0 -131
- package/dist/orchestration/streaming-tool-executor.js +0 -96
- package/dist/orchestration/team-orchestration.js +0 -369
- package/dist/orchestration/team-tool-loop-wiring.js +0 -147
- package/dist/orchestration/tool-choice-policy.js +0 -164
- package/dist/orchestration/tool-loop-state.js +0 -133
- package/dist/orchestration/tool-schema.js +0 -297
- package/dist/orchestration/transcript-repair.js +0 -426
- package/dist/orchestration/turn-loop-guard.js +0 -92
- package/dist/orchestration/web-browser-policy.js +0 -39
- package/dist/runtime/context-compression.js +0 -274
- package/dist/runtime/hook-registry.js +0 -53
- package/dist/runtime/memory-hooks.js +0 -65
- package/dist/runtime/tool-eligibility.js +0 -111
- package/dist/skills/index.js +0 -82
- package/dist/skills/memory-extractor.js +0 -173
- package/dist/skills/memory-query-tool.js +0 -127
- package/dist/skills/memory-store.js +0 -228
- package/dist/skills/memory-tool.js +0 -192
- package/dist/skills/portable-tool.js +0 -14
- package/dist/skills/qmemory-adapter.js +0 -165
- package/dist/skills/skill-frontmatter.js +0 -344
- package/dist/skills/skill-guard.js +0 -229
- package/dist/skills/skill-loader.js +0 -303
- package/dist/skills/skill-source.js +0 -126
- package/dist/skills/skill-types.js +0 -6
- package/dist/skills/think-tool.js +0 -59
- package/dist/skills/todo-tool.js +0 -114
- package/dist/skills/tools/agent-tool.js +0 -142
- package/dist/skills/tools/apply-patch-tool.js +0 -184
- package/dist/skills/tools/ask-user-tool.js +0 -121
- package/dist/skills/tools/brief-tool.js +0 -95
- package/dist/skills/tools/browser-tool.js +0 -155
- package/dist/skills/tools/checkpoint-tool.js +0 -102
- package/dist/skills/tools/config-tool.js +0 -143
- package/dist/skills/tools/cron-tool.js +0 -175
- package/dist/skills/tools/edit-tool.js +0 -70
- package/dist/skills/tools/exec-tool.js +0 -133
- package/dist/skills/tools/image-generate-tool.js +0 -67
- package/dist/skills/tools/instructions-tool.js +0 -187
- package/dist/skills/tools/lsp-tool.js +0 -227
- package/dist/skills/tools/mcp-client-types.js +0 -53
- package/dist/skills/tools/mcp-tool.js +0 -503
- package/dist/skills/tools/memory-tool.js +0 -88
- package/dist/skills/tools/monitor-tool.js +0 -131
- package/dist/skills/tools/music-generate-tool.js +0 -62
- package/dist/skills/tools/notify-tool.js +0 -62
- package/dist/skills/tools/patch-tool.js +0 -505
- package/dist/skills/tools/pdf-tool.js +0 -88
- package/dist/skills/tools/plan-mode-tool.js +0 -122
- package/dist/skills/tools/read-tool.js +0 -84
- package/dist/skills/tools/repl-tool.js +0 -69
- package/dist/skills/tools/search-tool.js +0 -225
- package/dist/skills/tools/send-message-tool.js +0 -76
- package/dist/skills/tools/skill-list-tool.js +0 -54
- package/dist/skills/tools/skill-manage-tool.js +0 -153
- package/dist/skills/tools/skill-view-tool.js +0 -72
- package/dist/skills/tools/sleep-tool.js +0 -81
- package/dist/skills/tools/structured-output-tool.js +0 -176
- package/dist/skills/tools/task-tool.js +0 -161
- package/dist/skills/tools/team-tool.js +0 -105
- package/dist/skills/tools/tool-search-tool.js +0 -110
- package/dist/skills/tools/tts-tool.js +0 -45
- package/dist/skills/tools/video-edit-tool.js +0 -74
- package/dist/skills/tools/video-generate-tool.js +0 -66
- package/dist/skills/tools/video-merge-tool.js +0 -92
- package/dist/skills/tools/video-upscale-tool.js +0 -52
- package/dist/skills/tools/web-fetch-tool.js +0 -92
- package/dist/skills/tools/web-search-tool.js +0 -86
- package/dist/skills/tools/worktree-tool.js +0 -147
- package/dist/skills/tools/write-tool.js +0 -81
- /package/dist/{agent → types/agent}/agent.d.ts +0 -0
- /package/dist/{agent → types/agent}/tool-loop.d.ts +0 -0
- /package/dist/{agent → types/agent}/types.d.ts +0 -0
- /package/dist/{cli → types/cli}/main.d.ts +0 -0
- /package/dist/{cli → types/cli}/stdio-server.d.ts +0 -0
- /package/dist/{config → types/config}/config.d.ts +0 -0
- /package/dist/{contracts → types/contracts}/hooks.d.ts +0 -0
- /package/dist/{contracts → types/contracts}/index.d.ts +0 -0
- /package/dist/{contracts → types/contracts}/planner.d.ts +0 -0
- /package/dist/{contracts → types/contracts}/skill-candidate.d.ts +0 -0
- /package/dist/{contracts → types/contracts}/todo.d.ts +0 -0
- /package/dist/{index.d.ts → types/index.d.ts} +0 -0
- /package/dist/{llm → types/llm}/builtin-providers.d.ts +0 -0
- /package/dist/{llm → types/llm}/index.d.ts +0 -0
- /package/dist/{llm → types/llm}/llm-client.d.ts +0 -0
- /package/dist/{llm → types/llm}/model-catalog.d.ts +0 -0
- /package/dist/{llm → types/llm}/provider-def.d.ts +0 -0
- /package/dist/{llm → types/llm}/provider-registry.d.ts +0 -0
- /package/dist/{llm → types/llm}/transport.d.ts +0 -0
- /package/dist/{llm → types/llm}/transports/anthropic-messages.d.ts +0 -0
- /package/dist/{llm → types/llm}/transports/openai-chat.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/agent-registry.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/approval-aware-tool-plan.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/context-compression.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/conversation-repair.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/curator-scheduler.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/embedded-failover-policy.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/error-classification.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/failover-classification.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/failover-error.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/fork-subagent.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/index.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/memory-flush-policy.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/memory-provider.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/parallel-tool-calls.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/prompt-cache-strategy.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/reactive-compact.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/retry-loop.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/skill-candidate.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/skill-consolidation.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/skill-improvement.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/skill-similarity.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/streaming-tool-executor.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/team-orchestration.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/team-tool-loop-wiring.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/tool-choice-policy.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/tool-loop-state.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/tool-schema.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/transcript-repair.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/turn-loop-guard.d.ts +0 -0
- /package/dist/{orchestration → types/orchestration}/web-browser-policy.d.ts +0 -0
- /package/dist/{runtime → types/runtime}/context-compression.d.ts +0 -0
- /package/dist/{runtime → types/runtime}/hook-registry.d.ts +0 -0
- /package/dist/{runtime → types/runtime}/memory-hooks.d.ts +0 -0
- /package/dist/{runtime → types/runtime}/tool-eligibility.d.ts +0 -0
- /package/dist/{skills → types/skills}/index.d.ts +0 -0
- /package/dist/{skills → types/skills}/memory-extractor.d.ts +0 -0
- /package/dist/{skills → types/skills}/memory-query-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/memory-store.d.ts +0 -0
- /package/dist/{skills → types/skills}/memory-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/portable-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/qmemory-adapter.d.ts +0 -0
- /package/dist/{skills → types/skills}/skill-frontmatter.d.ts +0 -0
- /package/dist/{skills → types/skills}/skill-guard.d.ts +0 -0
- /package/dist/{skills → types/skills}/skill-loader.d.ts +0 -0
- /package/dist/{skills → types/skills}/skill-source.d.ts +0 -0
- /package/dist/{skills → types/skills}/skill-types.d.ts +0 -0
- /package/dist/{skills → types/skills}/think-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/todo-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/agent-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/apply-patch-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/ask-user-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/brief-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/browser-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/checkpoint-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/config-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/cron-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/edit-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/exec-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/image-generate-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/instructions-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/lsp-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/mcp-client-types.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/mcp-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/memory-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/monitor-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/music-generate-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/notify-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/patch-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/pdf-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/plan-mode-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/read-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/repl-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/search-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/send-message-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/skill-list-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/skill-manage-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/skill-view-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/sleep-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/structured-output-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/task-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/team-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/tool-search-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/tts-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/video-edit-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/video-generate-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/video-merge-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/video-upscale-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/web-fetch-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/web-search-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/worktree-tool.d.ts +0 -0
- /package/dist/{skills → types/skills}/tools/write-tool.d.ts +0 -0
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// Agent Tool — CC-aligned fork sub-agent with built-in registry.
|
|
3
|
-
// Reference: claude-code-haha/src/tools/AgentTool/AgentTool.tsx
|
|
4
|
-
// claude-code-haha/src/tools/AgentTool/runAgent.ts
|
|
5
|
-
// claude-code-haha/src/tools/AgentTool/forkSubagent.ts
|
|
6
|
-
// claude-code-haha/src/tools/AgentTool/builtInAgents.ts
|
|
7
|
-
// Category: system
|
|
8
|
-
// ============================================================
|
|
9
|
-
export const AGENT_TOOL_NAME = "agent";
|
|
10
|
-
export const BUILT_IN_AGENT_TYPES = [
|
|
11
|
-
"general", "explore", "plan", "code", "research", "verify",
|
|
12
|
-
];
|
|
13
|
-
export const AGENT_TOOL_SCHEMA = {
|
|
14
|
-
type: "object",
|
|
15
|
-
properties: {
|
|
16
|
-
agent: {
|
|
17
|
-
type: "string",
|
|
18
|
-
enum: ["general", "explore", "plan", "code", "research", "verify"],
|
|
19
|
-
description: "Sub-agent type to fork:\n" +
|
|
20
|
-
"- general: Full tool access, any task\n" +
|
|
21
|
-
"- explore: Read-only codebase exploration (search, read, analyze)\n" +
|
|
22
|
-
"- plan: Planning mode (explore + produce plan, no writes)\n" +
|
|
23
|
-
"- code: Coding agent with full tool access\n" +
|
|
24
|
-
"- research: Web research and information gathering\n" +
|
|
25
|
-
"- verify: Run tests, check builds, validate changes",
|
|
26
|
-
},
|
|
27
|
-
prompt: {
|
|
28
|
-
type: "string",
|
|
29
|
-
description: "Detailed task for the sub-agent. The sub-agent shares your conversation " +
|
|
30
|
-
"history as context (prompt cache shared). Be specific about what " +
|
|
31
|
-
"information to return in the final response.",
|
|
32
|
-
},
|
|
33
|
-
description: {
|
|
34
|
-
type: "string",
|
|
35
|
-
description: "Short description (3-7 words) for status tracking.",
|
|
36
|
-
},
|
|
37
|
-
maxTurns: {
|
|
38
|
-
type: "number",
|
|
39
|
-
description: "Max turns for the sub-agent. Defaults: general=200, explore=50, plan=80, code=200, research=30, verify=40.",
|
|
40
|
-
},
|
|
41
|
-
background: {
|
|
42
|
-
type: "boolean",
|
|
43
|
-
description: "If true, runs in background and returns a task_id. Poll with task tool. Default: false.",
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
required: ["agent", "prompt"],
|
|
47
|
-
additionalProperties: false,
|
|
48
|
-
};
|
|
49
|
-
/** Maximum fork depth for in-memory agents. */
|
|
50
|
-
export const MAX_FORK_DEPTH = 4;
|
|
51
|
-
export function createAgentTool(deps) {
|
|
52
|
-
return {
|
|
53
|
-
name: AGENT_TOOL_NAME,
|
|
54
|
-
label: "Sub-Agent",
|
|
55
|
-
description: "Fork a sub-agent to handle complex tasks autonomously. " +
|
|
56
|
-
"Sub-agents share your conversation context (prompt cache) and " +
|
|
57
|
-
"have isolated tool state. Use for: parallel research, code exploration, " +
|
|
58
|
-
"testing, delegating large tasks to specialized agents.",
|
|
59
|
-
parameters: AGENT_TOOL_SCHEMA,
|
|
60
|
-
searchHint: "fork subagent delegate spawn child parallel worker",
|
|
61
|
-
isConcurrencySafe: true,
|
|
62
|
-
execute: async (_toolCallId, params) => {
|
|
63
|
-
// Validate prompt
|
|
64
|
-
if (!params.prompt || params.prompt.trim().length < 10) {
|
|
65
|
-
return {
|
|
66
|
-
content: [{ type: "text", text: "Error: prompt must be at least 10 characters." }],
|
|
67
|
-
details: { type: "agent", error: "prompt_too_short" },
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
// Validate agent type
|
|
71
|
-
if (!BUILT_IN_AGENT_TYPES.includes(params.agent)) {
|
|
72
|
-
return {
|
|
73
|
-
content: [{
|
|
74
|
-
type: "text",
|
|
75
|
-
text: `Error: unknown agent "${params.agent}". Available: ${BUILT_IN_AGENT_TYPES.join(", ")}`,
|
|
76
|
-
}],
|
|
77
|
-
details: { type: "agent", error: "invalid_agent_type" },
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
// Fork depth guard
|
|
81
|
-
const depth = deps.currentForkDepth ?? 0;
|
|
82
|
-
if (depth >= MAX_FORK_DEPTH) {
|
|
83
|
-
return {
|
|
84
|
-
content: [{
|
|
85
|
-
type: "text",
|
|
86
|
-
text: `Error: maximum fork depth (${MAX_FORK_DEPTH}) reached. Cannot spawn more sub-agents. Complete current work instead.`,
|
|
87
|
-
}],
|
|
88
|
-
details: { type: "agent", error: "max_depth_reached", depth },
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
try {
|
|
92
|
-
const result = await deps.forkAgent({
|
|
93
|
-
agent: params.agent,
|
|
94
|
-
prompt: params.prompt.trim(),
|
|
95
|
-
description: params.description,
|
|
96
|
-
maxTurns: params.maxTurns,
|
|
97
|
-
background: params.background,
|
|
98
|
-
abortSignal: deps.abortSignal,
|
|
99
|
-
});
|
|
100
|
-
// Background mode — return task reference
|
|
101
|
-
if (params.background && result.status === "running") {
|
|
102
|
-
return {
|
|
103
|
-
content: [{
|
|
104
|
-
type: "text",
|
|
105
|
-
text: `Sub-agent "${params.agent}" started in background.\nAgent ID: ${result.agentId}\nUse task tool with this ID to check status and get output.`,
|
|
106
|
-
}],
|
|
107
|
-
details: { type: "agent", agentId: result.agentId, status: "running", background: true },
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
// Failed
|
|
111
|
-
if (result.status === "failed") {
|
|
112
|
-
return {
|
|
113
|
-
content: [{ type: "text", text: `Sub-agent failed: ${result.error || "unknown error"}` }],
|
|
114
|
-
details: { type: "agent", agentId: result.agentId, status: "failed", error: result.error },
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
// Completed — return output with metadata
|
|
118
|
-
const output = result.output || "(sub-agent returned no output)";
|
|
119
|
-
const suffix = result.maxTurnsReached
|
|
120
|
-
? "\n\n[Note: Sub-agent reached turn limit. Output may be incomplete.]"
|
|
121
|
-
: "";
|
|
122
|
-
return {
|
|
123
|
-
content: [{ type: "text", text: output + suffix }],
|
|
124
|
-
details: {
|
|
125
|
-
type: "agent",
|
|
126
|
-
agentId: result.agentId,
|
|
127
|
-
status: "completed",
|
|
128
|
-
tokensUsed: result.tokensUsed,
|
|
129
|
-
maxTurnsReached: result.maxTurnsReached,
|
|
130
|
-
},
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
catch (err) {
|
|
134
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
135
|
-
return {
|
|
136
|
-
content: [{ type: "text", text: `Sub-agent execution failed: ${msg}` }],
|
|
137
|
-
details: { type: "agent", error: "execution_error", message: msg },
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
},
|
|
141
|
-
};
|
|
142
|
-
}
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// Apply Patch Tool — apply unified diff patches to files.
|
|
3
|
-
// Category: coding
|
|
4
|
-
// ============================================================
|
|
5
|
-
export const APPLY_PATCH_TOOL_NAME = "apply_patch";
|
|
6
|
-
export const APPLY_PATCH_TOOL_SCHEMA = {
|
|
7
|
-
type: "object",
|
|
8
|
-
properties: {
|
|
9
|
-
input: {
|
|
10
|
-
type: "string",
|
|
11
|
-
description: "Patch content using the *** Begin Patch / *** End Patch format.",
|
|
12
|
-
},
|
|
13
|
-
},
|
|
14
|
-
required: ["input"],
|
|
15
|
-
};
|
|
16
|
-
function parsePatch(input) {
|
|
17
|
-
const lines = input.split("\n");
|
|
18
|
-
const ops = [];
|
|
19
|
-
let current = null;
|
|
20
|
-
let currentHunk = null;
|
|
21
|
-
let inPatch = false;
|
|
22
|
-
for (const line of lines) {
|
|
23
|
-
if (line.startsWith("*** Begin Patch")) {
|
|
24
|
-
inPatch = true;
|
|
25
|
-
continue;
|
|
26
|
-
}
|
|
27
|
-
if (line.startsWith("*** End Patch")) {
|
|
28
|
-
break;
|
|
29
|
-
}
|
|
30
|
-
if (!inPatch)
|
|
31
|
-
continue;
|
|
32
|
-
if (line.startsWith("*** Add File: ")) {
|
|
33
|
-
if (current)
|
|
34
|
-
ops.push(current);
|
|
35
|
-
current = { type: "add", path: line.slice("*** Add File: ".length).trim(), hunks: [] };
|
|
36
|
-
currentHunk = { contextBefore: [], removals: [], additions: [], contextAfter: [] };
|
|
37
|
-
current.hunks.push(currentHunk);
|
|
38
|
-
}
|
|
39
|
-
else if (line.startsWith("*** Update File: ")) {
|
|
40
|
-
if (current)
|
|
41
|
-
ops.push(current);
|
|
42
|
-
current = { type: "update", path: line.slice("*** Update File: ".length).trim(), hunks: [] };
|
|
43
|
-
currentHunk = null;
|
|
44
|
-
}
|
|
45
|
-
else if (line.startsWith("*** Delete File: ")) {
|
|
46
|
-
if (current)
|
|
47
|
-
ops.push(current);
|
|
48
|
-
current = { type: "delete", path: line.slice("*** Delete File: ".length).trim(), hunks: [] };
|
|
49
|
-
currentHunk = null;
|
|
50
|
-
}
|
|
51
|
-
else if (line.startsWith("*** Move to: ") && current) {
|
|
52
|
-
current.moveTo = line.slice("*** Move to: ".length).trim();
|
|
53
|
-
}
|
|
54
|
-
else if (line.startsWith("@@ ") && current) {
|
|
55
|
-
currentHunk = { contextBefore: [], removals: [], additions: [], contextAfter: [] };
|
|
56
|
-
current.hunks.push(currentHunk);
|
|
57
|
-
}
|
|
58
|
-
else if (currentHunk) {
|
|
59
|
-
if (line.startsWith("+")) {
|
|
60
|
-
currentHunk.additions.push(line.slice(1));
|
|
61
|
-
}
|
|
62
|
-
else if (line.startsWith("-")) {
|
|
63
|
-
currentHunk.removals.push(line.slice(1));
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
// context line (space prefix or bare)
|
|
67
|
-
const ctx = line.startsWith(" ") ? line.slice(1) : line;
|
|
68
|
-
if (currentHunk.additions.length === 0 && currentHunk.removals.length === 0) {
|
|
69
|
-
currentHunk.contextBefore.push(ctx);
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
currentHunk.contextAfter.push(ctx);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
if (current)
|
|
78
|
-
ops.push(current);
|
|
79
|
-
return ops;
|
|
80
|
-
}
|
|
81
|
-
function applyHunksToContent(content, hunks) {
|
|
82
|
-
const lines = content.split("\n");
|
|
83
|
-
let result = [...lines];
|
|
84
|
-
for (const hunk of hunks) {
|
|
85
|
-
// Find context match position
|
|
86
|
-
let matchStart = -1;
|
|
87
|
-
if (hunk.contextBefore.length > 0) {
|
|
88
|
-
for (let i = 0; i <= result.length - hunk.contextBefore.length; i++) {
|
|
89
|
-
let matches = true;
|
|
90
|
-
for (let j = 0; j < hunk.contextBefore.length; j++) {
|
|
91
|
-
if (result[i + j] !== hunk.contextBefore[j]) {
|
|
92
|
-
matches = false;
|
|
93
|
-
break;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
if (matches) {
|
|
97
|
-
matchStart = i + hunk.contextBefore.length;
|
|
98
|
-
break;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
else {
|
|
103
|
-
matchStart = 0;
|
|
104
|
-
}
|
|
105
|
-
if (matchStart === -1)
|
|
106
|
-
continue;
|
|
107
|
-
// Remove old lines
|
|
108
|
-
if (hunk.removals.length > 0) {
|
|
109
|
-
result.splice(matchStart, hunk.removals.length, ...hunk.additions);
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
result.splice(matchStart, 0, ...hunk.additions);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
return result.join("\n");
|
|
116
|
-
}
|
|
117
|
-
export function createApplyPatchTool(deps) {
|
|
118
|
-
return {
|
|
119
|
-
name: APPLY_PATCH_TOOL_NAME,
|
|
120
|
-
label: "Apply Patch",
|
|
121
|
-
description: "Apply a patch to one or more files using the *** Begin Patch / *** End Patch format. " +
|
|
122
|
-
"Supports Add File, Update File, Delete File, and Move To operations.",
|
|
123
|
-
parameters: APPLY_PATCH_TOOL_SCHEMA,
|
|
124
|
-
execute: async (_toolCallId, params) => {
|
|
125
|
-
const ops = parsePatch(params.input);
|
|
126
|
-
if (ops.length === 0) {
|
|
127
|
-
return {
|
|
128
|
-
content: [{ type: "text", text: "Error: No valid patch operations found. Ensure *** Begin Patch / *** End Patch markers are present." }],
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
const summary = { added: [], modified: [], deleted: [] };
|
|
132
|
-
const errors = [];
|
|
133
|
-
for (const op of ops) {
|
|
134
|
-
const resolved = deps.resolvePath(op.path);
|
|
135
|
-
try {
|
|
136
|
-
switch (op.type) {
|
|
137
|
-
case "add": {
|
|
138
|
-
const newContent = op.hunks.flatMap((h) => [...h.additions]).join("\n");
|
|
139
|
-
await deps.writeFile(resolved, newContent);
|
|
140
|
-
summary.added.push(op.path);
|
|
141
|
-
break;
|
|
142
|
-
}
|
|
143
|
-
case "update": {
|
|
144
|
-
const existing = await deps.readFile(resolved);
|
|
145
|
-
const patched = applyHunksToContent(existing, op.hunks);
|
|
146
|
-
if (op.moveTo) {
|
|
147
|
-
const dest = deps.resolvePath(op.moveTo);
|
|
148
|
-
await deps.writeFile(dest, patched);
|
|
149
|
-
await deps.deleteFile(resolved);
|
|
150
|
-
summary.modified.push(`${op.path} → ${op.moveTo}`);
|
|
151
|
-
}
|
|
152
|
-
else {
|
|
153
|
-
await deps.writeFile(resolved, patched);
|
|
154
|
-
summary.modified.push(op.path);
|
|
155
|
-
}
|
|
156
|
-
break;
|
|
157
|
-
}
|
|
158
|
-
case "delete": {
|
|
159
|
-
await deps.deleteFile(resolved);
|
|
160
|
-
summary.deleted.push(op.path);
|
|
161
|
-
break;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
catch (err) {
|
|
166
|
-
errors.push(`${op.type} ${op.path}: ${err instanceof Error ? err.message : String(err)}`);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
const parts = [];
|
|
170
|
-
if (summary.added.length)
|
|
171
|
-
parts.push(`Added: ${summary.added.join(", ")}`);
|
|
172
|
-
if (summary.modified.length)
|
|
173
|
-
parts.push(`Modified: ${summary.modified.join(", ")}`);
|
|
174
|
-
if (summary.deleted.length)
|
|
175
|
-
parts.push(`Deleted: ${summary.deleted.join(", ")}`);
|
|
176
|
-
if (errors.length)
|
|
177
|
-
parts.push(`Errors: ${errors.join("; ")}`);
|
|
178
|
-
return {
|
|
179
|
-
content: [{ type: "text", text: parts.join("\n") || "No changes applied." }],
|
|
180
|
-
details: { type: "apply_patch", summary, errors },
|
|
181
|
-
};
|
|
182
|
-
},
|
|
183
|
-
};
|
|
184
|
-
}
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// Ask User Tool — ask the user clarifying questions.
|
|
3
|
-
// Reference: claude-code-haha/src/tools/AskUserQuestionTool/AskUserQuestionTool.tsx
|
|
4
|
-
// Category: interaction
|
|
5
|
-
// ============================================================
|
|
6
|
-
export const ASK_USER_TOOL_NAME = "ask_user";
|
|
7
|
-
export const ASK_USER_TOOL_SCHEMA = {
|
|
8
|
-
type: "object",
|
|
9
|
-
properties: {
|
|
10
|
-
questions: {
|
|
11
|
-
type: "array",
|
|
12
|
-
minItems: 1,
|
|
13
|
-
maxItems: 4,
|
|
14
|
-
description: "1-4 clarifying questions to ask the user.",
|
|
15
|
-
items: {
|
|
16
|
-
type: "object",
|
|
17
|
-
properties: {
|
|
18
|
-
question: {
|
|
19
|
-
type: "string",
|
|
20
|
-
description: "The question text. Should end with '?'.",
|
|
21
|
-
},
|
|
22
|
-
header: {
|
|
23
|
-
type: "string",
|
|
24
|
-
description: "Short identifier/tag for this question (max 50 chars).",
|
|
25
|
-
},
|
|
26
|
-
options: {
|
|
27
|
-
type: "array",
|
|
28
|
-
description: "2-4 options for the user to choose from. Omit for free text.",
|
|
29
|
-
items: {
|
|
30
|
-
type: "object",
|
|
31
|
-
properties: {
|
|
32
|
-
label: {
|
|
33
|
-
type: "string",
|
|
34
|
-
description: "Display label (1-5 words).",
|
|
35
|
-
},
|
|
36
|
-
description: {
|
|
37
|
-
type: "string",
|
|
38
|
-
description: "Brief explanation of this option.",
|
|
39
|
-
},
|
|
40
|
-
},
|
|
41
|
-
required: ["label"],
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
multiSelect: {
|
|
45
|
-
type: "boolean",
|
|
46
|
-
description: "Allow selecting multiple options (default: false).",
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
required: ["question", "header"],
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
required: ["questions"],
|
|
54
|
-
};
|
|
55
|
-
export function createAskUserTool(deps) {
|
|
56
|
-
return {
|
|
57
|
-
name: ASK_USER_TOOL_NAME,
|
|
58
|
-
label: "Ask User",
|
|
59
|
-
description: "Ask the user clarifying questions when you need more information to proceed. " +
|
|
60
|
-
"Supports free text questions and multiple-choice options. " +
|
|
61
|
-
"Use this when the user's intent is ambiguous or you need confirmation.",
|
|
62
|
-
parameters: ASK_USER_TOOL_SCHEMA,
|
|
63
|
-
execute: async (_toolCallId, params) => {
|
|
64
|
-
// Validate questions count
|
|
65
|
-
if (!params.questions || params.questions.length === 0) {
|
|
66
|
-
return {
|
|
67
|
-
content: [{ type: "text", text: "Error: at least one question is required." }],
|
|
68
|
-
details: { type: "ask_user", error: "no_questions" },
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
if (params.questions.length > 4) {
|
|
72
|
-
return {
|
|
73
|
-
content: [{ type: "text", text: "Error: maximum 4 questions allowed." }],
|
|
74
|
-
details: { type: "ask_user", error: "too_many_questions" },
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
// Validate unique question texts
|
|
78
|
-
const questionTexts = params.questions.map((q) => q.question);
|
|
79
|
-
if (new Set(questionTexts).size !== questionTexts.length) {
|
|
80
|
-
return {
|
|
81
|
-
content: [{ type: "text", text: "Error: all questions must have unique text." }],
|
|
82
|
-
details: { type: "ask_user", error: "duplicate_questions" },
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
// Validate options count and label uniqueness per question
|
|
86
|
-
for (const q of params.questions) {
|
|
87
|
-
if (q.options && (q.options.length < 2 || q.options.length > 4)) {
|
|
88
|
-
return {
|
|
89
|
-
content: [{ type: "text", text: `Error: question "${q.header}" must have 2-4 options (got ${q.options.length}).` }],
|
|
90
|
-
details: { type: "ask_user", error: "invalid_option_count" },
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
if (q.options) {
|
|
94
|
-
const labels = q.options.map((o) => o.label);
|
|
95
|
-
if (new Set(labels).size !== labels.length) {
|
|
96
|
-
return {
|
|
97
|
-
content: [{ type: "text", text: `Error: question "${q.header}" has duplicate option labels.` }],
|
|
98
|
-
details: { type: "ask_user", error: "duplicate_option_labels" },
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
const answers = await deps.askUser(params.questions);
|
|
104
|
-
if (answers === null) {
|
|
105
|
-
return {
|
|
106
|
-
content: [{ type: "text", text: "User declined to answer questions." }],
|
|
107
|
-
details: { type: "ask_user", declined: true },
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
const lines = ["User answered:"];
|
|
111
|
-
for (const q of params.questions) {
|
|
112
|
-
const answer = answers[q.question] ?? "(no answer)";
|
|
113
|
-
lines.push(`- ${q.header}: ${answer}`);
|
|
114
|
-
}
|
|
115
|
-
return {
|
|
116
|
-
content: [{ type: "text", text: lines.join("\n") }],
|
|
117
|
-
details: { type: "ask_user", answers, questionCount: params.questions.length },
|
|
118
|
-
};
|
|
119
|
-
},
|
|
120
|
-
};
|
|
121
|
-
}
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// Brief Tool — "SendUserMessage" equivalent from Claude Code.
|
|
3
|
-
//
|
|
4
|
-
// In brief/chat mode, agent output is not directly visible to
|
|
5
|
-
// the user. Only messages sent through this tool are displayed.
|
|
6
|
-
// This enables clean separation of internal reasoning vs
|
|
7
|
-
// user-facing communication.
|
|
8
|
-
//
|
|
9
|
-
// Reference: claude-code-haha/src/tools/BriefTool/BriefTool.ts
|
|
10
|
-
// Category: interaction
|
|
11
|
-
// ============================================================
|
|
12
|
-
export const BRIEF_TOOL_NAME = "send_user_message";
|
|
13
|
-
export const BRIEF_TOOL_SCHEMA = {
|
|
14
|
-
type: "object",
|
|
15
|
-
properties: {
|
|
16
|
-
message: {
|
|
17
|
-
type: "string",
|
|
18
|
-
description: "The message to send to the user. Supports Markdown formatting. " +
|
|
19
|
-
"This is the ONLY way to communicate with the user in brief/chat mode.",
|
|
20
|
-
minLength: 1,
|
|
21
|
-
},
|
|
22
|
-
attachments: {
|
|
23
|
-
type: "array",
|
|
24
|
-
description: "Optional file paths to attach (images, documents, etc.).",
|
|
25
|
-
items: { type: "string" },
|
|
26
|
-
maxItems: 10,
|
|
27
|
-
},
|
|
28
|
-
status: {
|
|
29
|
-
type: "string",
|
|
30
|
-
enum: ["normal", "proactive"],
|
|
31
|
-
description: "Message status. Use 'proactive' when providing unsolicited information " +
|
|
32
|
-
"(e.g., monitoring alerts, task completion notifications).",
|
|
33
|
-
},
|
|
34
|
-
},
|
|
35
|
-
required: ["message"],
|
|
36
|
-
};
|
|
37
|
-
export function createBriefTool(deps) {
|
|
38
|
-
return {
|
|
39
|
-
name: BRIEF_TOOL_NAME,
|
|
40
|
-
label: "Send User Message",
|
|
41
|
-
description: "Send a message to the user. In brief/chat mode this is the ONLY way " +
|
|
42
|
-
"your messages are visible. Supports Markdown and file attachments. " +
|
|
43
|
-
"Use 'proactive' status for unsolicited updates (monitoring alerts, " +
|
|
44
|
-
"task completions). Keep messages concise and useful.",
|
|
45
|
-
parameters: BRIEF_TOOL_SCHEMA,
|
|
46
|
-
isConcurrencySafe: true,
|
|
47
|
-
isReadOnly: true,
|
|
48
|
-
searchHint: "send message user brief chat communicate display output",
|
|
49
|
-
execute: async (_toolCallId, params) => {
|
|
50
|
-
if (!params.message || params.message.trim().length === 0) {
|
|
51
|
-
return {
|
|
52
|
-
content: [{ type: "text", text: "Error: message cannot be empty." }],
|
|
53
|
-
details: { type: "brief", error: "empty_message" },
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
// Resolve attachments if provided
|
|
57
|
-
let resolvedAttachments;
|
|
58
|
-
if (params.attachments && params.attachments.length > 0) {
|
|
59
|
-
if (deps.resolveAttachments) {
|
|
60
|
-
const resolved = await deps.resolveAttachments(params.attachments);
|
|
61
|
-
if ("error" in resolved) {
|
|
62
|
-
return {
|
|
63
|
-
content: [{ type: "text", text: `Attachment error: ${resolved.error}` }],
|
|
64
|
-
details: { type: "brief", error: "attachment_resolution_failed" },
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
resolvedAttachments = resolved;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
const status = params.status || "normal";
|
|
71
|
-
const result = await deps.deliverMessage({
|
|
72
|
-
message: params.message.trim(),
|
|
73
|
-
attachments: params.attachments,
|
|
74
|
-
status,
|
|
75
|
-
});
|
|
76
|
-
if (!result.delivered) {
|
|
77
|
-
return {
|
|
78
|
-
content: [{ type: "text", text: `Message delivery failed: ${result.error || "unknown error"}` }],
|
|
79
|
-
details: { type: "brief", delivered: false, error: result.error },
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
// Minimal confirmation — avoids re-echoing message in context (saves tokens)
|
|
83
|
-
return {
|
|
84
|
-
content: [{ type: "text", text: "Message delivered to user." }],
|
|
85
|
-
details: {
|
|
86
|
-
type: "brief",
|
|
87
|
-
delivered: true,
|
|
88
|
-
status,
|
|
89
|
-
hasAttachments: (resolvedAttachments?.length ?? 0) > 0,
|
|
90
|
-
sentAt: result.sentAt,
|
|
91
|
-
},
|
|
92
|
-
};
|
|
93
|
-
},
|
|
94
|
-
};
|
|
95
|
-
}
|