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,153 +0,0 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// Skill Manage Tool â create/edit/delete skills.
|
|
3
|
-
// Reference: hermes-agent-2026.4.30/tools/skill_manager_tool.py
|
|
4
|
-
// Category: skill
|
|
5
|
-
// ============================================================
|
|
6
|
-
export const SKILL_MANAGE_TOOL_NAME = "skill_manage";
|
|
7
|
-
export const SKILL_MANAGE_TOOL_SCHEMA = {
|
|
8
|
-
type: "object",
|
|
9
|
-
properties: {
|
|
10
|
-
action: {
|
|
11
|
-
type: "string",
|
|
12
|
-
enum: ["create", "edit", "patch", "delete", "write_file", "remove_file"],
|
|
13
|
-
description: "Action to perform: create (new skill), edit (overwrite SKILL.md), " +
|
|
14
|
-
"patch (find/replace in SKILL.md), delete (remove skill), " +
|
|
15
|
-
"write_file (add/overwrite supporting file), remove_file (delete supporting file).",
|
|
16
|
-
},
|
|
17
|
-
name: {
|
|
18
|
-
type: "string",
|
|
19
|
-
description: "Skill name (lowercase, max 64 chars, kebab-case: letters, digits, hyphens).",
|
|
20
|
-
},
|
|
21
|
-
content: {
|
|
22
|
-
type: "string",
|
|
23
|
-
description: "Full SKILL.md content (YAML frontmatter + body). Required for create/edit. " +
|
|
24
|
-
"Max 100,000 chars. Must include ---\\nname: ...\\ndescription: ...\\n--- header.",
|
|
25
|
-
},
|
|
26
|
-
category: {
|
|
27
|
-
type: "string",
|
|
28
|
-
description: "Category/domain (e.g. 'devops', 'mlops'). Used by create to organize skills.",
|
|
29
|
-
},
|
|
30
|
-
filePath: {
|
|
31
|
-
type: "string",
|
|
32
|
-
description: "Path within the skill for write_file/remove_file. " +
|
|
33
|
-
"Must be in references/, templates/, scripts/, or assets/ subdirectory.",
|
|
34
|
-
},
|
|
35
|
-
fileContent: {
|
|
36
|
-
type: "string",
|
|
37
|
-
description: "Content for write_file action. Max 1 MiB.",
|
|
38
|
-
},
|
|
39
|
-
oldString: {
|
|
40
|
-
type: "string",
|
|
41
|
-
description: "Text to find for patch action (must match uniquely in SKILL.md).",
|
|
42
|
-
},
|
|
43
|
-
newString: {
|
|
44
|
-
type: "string",
|
|
45
|
-
description: "Replacement text for patch action (can be empty to delete).",
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
required: ["action", "name"],
|
|
49
|
-
};
|
|
50
|
-
const NAME_PATTERN = /^[a-z0-9][a-z0-9._-]{0,63}$/;
|
|
51
|
-
const MAX_CONTENT_LENGTH = 100_000;
|
|
52
|
-
const MAX_FILE_CONTENT_LENGTH = 1_048_576; // 1 MiB
|
|
53
|
-
const ALLOWED_FILE_DIRS = ["references/", "templates/", "scripts/", "assets/"];
|
|
54
|
-
export function createSkillManageTool(deps) {
|
|
55
|
-
return {
|
|
56
|
-
name: SKILL_MANAGE_TOOL_NAME,
|
|
57
|
-
label: "Manage Skills",
|
|
58
|
-
description: "Create, edit, patch, or delete skills. Skills are reusable workflows/knowledge packages " +
|
|
59
|
-
"that can be discovered and invoked. Supports managing supporting files (references, templates).",
|
|
60
|
-
parameters: SKILL_MANAGE_TOOL_SCHEMA,
|
|
61
|
-
execute: async (_toolCallId, params) => {
|
|
62
|
-
// Validate name
|
|
63
|
-
const nameError = deps.validateName
|
|
64
|
-
? deps.validateName(params.name)
|
|
65
|
-
: validateNameBuiltin(params.name);
|
|
66
|
-
if (nameError) {
|
|
67
|
-
return {
|
|
68
|
-
content: [{ type: "text", text: `Error: ${nameError}` }],
|
|
69
|
-
details: { type: "skill_manage", error: "invalid_name" },
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
// Action-specific validation
|
|
73
|
-
const validationError = validateAction(params);
|
|
74
|
-
if (validationError) {
|
|
75
|
-
return {
|
|
76
|
-
content: [{ type: "text", text: `Error: ${validationError}` }],
|
|
77
|
-
details: { type: "skill_manage", error: "validation_failed" },
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
const result = await deps.manageSkill(params);
|
|
81
|
-
return {
|
|
82
|
-
content: [{ type: "text", text: result.message }],
|
|
83
|
-
details: {
|
|
84
|
-
type: "skill_manage",
|
|
85
|
-
action: params.action,
|
|
86
|
-
name: params.name,
|
|
87
|
-
success: result.success,
|
|
88
|
-
path: result.path,
|
|
89
|
-
},
|
|
90
|
-
};
|
|
91
|
-
},
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
function validateNameBuiltin(name) {
|
|
95
|
-
if (!name)
|
|
96
|
-
return "name is required.";
|
|
97
|
-
if (!NAME_PATTERN.test(name)) {
|
|
98
|
-
return "name must be lowercase, start with letter/digit, contain only letters, digits, hyphens, dots, underscores (max 64 chars).";
|
|
99
|
-
}
|
|
100
|
-
return null;
|
|
101
|
-
}
|
|
102
|
-
function validateAction(params) {
|
|
103
|
-
switch (params.action) {
|
|
104
|
-
case "create":
|
|
105
|
-
case "edit":
|
|
106
|
-
if (!params.content)
|
|
107
|
-
return `content is required for ${params.action}.`;
|
|
108
|
-
if (params.content.length > MAX_CONTENT_LENGTH) {
|
|
109
|
-
return `content exceeds max length (${MAX_CONTENT_LENGTH} chars).`;
|
|
110
|
-
}
|
|
111
|
-
if (!params.content.includes("---")) {
|
|
112
|
-
return "content must include YAML frontmatter (--- delimiters).";
|
|
113
|
-
}
|
|
114
|
-
break;
|
|
115
|
-
case "patch":
|
|
116
|
-
if (!params.oldString)
|
|
117
|
-
return "oldString is required for patch.";
|
|
118
|
-
if (params.newString === undefined)
|
|
119
|
-
return "newString is required for patch (can be empty to delete).";
|
|
120
|
-
break;
|
|
121
|
-
case "write_file":
|
|
122
|
-
if (!params.filePath)
|
|
123
|
-
return "filePath is required for write_file.";
|
|
124
|
-
if (!params.fileContent)
|
|
125
|
-
return "fileContent is required for write_file.";
|
|
126
|
-
if (params.fileContent.length > MAX_FILE_CONTENT_LENGTH) {
|
|
127
|
-
return "fileContent exceeds max length (1 MiB).";
|
|
128
|
-
}
|
|
129
|
-
if (!ALLOWED_FILE_DIRS.some((d) => params.filePath.startsWith(d))) {
|
|
130
|
-
return `filePath must be in one of: ${ALLOWED_FILE_DIRS.join(", ")}`;
|
|
131
|
-
}
|
|
132
|
-
if (params.filePath.includes("..")) {
|
|
133
|
-
return "filePath must not contain path traversal (..).";
|
|
134
|
-
}
|
|
135
|
-
break;
|
|
136
|
-
case "remove_file":
|
|
137
|
-
if (!params.filePath)
|
|
138
|
-
return "filePath is required for remove_file.";
|
|
139
|
-
if (!ALLOWED_FILE_DIRS.some((d) => params.filePath.startsWith(d))) {
|
|
140
|
-
return `filePath must be in one of: ${ALLOWED_FILE_DIRS.join(", ")}`;
|
|
141
|
-
}
|
|
142
|
-
if (params.filePath.includes("..")) {
|
|
143
|
-
return "filePath must not contain path traversal (..).";
|
|
144
|
-
}
|
|
145
|
-
break;
|
|
146
|
-
case "delete":
|
|
147
|
-
// No extra validation needed
|
|
148
|
-
break;
|
|
149
|
-
default:
|
|
150
|
-
return `unknown action: ${params.action}`;
|
|
151
|
-
}
|
|
152
|
-
return null;
|
|
153
|
-
}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// Skill View Tool â view full skill content.
|
|
3
|
-
// Reference: hermes-agent-2026.4.30/tools/skills_tool.py (skill_view)
|
|
4
|
-
// Category: skill
|
|
5
|
-
// ============================================================
|
|
6
|
-
export const SKILL_VIEW_TOOL_NAME = "skill_view";
|
|
7
|
-
export const SKILL_VIEW_TOOL_SCHEMA = {
|
|
8
|
-
type: "object",
|
|
9
|
-
properties: {
|
|
10
|
-
name: {
|
|
11
|
-
type: "string",
|
|
12
|
-
description: "Skill name to view (e.g. 'code-review', 'deploy-ecs').",
|
|
13
|
-
},
|
|
14
|
-
filePath: {
|
|
15
|
-
type: "string",
|
|
16
|
-
description: "Optional: view a specific file within the skill (e.g. 'references/api.md'). " +
|
|
17
|
-
"Omit to view the main SKILL.md.",
|
|
18
|
-
},
|
|
19
|
-
},
|
|
20
|
-
required: ["name"],
|
|
21
|
-
};
|
|
22
|
-
export function createSkillViewTool(deps) {
|
|
23
|
-
return {
|
|
24
|
-
name: SKILL_VIEW_TOOL_NAME,
|
|
25
|
-
label: "View Skill",
|
|
26
|
-
description: "View the full content of a skill (instructions, configuration, reference files). " +
|
|
27
|
-
"Use skill_list to discover available skills first.",
|
|
28
|
-
parameters: SKILL_VIEW_TOOL_SCHEMA,
|
|
29
|
-
execute: async (_toolCallId, params) => {
|
|
30
|
-
if (!params.name || params.name.trim().length === 0) {
|
|
31
|
-
return {
|
|
32
|
-
content: [{ type: "text", text: "Error: skill name is required." }],
|
|
33
|
-
details: { type: "skill_view", error: "empty_name" },
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
const result = await deps.viewSkill(params.name.trim(), params.filePath);
|
|
37
|
-
if (!result) {
|
|
38
|
-
return {
|
|
39
|
-
content: [{
|
|
40
|
-
type: "text",
|
|
41
|
-
text: `Skill "${params.name}" not found. Use skill_list to see available skills.`,
|
|
42
|
-
}],
|
|
43
|
-
details: { type: "skill_view", error: "not_found", name: params.name },
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
const lines = [];
|
|
47
|
-
if (params.filePath) {
|
|
48
|
-
lines.push(`## ${result.name} / ${params.filePath}`);
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
lines.push(`## Skill: ${result.name}`);
|
|
52
|
-
if (result.tags && result.tags.length > 0) {
|
|
53
|
-
lines.push(`Tags: ${result.tags.join(", ")}`);
|
|
54
|
-
}
|
|
55
|
-
if (result.referenceFiles && result.referenceFiles.length > 0) {
|
|
56
|
-
lines.push(`Reference files: ${result.referenceFiles.join(", ")}`);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
lines.push("");
|
|
60
|
-
lines.push(result.content);
|
|
61
|
-
return {
|
|
62
|
-
content: [{ type: "text", text: lines.join("\n") }],
|
|
63
|
-
details: {
|
|
64
|
-
type: "skill_view",
|
|
65
|
-
name: result.name,
|
|
66
|
-
filePath: params.filePath,
|
|
67
|
-
referenceFiles: result.referenceFiles,
|
|
68
|
-
},
|
|
69
|
-
};
|
|
70
|
-
},
|
|
71
|
-
};
|
|
72
|
-
}
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// Sleep Tool â lightweight wait with tick/interrupt support.
|
|
3
|
-
// Reference: claude-code-haha/src/tools/SleepTool/prompt.ts
|
|
4
|
-
// Category: autonomous / proactive mode
|
|
5
|
-
// ============================================================
|
|
6
|
-
export const SLEEP_TOOL_NAME = "sleep";
|
|
7
|
-
export const SLEEP_TOOL_SCHEMA = {
|
|
8
|
-
type: "object",
|
|
9
|
-
properties: {
|
|
10
|
-
duration: {
|
|
11
|
-
type: "number",
|
|
12
|
-
description: "Duration to sleep in seconds (1â3600). Prefer short sleeps (10â60s) to stay responsive.",
|
|
13
|
-
minimum: 1,
|
|
14
|
-
maximum: 3600,
|
|
15
|
-
},
|
|
16
|
-
reason: {
|
|
17
|
-
type: "string",
|
|
18
|
-
description: "Brief reason for sleeping. Examples: \"waiting for build to finish\", " +
|
|
19
|
-
"\"nothing to do\", \"user asked to rest\".",
|
|
20
|
-
},
|
|
21
|
-
},
|
|
22
|
-
required: ["duration"],
|
|
23
|
-
};
|
|
24
|
-
export function createSleepTool(deps) {
|
|
25
|
-
return {
|
|
26
|
-
name: SLEEP_TOOL_NAME,
|
|
27
|
-
label: "Sleep",
|
|
28
|
-
shouldDefer: true,
|
|
29
|
-
isConcurrencySafe: true,
|
|
30
|
-
isReadOnly: true,
|
|
31
|
-
searchHint: "wait sleep rest idle tick proactive",
|
|
32
|
-
description: [
|
|
33
|
-
"Wait for a specified duration. The user can interrupt the sleep at any time.",
|
|
34
|
-
"",
|
|
35
|
-
"Use this when:",
|
|
36
|
-
"âĸ You have nothing useful to do right now",
|
|
37
|
-
"âĸ You're waiting for an external process to complete",
|
|
38
|
-
"âĸ The user tells you to sleep or rest",
|
|
39
|
-
"âĸ You receive a <tick> check-in with no actionable work",
|
|
40
|
-
"",
|
|
41
|
-
"Prefer this over `exec(sleep ...)` â it doesn't hold a shell process.",
|
|
42
|
-
"You can call this concurrently with other tools â it won't interfere with them.",
|
|
43
|
-
"",
|
|
44
|
-
"Each wake-up costs an API call, but the prompt cache expires after 5 minutes " +
|
|
45
|
-
"of inactivity â balance accordingly.",
|
|
46
|
-
].join("\n"),
|
|
47
|
-
parameters: SLEEP_TOOL_SCHEMA,
|
|
48
|
-
execute: async (_toolCallId, params, signal) => {
|
|
49
|
-
const durationSec = Math.max(1, Math.min(3600, Math.round(params.duration)));
|
|
50
|
-
const durationMs = durationSec * 1000;
|
|
51
|
-
// Create a child AbortController so we can forward the outer signal
|
|
52
|
-
const controller = new AbortController();
|
|
53
|
-
const onAbort = () => controller.abort();
|
|
54
|
-
signal?.addEventListener("abort", onAbort, { once: true });
|
|
55
|
-
// Handle pre-aborted signal
|
|
56
|
-
if (signal?.aborted)
|
|
57
|
-
controller.abort();
|
|
58
|
-
try {
|
|
59
|
-
const result = await deps.sleep(durationMs, controller.signal);
|
|
60
|
-
const lines = [];
|
|
61
|
-
if (result.interrupted) {
|
|
62
|
-
lines.push(`Sleep interrupted after ${result.sleptSeconds}s.`);
|
|
63
|
-
if (result.interruptReason) {
|
|
64
|
-
lines.push(`Reason: ${result.interruptReason}`);
|
|
65
|
-
}
|
|
66
|
-
lines.push("Check for new messages or tasks.");
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
lines.push(`Slept for ${result.sleptSeconds}s. Waking up.`);
|
|
70
|
-
}
|
|
71
|
-
return {
|
|
72
|
-
content: [{ type: "text", text: lines.join("\n") }],
|
|
73
|
-
details: { ...result, requestedSeconds: durationSec },
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
finally {
|
|
77
|
-
signal?.removeEventListener("abort", onAbort);
|
|
78
|
-
}
|
|
79
|
-
},
|
|
80
|
-
};
|
|
81
|
-
}
|
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// Structured Output Tool â validated JSON schema output for
|
|
3
|
-
// non-interactive (SDK/API) sessions.
|
|
4
|
-
// Reference: claude-code-haha/src/tools/SyntheticOutputTool/SyntheticOutputTool.ts
|
|
5
|
-
// Category: output / structured
|
|
6
|
-
// ============================================================
|
|
7
|
-
export const STRUCTURED_OUTPUT_TOOL_NAME = "structured_output";
|
|
8
|
-
/** Maximum content size for structured output results. */
|
|
9
|
-
export const STRUCTURED_OUTPUT_MAX_CHARS = 100_000;
|
|
10
|
-
/**
|
|
11
|
-
* Base schema â accepts any object.
|
|
12
|
-
* When used with createConfiguredStructuredOutputTool, the host overrides
|
|
13
|
-
* this with the actual JSON Schema from `response_format.json_schema`.
|
|
14
|
-
*/
|
|
15
|
-
export const STRUCTURED_OUTPUT_TOOL_SCHEMA = {
|
|
16
|
-
type: "object",
|
|
17
|
-
properties: {
|
|
18
|
-
data: {
|
|
19
|
-
type: "object",
|
|
20
|
-
description: "The structured JSON data to return as this turn's output. " +
|
|
21
|
-
"Must conform to the output schema specified for this session.",
|
|
22
|
-
additionalProperties: true,
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
|
-
required: ["data"],
|
|
26
|
-
};
|
|
27
|
-
/**
|
|
28
|
-
* Whether the structured output tool should be enabled for this session.
|
|
29
|
-
* CC equivalent: `isSyntheticOutputToolEnabled`.
|
|
30
|
-
*/
|
|
31
|
-
export function isStructuredOutputEnabled(opts) {
|
|
32
|
-
return opts.isNonInteractiveSession;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Create the base structured output tool with DI-based validation.
|
|
36
|
-
* This is the standard factory for runtime integration.
|
|
37
|
-
*/
|
|
38
|
-
export function createStructuredOutputTool(deps) {
|
|
39
|
-
return {
|
|
40
|
-
name: STRUCTURED_OUTPUT_TOOL_NAME,
|
|
41
|
-
label: "Structured Output",
|
|
42
|
-
shouldDefer: false,
|
|
43
|
-
isConcurrencySafe: true,
|
|
44
|
-
isReadOnly: true,
|
|
45
|
-
searchHint: "return the final response as structured JSON",
|
|
46
|
-
maxResultSizeChars: STRUCTURED_OUTPUT_MAX_CHARS,
|
|
47
|
-
description: [
|
|
48
|
-
"Return your final response as structured JSON data.",
|
|
49
|
-
"",
|
|
50
|
-
"Use this tool ONLY when the session requests structured output (via response_format).",
|
|
51
|
-
"You MUST call this tool exactly once at the end of your response to provide the structured output.",
|
|
52
|
-
"The data you provide must conform to the output JSON Schema specified for this session.",
|
|
53
|
-
"",
|
|
54
|
-
"Rules:",
|
|
55
|
-
"âĸ Call this exactly once at the end of your turn to deliver results",
|
|
56
|
-
"âĸ The data must be a valid JSON object matching the required schema",
|
|
57
|
-
"âĸ If validation fails, you'll see the errors â fix your data and try again",
|
|
58
|
-
"âĸ This is typically the last tool call in a turn",
|
|
59
|
-
].join("\n"),
|
|
60
|
-
parameters: STRUCTURED_OUTPUT_TOOL_SCHEMA,
|
|
61
|
-
execute: async (_toolCallId, params) => {
|
|
62
|
-
const schema = deps.getOutputSchema();
|
|
63
|
-
if (!schema) {
|
|
64
|
-
return {
|
|
65
|
-
content: [{
|
|
66
|
-
type: "text",
|
|
67
|
-
text: "Error: No output schema configured for this session. " +
|
|
68
|
-
"structured_output is only available when response_format.json_schema is specified.",
|
|
69
|
-
}],
|
|
70
|
-
details: { valid: false, error: "no_schema" },
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
const validation = deps.validateOutput(params.data);
|
|
74
|
-
if (!validation.valid) {
|
|
75
|
-
const errorLines = (validation.errors ?? []).map((e) => ` âĸ ${e.path || "/"}: ${e.message}`);
|
|
76
|
-
return {
|
|
77
|
-
content: [{
|
|
78
|
-
type: "text",
|
|
79
|
-
text: [
|
|
80
|
-
"Output does not match required schema:",
|
|
81
|
-
...errorLines,
|
|
82
|
-
].join("\n"),
|
|
83
|
-
}],
|
|
84
|
-
details: { valid: false, errors: validation.errors },
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
// Validation passed â deliver the output
|
|
88
|
-
await deps.deliverOutput(params.data);
|
|
89
|
-
return {
|
|
90
|
-
content: [{ type: "text", text: "Structured output provided successfully." }],
|
|
91
|
-
details: { valid: true, structured_output: params.data },
|
|
92
|
-
};
|
|
93
|
-
},
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
/** WeakMap cache for compiled schema tools (mirrors CC's toolCache). */
|
|
97
|
-
const configuredToolCache = new WeakMap();
|
|
98
|
-
/**
|
|
99
|
-
* Create a StructuredOutputTool configured with a specific JSON Schema.
|
|
100
|
-
* Mirrors CC's `createSyntheticOutputTool(jsonSchema)`.
|
|
101
|
-
*
|
|
102
|
-
* Features:
|
|
103
|
-
* - Validates the schema itself at creation time
|
|
104
|
-
* - Compiles the validator for reuse (cached via WeakMap)
|
|
105
|
-
* - Overrides the tool's `parameters` with the provided schema (dynamic input)
|
|
106
|
-
* - Returns { tool } on success or { error } if schema is invalid
|
|
107
|
-
*
|
|
108
|
-
* @param jsonSchema The JSON Schema to validate output against.
|
|
109
|
-
* @param compiler Schema compiler/validator provided by the host.
|
|
110
|
-
* @param deliver Output delivery function (called after successful validation).
|
|
111
|
-
*/
|
|
112
|
-
export function createConfiguredStructuredOutputTool(jsonSchema, compiler, deliver) {
|
|
113
|
-
const cached = configuredToolCache.get(jsonSchema);
|
|
114
|
-
if (cached)
|
|
115
|
-
return cached;
|
|
116
|
-
const result = buildConfiguredTool(jsonSchema, compiler, deliver);
|
|
117
|
-
configuredToolCache.set(jsonSchema, result);
|
|
118
|
-
return result;
|
|
119
|
-
}
|
|
120
|
-
function buildConfiguredTool(jsonSchema, compiler, deliver) {
|
|
121
|
-
try {
|
|
122
|
-
// Step 1: Validate the schema itself
|
|
123
|
-
const schemaError = compiler.validateSchema(jsonSchema);
|
|
124
|
-
if (schemaError) {
|
|
125
|
-
return { error: `Invalid JSON Schema: ${schemaError}` };
|
|
126
|
-
}
|
|
127
|
-
// Step 2: Compile the validator
|
|
128
|
-
const validate = compiler.compile(jsonSchema);
|
|
129
|
-
// Step 3: Build the tool with dynamic input schema
|
|
130
|
-
const tool = {
|
|
131
|
-
name: STRUCTURED_OUTPUT_TOOL_NAME,
|
|
132
|
-
label: "Structured Output",
|
|
133
|
-
shouldDefer: false,
|
|
134
|
-
isConcurrencySafe: true,
|
|
135
|
-
isReadOnly: true,
|
|
136
|
-
searchHint: "return the final response as structured JSON",
|
|
137
|
-
maxResultSizeChars: STRUCTURED_OUTPUT_MAX_CHARS,
|
|
138
|
-
description: [
|
|
139
|
-
"Use this tool to return your final response in the requested structured format.",
|
|
140
|
-
"You MUST call this tool exactly once at the end of your response to provide the structured output.",
|
|
141
|
-
].join(" "),
|
|
142
|
-
// Dynamic: override with the actual JSON Schema so LLM gets type guidance
|
|
143
|
-
parameters: {
|
|
144
|
-
type: "object",
|
|
145
|
-
properties: {
|
|
146
|
-
data: jsonSchema,
|
|
147
|
-
},
|
|
148
|
-
required: ["data"],
|
|
149
|
-
},
|
|
150
|
-
execute: async (_toolCallId, params) => {
|
|
151
|
-
const validation = validate(params.data);
|
|
152
|
-
if (!validation.valid) {
|
|
153
|
-
const errors = (validation.errors ?? [])
|
|
154
|
-
.map((e) => `${e.path || "root"}: ${e.message}`)
|
|
155
|
-
.join(", ");
|
|
156
|
-
return {
|
|
157
|
-
content: [{
|
|
158
|
-
type: "text",
|
|
159
|
-
text: `Output does not match required schema: ${errors}`,
|
|
160
|
-
}],
|
|
161
|
-
details: { valid: false, errors: validation.errors },
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
await deliver(params.data);
|
|
165
|
-
return {
|
|
166
|
-
content: [{ type: "text", text: "Structured output provided successfully." }],
|
|
167
|
-
details: { valid: true, structured_output: params.data },
|
|
168
|
-
};
|
|
169
|
-
},
|
|
170
|
-
};
|
|
171
|
-
return { tool };
|
|
172
|
-
}
|
|
173
|
-
catch (e) {
|
|
174
|
-
return { error: e instanceof Error ? e.message : String(e) };
|
|
175
|
-
}
|
|
176
|
-
}
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// Task Tool â background agent task management (CRUD + output).
|
|
3
|
-
// Reference: claude-code-haha/src/tools/TaskCreateTool/TaskCreateTool.ts
|
|
4
|
-
// claude-code-haha/src/tools/TaskGetTool/TaskGetTool.ts
|
|
5
|
-
// claude-code-haha/src/tools/TaskListTool/TaskListTool.ts
|
|
6
|
-
// claude-code-haha/src/tools/TaskOutputTool/TaskOutputTool.tsx
|
|
7
|
-
// claude-code-haha/src/tools/TaskStopTool/TaskStopTool.ts
|
|
8
|
-
// Category: system
|
|
9
|
-
// ============================================================
|
|
10
|
-
export const TASK_TOOL_NAME = "task";
|
|
11
|
-
export const TASK_TOOL_SCHEMA = {
|
|
12
|
-
type: "object",
|
|
13
|
-
properties: {
|
|
14
|
-
action: {
|
|
15
|
-
type: "string",
|
|
16
|
-
enum: ["create", "get", "list", "output", "stop"],
|
|
17
|
-
description: "Action to perform:\n" +
|
|
18
|
-
"- create: Spawn a new background agent task\n" +
|
|
19
|
-
"- get: Get task status and metadata by ID\n" +
|
|
20
|
-
"- list: List all tasks with their statuses\n" +
|
|
21
|
-
"- output: Get stdout/output from a running or completed task\n" +
|
|
22
|
-
"- stop: Terminate a running task",
|
|
23
|
-
},
|
|
24
|
-
taskId: {
|
|
25
|
-
type: "string",
|
|
26
|
-
description: "Task ID. Required for get/output/stop.",
|
|
27
|
-
},
|
|
28
|
-
prompt: {
|
|
29
|
-
type: "string",
|
|
30
|
-
description: "Detailed prompt for the background agent. Must contain all context needed " +
|
|
31
|
-
"to complete the task independently. Required for create.",
|
|
32
|
-
},
|
|
33
|
-
description: {
|
|
34
|
-
type: "string",
|
|
35
|
-
description: "Short (3-7 word) description of the task. Used for tracking and display.",
|
|
36
|
-
},
|
|
37
|
-
allowedTools: {
|
|
38
|
-
type: "array",
|
|
39
|
-
items: { type: "string" },
|
|
40
|
-
description: "Restrict background agent to only these tools. If omitted, inherits parent's tools.",
|
|
41
|
-
},
|
|
42
|
-
cwd: {
|
|
43
|
-
type: "string",
|
|
44
|
-
description: "Working directory for the background task (absolute path).",
|
|
45
|
-
},
|
|
46
|
-
model: {
|
|
47
|
-
type: "string",
|
|
48
|
-
description: "Model override for the task agent (e.g. 'sonnet', 'opus').",
|
|
49
|
-
},
|
|
50
|
-
maxLines: {
|
|
51
|
-
type: "number",
|
|
52
|
-
description: "Max output lines to return for the 'output' action (default: 100).",
|
|
53
|
-
minimum: 1,
|
|
54
|
-
maximum: 2000,
|
|
55
|
-
},
|
|
56
|
-
},
|
|
57
|
-
required: ["action"],
|
|
58
|
-
};
|
|
59
|
-
const DEFAULT_MAX_LINES = 100;
|
|
60
|
-
export function createTaskTool(deps) {
|
|
61
|
-
return {
|
|
62
|
-
name: TASK_TOOL_NAME,
|
|
63
|
-
label: "Task",
|
|
64
|
-
shouldDefer: true,
|
|
65
|
-
description: "Manage background agent tasks. Use this to spawn long-running tasks (image generation, " +
|
|
66
|
-
"code refactoring, research) that run independently while you continue working. " +
|
|
67
|
-
"Actions: create (spawn), get (status check), list (all tasks), output (logs), stop (terminate).",
|
|
68
|
-
parameters: TASK_TOOL_SCHEMA,
|
|
69
|
-
execute: async (_toolCallId, params) => {
|
|
70
|
-
switch (params.action) {
|
|
71
|
-
case "create": {
|
|
72
|
-
if (!params.prompt || params.prompt.trim().length < 10) {
|
|
73
|
-
return {
|
|
74
|
-
content: [{ type: "text", text: "Error: 'prompt' is required for create (min 10 chars)." }],
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
const task = await deps.createTask({
|
|
78
|
-
prompt: params.prompt.trim(),
|
|
79
|
-
description: params.description,
|
|
80
|
-
allowedTools: params.allowedTools,
|
|
81
|
-
cwd: params.cwd,
|
|
82
|
-
model: params.model,
|
|
83
|
-
});
|
|
84
|
-
return {
|
|
85
|
-
content: [{
|
|
86
|
-
type: "text",
|
|
87
|
-
text: [
|
|
88
|
-
`Task created successfully.`,
|
|
89
|
-
`ID: ${task.taskId}`,
|
|
90
|
-
`Status: ${task.status}`,
|
|
91
|
-
task.description ? `Description: ${task.description}` : "",
|
|
92
|
-
].filter(Boolean).join("\n"),
|
|
93
|
-
}],
|
|
94
|
-
details: { type: "task", action: "create", taskId: task.taskId, status: task.status },
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
case "get": {
|
|
98
|
-
if (!params.taskId) {
|
|
99
|
-
return { content: [{ type: "text", text: "Error: 'taskId' is required for get." }] };
|
|
100
|
-
}
|
|
101
|
-
const task = await deps.getTask(params.taskId);
|
|
102
|
-
if (!task) {
|
|
103
|
-
return { content: [{ type: "text", text: `Error: task "${params.taskId}" not found.` }] };
|
|
104
|
-
}
|
|
105
|
-
const lines = [
|
|
106
|
-
`Task: ${task.taskId}`,
|
|
107
|
-
`Status: ${task.status}`,
|
|
108
|
-
task.description ? `Description: ${task.description}` : "",
|
|
109
|
-
`Created: ${new Date(task.createdAt).toISOString()}`,
|
|
110
|
-
task.completedAt ? `Completed: ${new Date(task.completedAt).toISOString()}` : "",
|
|
111
|
-
task.result ? `Result: ${task.result.slice(0, 500)}` : "",
|
|
112
|
-
task.error ? `Error: ${task.error}` : "",
|
|
113
|
-
];
|
|
114
|
-
return {
|
|
115
|
-
content: [{ type: "text", text: lines.filter(Boolean).join("\n") }],
|
|
116
|
-
details: { type: "task", action: "get", task },
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
case "list": {
|
|
120
|
-
const tasks = await deps.listTasks();
|
|
121
|
-
if (tasks.length === 0) {
|
|
122
|
-
return { content: [{ type: "text", text: "No tasks found." }] };
|
|
123
|
-
}
|
|
124
|
-
const lines = tasks.map(t => {
|
|
125
|
-
const icon = t.status === "completed" ? "â
" :
|
|
126
|
-
t.status === "running" ? "đ" :
|
|
127
|
-
t.status === "failed" ? "â" :
|
|
128
|
-
t.status === "stopped" ? "âšī¸" : "âŗ";
|
|
129
|
-
return `${icon} [${t.taskId}] ${t.description || "(no description)"} â ${t.status}`;
|
|
130
|
-
});
|
|
131
|
-
return {
|
|
132
|
-
content: [{ type: "text", text: `Tasks (${tasks.length}):\n${lines.join("\n")}` }],
|
|
133
|
-
details: { type: "task", action: "list", count: tasks.length },
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
case "output": {
|
|
137
|
-
if (!params.taskId) {
|
|
138
|
-
return { content: [{ type: "text", text: "Error: 'taskId' is required for output." }] };
|
|
139
|
-
}
|
|
140
|
-
const output = await deps.getTaskOutput(params.taskId, params.maxLines ?? DEFAULT_MAX_LINES);
|
|
141
|
-
return {
|
|
142
|
-
content: [{ type: "text", text: output || "(no output yet)" }],
|
|
143
|
-
details: { type: "task", action: "output", taskId: params.taskId },
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
case "stop": {
|
|
147
|
-
if (!params.taskId) {
|
|
148
|
-
return { content: [{ type: "text", text: "Error: 'taskId' is required for stop." }] };
|
|
149
|
-
}
|
|
150
|
-
const stopped = await deps.stopTask(params.taskId);
|
|
151
|
-
return {
|
|
152
|
-
content: [{ type: "text", text: stopped ? `Task ${params.taskId} stopped.` : `Failed to stop task ${params.taskId} (may already be completed).` }],
|
|
153
|
-
details: { type: "task", action: "stop", taskId: params.taskId, stopped },
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
default:
|
|
157
|
-
return { content: [{ type: "text", text: `Error: unknown action "${params.action}". Use: create/get/list/output/stop.` }] };
|
|
158
|
-
}
|
|
159
|
-
},
|
|
160
|
-
};
|
|
161
|
-
}
|