qlogicagent 0.2.1 → 0.4.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/README.md +45 -45
- package/package.json +56 -42
- package/dist/agent/agent.d.ts +0 -43
- package/dist/agent/agent.js +0 -113
- package/dist/agent/tool-loop.d.ts +0 -64
- package/dist/agent/tool-loop.js +0 -575
- package/dist/agent/types.d.ts +0 -175
- package/dist/agent/types.js +0 -14
- package/dist/cli/main.d.ts +0 -11
- package/dist/cli/main.js +0 -23
- package/dist/cli/stdio-server.d.ts +0 -45
- package/dist/cli/stdio-server.js +0 -463
- package/dist/config/config.d.ts +0 -17
- package/dist/config/config.js +0 -21
- package/dist/contracts/hooks.d.ts +0 -120
- package/dist/contracts/hooks.js +0 -7
- package/dist/contracts/index.d.ts +0 -10
- package/dist/contracts/index.js +0 -10
- package/dist/contracts/planner.d.ts +0 -35
- package/dist/contracts/planner.js +0 -2
- package/dist/contracts/skill-candidate.d.ts +0 -63
- package/dist/contracts/skill-candidate.js +0 -195
- package/dist/contracts/todo.d.ts +0 -14
- package/dist/contracts/todo.js +0 -9
- package/dist/index.d.ts +0 -13
- package/dist/index.js +0 -15
- package/dist/llm/builtin-providers.d.ts +0 -10
- package/dist/llm/builtin-providers.js +0 -531
- package/dist/llm/index.d.ts +0 -15
- package/dist/llm/index.js +0 -14
- package/dist/llm/llm-client.d.ts +0 -43
- package/dist/llm/llm-client.js +0 -67
- package/dist/llm/model-catalog.d.ts +0 -53
- package/dist/llm/model-catalog.js +0 -191
- package/dist/llm/provider-def.d.ts +0 -59
- package/dist/llm/provider-def.js +0 -12
- package/dist/llm/provider-registry.d.ts +0 -54
- package/dist/llm/provider-registry.js +0 -147
- package/dist/llm/transport.d.ts +0 -62
- package/dist/llm/transport.js +0 -27
- package/dist/llm/transports/anthropic-messages.d.ts +0 -31
- package/dist/llm/transports/anthropic-messages.js +0 -293
- package/dist/llm/transports/openai-chat.d.ts +0 -36
- package/dist/llm/transports/openai-chat.js +0 -165
- package/dist/orchestration/agent-registry.d.ts +0 -41
- package/dist/orchestration/agent-registry.js +0 -116
- package/dist/orchestration/approval-aware-tool-plan.d.ts +0 -32
- package/dist/orchestration/approval-aware-tool-plan.js +0 -87
- package/dist/orchestration/context-compression.d.ts +0 -220
- package/dist/orchestration/context-compression.js +0 -583
- package/dist/orchestration/conversation-repair.d.ts +0 -61
- package/dist/orchestration/conversation-repair.js +0 -429
- package/dist/orchestration/curator-scheduler.d.ts +0 -119
- package/dist/orchestration/curator-scheduler.js +0 -135
- package/dist/orchestration/embedded-failover-policy.d.ts +0 -110
- package/dist/orchestration/embedded-failover-policy.js +0 -168
- package/dist/orchestration/error-classification.d.ts +0 -12
- package/dist/orchestration/error-classification.js +0 -77
- package/dist/orchestration/failover-classification.d.ts +0 -8
- package/dist/orchestration/failover-classification.js +0 -381
- package/dist/orchestration/failover-error.d.ts +0 -33
- package/dist/orchestration/failover-error.js +0 -198
- package/dist/orchestration/fork-subagent.d.ts +0 -100
- package/dist/orchestration/fork-subagent.js +0 -98
- package/dist/orchestration/index.d.ts +0 -120
- package/dist/orchestration/index.js +0 -267
- package/dist/orchestration/memory-flush-policy.d.ts +0 -57
- package/dist/orchestration/memory-flush-policy.js +0 -85
- package/dist/orchestration/memory-provider.d.ts +0 -14
- package/dist/orchestration/memory-provider.js +0 -2
- package/dist/orchestration/parallel-tool-calls.d.ts +0 -41
- package/dist/orchestration/parallel-tool-calls.js +0 -59
- package/dist/orchestration/prompt-cache-strategy.d.ts +0 -126
- package/dist/orchestration/prompt-cache-strategy.js +0 -228
- package/dist/orchestration/reactive-compact.d.ts +0 -73
- package/dist/orchestration/reactive-compact.js +0 -78
- package/dist/orchestration/retry-loop.d.ts +0 -22
- package/dist/orchestration/retry-loop.js +0 -24
- package/dist/orchestration/skill-candidate.d.ts +0 -52
- package/dist/orchestration/skill-candidate.js +0 -141
- package/dist/orchestration/skill-consolidation.d.ts +0 -123
- package/dist/orchestration/skill-consolidation.js +0 -220
- package/dist/orchestration/skill-improvement.d.ts +0 -59
- package/dist/orchestration/skill-improvement.js +0 -66
- package/dist/orchestration/skill-similarity.d.ts +0 -98
- package/dist/orchestration/skill-similarity.js +0 -131
- package/dist/orchestration/streaming-tool-executor.d.ts +0 -73
- package/dist/orchestration/streaming-tool-executor.js +0 -96
- package/dist/orchestration/team-orchestration.d.ts +0 -195
- package/dist/orchestration/team-orchestration.js +0 -369
- package/dist/orchestration/team-tool-loop-wiring.d.ts +0 -92
- package/dist/orchestration/team-tool-loop-wiring.js +0 -147
- package/dist/orchestration/tool-choice-policy.d.ts +0 -54
- package/dist/orchestration/tool-choice-policy.js +0 -164
- package/dist/orchestration/tool-loop-state.d.ts +0 -50
- package/dist/orchestration/tool-loop-state.js +0 -133
- package/dist/orchestration/tool-schema.d.ts +0 -39
- package/dist/orchestration/tool-schema.js +0 -297
- package/dist/orchestration/transcript-repair.d.ts +0 -42
- package/dist/orchestration/transcript-repair.js +0 -426
- package/dist/orchestration/turn-loop-guard.d.ts +0 -86
- package/dist/orchestration/turn-loop-guard.js +0 -92
- package/dist/orchestration/web-browser-policy.d.ts +0 -17
- package/dist/orchestration/web-browser-policy.js +0 -39
- package/dist/runtime/context-compression.d.ts +0 -61
- package/dist/runtime/context-compression.js +0 -274
- package/dist/runtime/hook-registry.d.ts +0 -12
- package/dist/runtime/hook-registry.js +0 -53
- package/dist/runtime/memory-hooks.d.ts +0 -23
- package/dist/runtime/memory-hooks.js +0 -65
- package/dist/runtime/tool-eligibility.d.ts +0 -59
- package/dist/runtime/tool-eligibility.js +0 -111
- package/dist/skills/index.d.ts +0 -108
- package/dist/skills/index.js +0 -82
- package/dist/skills/memory-extractor.d.ts +0 -64
- package/dist/skills/memory-extractor.js +0 -173
- package/dist/skills/memory-query-tool.d.ts +0 -43
- package/dist/skills/memory-query-tool.js +0 -127
- package/dist/skills/memory-store.d.ts +0 -66
- package/dist/skills/memory-store.js +0 -228
- package/dist/skills/memory-tool.d.ts +0 -67
- package/dist/skills/memory-tool.js +0 -192
- package/dist/skills/portable-tool.d.ts +0 -71
- package/dist/skills/portable-tool.js +0 -14
- package/dist/skills/qmemory-adapter.d.ts +0 -52
- package/dist/skills/qmemory-adapter.js +0 -165
- package/dist/skills/skill-frontmatter.d.ts +0 -19
- package/dist/skills/skill-frontmatter.js +0 -344
- package/dist/skills/skill-guard.d.ts +0 -23
- package/dist/skills/skill-guard.js +0 -229
- package/dist/skills/skill-loader.d.ts +0 -16
- package/dist/skills/skill-loader.js +0 -303
- package/dist/skills/skill-source.d.ts +0 -119
- package/dist/skills/skill-source.js +0 -126
- package/dist/skills/skill-types.d.ts +0 -199
- package/dist/skills/skill-types.js +0 -6
- package/dist/skills/think-tool.d.ts +0 -16
- package/dist/skills/think-tool.js +0 -59
- package/dist/skills/todo-tool.d.ts +0 -63
- package/dist/skills/todo-tool.js +0 -114
- package/dist/skills/tools/agent-tool.d.ts +0 -91
- package/dist/skills/tools/agent-tool.js +0 -142
- package/dist/skills/tools/apply-patch-tool.d.ts +0 -29
- package/dist/skills/tools/apply-patch-tool.js +0 -184
- package/dist/skills/tools/ask-user-tool.d.ts +0 -80
- package/dist/skills/tools/ask-user-tool.js +0 -121
- package/dist/skills/tools/brief-tool.d.ts +0 -74
- package/dist/skills/tools/brief-tool.js +0 -95
- package/dist/skills/tools/browser-tool.d.ts +0 -114
- package/dist/skills/tools/browser-tool.js +0 -155
- package/dist/skills/tools/checkpoint-tool.d.ts +0 -66
- package/dist/skills/tools/checkpoint-tool.js +0 -102
- package/dist/skills/tools/config-tool.d.ts +0 -63
- package/dist/skills/tools/config-tool.js +0 -143
- package/dist/skills/tools/cron-tool.d.ts +0 -116
- package/dist/skills/tools/cron-tool.js +0 -175
- package/dist/skills/tools/edit-tool.d.ts +0 -43
- package/dist/skills/tools/edit-tool.js +0 -70
- package/dist/skills/tools/exec-tool.d.ts +0 -102
- package/dist/skills/tools/exec-tool.js +0 -133
- package/dist/skills/tools/image-generate-tool.d.ts +0 -62
- package/dist/skills/tools/image-generate-tool.js +0 -67
- package/dist/skills/tools/instructions-tool.d.ts +0 -103
- package/dist/skills/tools/instructions-tool.js +0 -187
- package/dist/skills/tools/lsp-tool.d.ts +0 -153
- package/dist/skills/tools/lsp-tool.js +0 -227
- package/dist/skills/tools/mcp-client-types.d.ts +0 -269
- package/dist/skills/tools/mcp-client-types.js +0 -53
- package/dist/skills/tools/mcp-tool.d.ts +0 -249
- package/dist/skills/tools/mcp-tool.js +0 -503
- package/dist/skills/tools/memory-tool.d.ts +0 -74
- package/dist/skills/tools/memory-tool.js +0 -88
- package/dist/skills/tools/monitor-tool.d.ts +0 -113
- package/dist/skills/tools/monitor-tool.js +0 -131
- package/dist/skills/tools/music-generate-tool.d.ts +0 -55
- package/dist/skills/tools/music-generate-tool.js +0 -62
- package/dist/skills/tools/notify-tool.d.ts +0 -53
- package/dist/skills/tools/notify-tool.js +0 -62
- package/dist/skills/tools/patch-tool.d.ts +0 -45
- package/dist/skills/tools/patch-tool.js +0 -505
- package/dist/skills/tools/pdf-tool.d.ts +0 -66
- package/dist/skills/tools/pdf-tool.js +0 -88
- package/dist/skills/tools/plan-mode-tool.d.ts +0 -59
- package/dist/skills/tools/plan-mode-tool.js +0 -122
- package/dist/skills/tools/read-tool.d.ts +0 -51
- package/dist/skills/tools/read-tool.js +0 -84
- package/dist/skills/tools/repl-tool.d.ts +0 -70
- package/dist/skills/tools/repl-tool.js +0 -69
- package/dist/skills/tools/search-tool.d.ts +0 -112
- package/dist/skills/tools/search-tool.js +0 -225
- package/dist/skills/tools/send-message-tool.d.ts +0 -51
- package/dist/skills/tools/send-message-tool.js +0 -76
- package/dist/skills/tools/skill-list-tool.d.ts +0 -33
- package/dist/skills/tools/skill-list-tool.js +0 -54
- package/dist/skills/tools/skill-manage-tool.d.ts +0 -73
- package/dist/skills/tools/skill-manage-tool.js +0 -153
- package/dist/skills/tools/skill-view-tool.d.ts +0 -37
- package/dist/skills/tools/skill-view-tool.js +0 -72
- package/dist/skills/tools/sleep-tool.d.ts +0 -49
- package/dist/skills/tools/sleep-tool.js +0 -81
- package/dist/skills/tools/structured-output-tool.d.ts +0 -116
- package/dist/skills/tools/structured-output-tool.js +0 -176
- package/dist/skills/tools/task-tool.d.ts +0 -104
- package/dist/skills/tools/task-tool.js +0 -161
- package/dist/skills/tools/team-tool.d.ts +0 -89
- package/dist/skills/tools/team-tool.js +0 -105
- package/dist/skills/tools/tool-search-tool.d.ts +0 -51
- package/dist/skills/tools/tool-search-tool.js +0 -110
- package/dist/skills/tools/tts-tool.d.ts +0 -38
- package/dist/skills/tools/tts-tool.js +0 -45
- package/dist/skills/tools/video-edit-tool.d.ts +0 -69
- package/dist/skills/tools/video-edit-tool.js +0 -74
- package/dist/skills/tools/video-generate-tool.d.ts +0 -62
- package/dist/skills/tools/video-generate-tool.js +0 -66
- package/dist/skills/tools/video-merge-tool.d.ts +0 -105
- package/dist/skills/tools/video-merge-tool.js +0 -92
- package/dist/skills/tools/video-upscale-tool.d.ts +0 -45
- package/dist/skills/tools/video-upscale-tool.js +0 -52
- package/dist/skills/tools/web-fetch-tool.d.ts +0 -78
- package/dist/skills/tools/web-fetch-tool.js +0 -92
- package/dist/skills/tools/web-search-tool.d.ts +0 -57
- package/dist/skills/tools/web-search-tool.js +0 -86
- package/dist/skills/tools/worktree-tool.d.ts +0 -69
- package/dist/skills/tools/worktree-tool.js +0 -147
- package/dist/skills/tools/write-tool.d.ts +0 -45
- package/dist/skills/tools/write-tool.js +0 -81
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// Config Tool — agent configuration management (read/write preferences).
|
|
3
|
-
// Reference: claude-code-haha/src/tools/ConfigTool/ConfigTool.ts
|
|
4
|
-
// Category: system
|
|
5
|
-
// ============================================================
|
|
6
|
-
export const CONFIG_TOOL_NAME = "config";
|
|
7
|
-
export const CONFIG_TOOL_SCHEMA = {
|
|
8
|
-
type: "object",
|
|
9
|
-
properties: {
|
|
10
|
-
action: {
|
|
11
|
-
type: "string",
|
|
12
|
-
enum: ["get", "set", "list", "reset"],
|
|
13
|
-
description: "Action:\n" +
|
|
14
|
-
"- get: Read a config setting\n" +
|
|
15
|
-
"- set: Write a config setting\n" +
|
|
16
|
-
"- list: List all available settings\n" +
|
|
17
|
-
"- reset: Reset a setting to default",
|
|
18
|
-
},
|
|
19
|
-
key: {
|
|
20
|
-
type: "string",
|
|
21
|
-
description: "Config key path (e.g. 'model', 'language', 'theme', 'permissions.defaultMode'). " +
|
|
22
|
-
"Required for get/set/reset.",
|
|
23
|
-
},
|
|
24
|
-
value: {
|
|
25
|
-
description: "Value to set. Type depends on the setting. Required for 'set' action.",
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
required: ["action"],
|
|
29
|
-
};
|
|
30
|
-
/** Keys that cannot be modified by LLM (security-critical) */
|
|
31
|
-
export const CONFIG_READONLY_KEYS = [
|
|
32
|
-
"permissions.securityPolicy",
|
|
33
|
-
"api.key",
|
|
34
|
-
"api.secret",
|
|
35
|
-
"auth.token",
|
|
36
|
-
"system.adminMode",
|
|
37
|
-
];
|
|
38
|
-
export function createConfigTool(deps) {
|
|
39
|
-
return {
|
|
40
|
-
name: CONFIG_TOOL_NAME,
|
|
41
|
-
label: "Config",
|
|
42
|
-
description: "Read and write agent configuration settings. " +
|
|
43
|
-
"Supports preferences like model selection, language, theme, tool enablement, etc. " +
|
|
44
|
-
"Security-critical settings (API keys, permissions) are read-only. " +
|
|
45
|
-
"Changes persist across sessions.",
|
|
46
|
-
parameters: CONFIG_TOOL_SCHEMA,
|
|
47
|
-
execute: async (_toolCallId, params) => {
|
|
48
|
-
switch (params.action) {
|
|
49
|
-
case "get": {
|
|
50
|
-
if (!params.key) {
|
|
51
|
-
return { content: [{ type: "text", text: "Error: key is required for get." }], details: { type: "config", error: "missing_key" } };
|
|
52
|
-
}
|
|
53
|
-
if (deps.isValidKey && !deps.isValidKey(params.key)) {
|
|
54
|
-
return { content: [{ type: "text", text: `Error: unknown config key "${params.key}". Use action='list' to see available settings.` }], details: { type: "config", error: "unknown_key" } };
|
|
55
|
-
}
|
|
56
|
-
const result = await deps.getConfig(params.key);
|
|
57
|
-
if (!result.success) {
|
|
58
|
-
return { content: [{ type: "text", text: `Error: ${result.error}` }], details: { type: "config", error: result.error } };
|
|
59
|
-
}
|
|
60
|
-
const s = result.setting;
|
|
61
|
-
const lines = [
|
|
62
|
-
`${s.key} = ${JSON.stringify(s.value)}`,
|
|
63
|
-
` Type: ${s.type}${s.options ? ` (${s.options.join(" | ")})` : ""}`,
|
|
64
|
-
` ${s.description}`,
|
|
65
|
-
];
|
|
66
|
-
if (s.readOnly)
|
|
67
|
-
lines.push(" ⚠️ Read-only (cannot be changed)");
|
|
68
|
-
return {
|
|
69
|
-
content: [{ type: "text", text: lines.join("\n") }],
|
|
70
|
-
details: { type: "config", action: "get", key: params.key, value: s.value },
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
case "set": {
|
|
74
|
-
if (!params.key) {
|
|
75
|
-
return { content: [{ type: "text", text: "Error: key is required for set." }], details: { type: "config", error: "missing_key" } };
|
|
76
|
-
}
|
|
77
|
-
if (params.value === undefined) {
|
|
78
|
-
return { content: [{ type: "text", text: "Error: value is required for set." }], details: { type: "config", error: "missing_value" } };
|
|
79
|
-
}
|
|
80
|
-
// Block security-critical keys
|
|
81
|
-
if (CONFIG_READONLY_KEYS.includes(params.key)) {
|
|
82
|
-
return {
|
|
83
|
-
content: [{ type: "text", text: `Error: "${params.key}" is a security-critical setting and cannot be modified.` }],
|
|
84
|
-
details: { type: "config", error: "readonly_key" },
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
if (deps.isValidKey && !deps.isValidKey(params.key)) {
|
|
88
|
-
return { content: [{ type: "text", text: `Error: unknown config key "${params.key}".` }], details: { type: "config", error: "unknown_key" } };
|
|
89
|
-
}
|
|
90
|
-
const result = await deps.setConfig(params.key, params.value);
|
|
91
|
-
if (!result.success) {
|
|
92
|
-
return { content: [{ type: "text", text: `Error: ${result.error}` }], details: { type: "config", error: result.error } };
|
|
93
|
-
}
|
|
94
|
-
return {
|
|
95
|
-
content: [{ type: "text", text: `Updated "${params.key}": ${JSON.stringify(result.previousValue)} → ${JSON.stringify(params.value)}` }],
|
|
96
|
-
details: { type: "config", action: "set", key: params.key, previousValue: result.previousValue, newValue: params.value },
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
case "list": {
|
|
100
|
-
const result = await deps.listConfig();
|
|
101
|
-
if (!result.settings || result.settings.length === 0) {
|
|
102
|
-
return { content: [{ type: "text", text: "No config settings available." }], details: { type: "config", action: "list", count: 0 } };
|
|
103
|
-
}
|
|
104
|
-
const lines = [`Available settings (${result.settings.length}):`, ""];
|
|
105
|
-
for (const s of result.settings) {
|
|
106
|
-
const ro = s.readOnly ? " [read-only]" : "";
|
|
107
|
-
const val = JSON.stringify(s.value);
|
|
108
|
-
lines.push(` ${s.key} = ${val}${ro}`);
|
|
109
|
-
lines.push(` ${s.description}`);
|
|
110
|
-
}
|
|
111
|
-
return {
|
|
112
|
-
content: [{ type: "text", text: lines.join("\n") }],
|
|
113
|
-
details: { type: "config", action: "list", count: result.settings.length },
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
case "reset": {
|
|
117
|
-
if (!params.key) {
|
|
118
|
-
return { content: [{ type: "text", text: "Error: key is required for reset." }], details: { type: "config", error: "missing_key" } };
|
|
119
|
-
}
|
|
120
|
-
if (CONFIG_READONLY_KEYS.includes(params.key)) {
|
|
121
|
-
return {
|
|
122
|
-
content: [{ type: "text", text: `Error: "${params.key}" cannot be reset (security-critical).` }],
|
|
123
|
-
details: { type: "config", error: "readonly_key" },
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
const result = await deps.resetConfig(params.key);
|
|
127
|
-
if (!result.success) {
|
|
128
|
-
return { content: [{ type: "text", text: `Error: ${result.error}` }], details: { type: "config", error: result.error } };
|
|
129
|
-
}
|
|
130
|
-
return {
|
|
131
|
-
content: [{ type: "text", text: `Reset "${params.key}" to default: ${JSON.stringify(result.setting?.value)}` }],
|
|
132
|
-
details: { type: "config", action: "reset", key: params.key, value: result.setting?.value },
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
default:
|
|
136
|
-
return {
|
|
137
|
-
content: [{ type: "text", text: `Error: unknown action "${params.action}".` }],
|
|
138
|
-
details: { type: "config", error: "unknown_action" },
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
},
|
|
142
|
-
};
|
|
143
|
-
}
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import type { PortableTool } from "../portable-tool.js";
|
|
2
|
-
export declare const CRON_TOOL_NAME: "cron";
|
|
3
|
-
export type CronAction = "create" | "list" | "get" | "update" | "delete" | "pause" | "resume" | "trigger";
|
|
4
|
-
export interface CronToolParams {
|
|
5
|
-
action: CronAction;
|
|
6
|
-
/** Job ID (required for get/update/delete/pause/resume/trigger) */
|
|
7
|
-
jobId?: string;
|
|
8
|
-
/** Task prompt to execute on schedule */
|
|
9
|
-
prompt?: string;
|
|
10
|
-
/** Cron expression or shorthand ('5m', '1h', '0 9 * * *') */
|
|
11
|
-
schedule?: string;
|
|
12
|
-
/** Human-readable job name */
|
|
13
|
-
name?: string;
|
|
14
|
-
/** Repeat count (null = infinite) */
|
|
15
|
-
repeat?: number | null;
|
|
16
|
-
/** Allowed tools for the scheduled task */
|
|
17
|
-
allowedTools?: string[];
|
|
18
|
-
/** Whether the job is enabled */
|
|
19
|
-
enabled?: boolean;
|
|
20
|
-
}
|
|
21
|
-
export declare const CRON_TOOL_SCHEMA: {
|
|
22
|
-
readonly type: "object";
|
|
23
|
-
readonly properties: {
|
|
24
|
-
readonly action: {
|
|
25
|
-
readonly type: "string";
|
|
26
|
-
readonly enum: readonly ["create", "list", "get", "update", "delete", "pause", "resume", "trigger"];
|
|
27
|
-
readonly description: "CRUD action: create/list/get/update/delete/pause/resume/trigger.";
|
|
28
|
-
};
|
|
29
|
-
readonly jobId: {
|
|
30
|
-
readonly type: "string";
|
|
31
|
-
readonly description: "Job ID. Required for get/update/delete/pause/resume/trigger.";
|
|
32
|
-
};
|
|
33
|
-
readonly prompt: {
|
|
34
|
-
readonly type: "string";
|
|
35
|
-
readonly description: "Task prompt to execute on schedule. Required for create.";
|
|
36
|
-
};
|
|
37
|
-
readonly schedule: {
|
|
38
|
-
readonly type: "string";
|
|
39
|
-
readonly description: string;
|
|
40
|
-
};
|
|
41
|
-
readonly name: {
|
|
42
|
-
readonly type: "string";
|
|
43
|
-
readonly description: "Human-readable job name.";
|
|
44
|
-
};
|
|
45
|
-
readonly repeat: {
|
|
46
|
-
readonly type: "number";
|
|
47
|
-
readonly description: "Number of times to repeat (null = infinite). Default: null.";
|
|
48
|
-
};
|
|
49
|
-
readonly allowedTools: {
|
|
50
|
-
readonly type: "array";
|
|
51
|
-
readonly items: {
|
|
52
|
-
readonly type: "string";
|
|
53
|
-
};
|
|
54
|
-
readonly description: "Tools the scheduled task is allowed to use.";
|
|
55
|
-
};
|
|
56
|
-
readonly enabled: {
|
|
57
|
-
readonly type: "boolean";
|
|
58
|
-
readonly description: "Whether the job is enabled (for update).";
|
|
59
|
-
};
|
|
60
|
-
};
|
|
61
|
-
readonly required: readonly ["action"];
|
|
62
|
-
};
|
|
63
|
-
export interface CronJob {
|
|
64
|
-
id: string;
|
|
65
|
-
name: string;
|
|
66
|
-
prompt: string;
|
|
67
|
-
schedule: string;
|
|
68
|
-
scheduleDisplay: string;
|
|
69
|
-
state: "scheduled" | "paused";
|
|
70
|
-
enabled: boolean;
|
|
71
|
-
repeat: {
|
|
72
|
-
times: number | null;
|
|
73
|
-
completed: number;
|
|
74
|
-
};
|
|
75
|
-
nextRunAt?: string;
|
|
76
|
-
lastRunAt?: string;
|
|
77
|
-
lastStatus?: "success" | "error" | null;
|
|
78
|
-
allowedTools?: string[];
|
|
79
|
-
}
|
|
80
|
-
export interface CronResult {
|
|
81
|
-
success: boolean;
|
|
82
|
-
job?: CronJob;
|
|
83
|
-
jobs?: CronJob[];
|
|
84
|
-
error?: string;
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Host-provided cron scheduler backend.
|
|
88
|
-
* Jobs are persisted locally and survive restarts.
|
|
89
|
-
*/
|
|
90
|
-
export interface CronToolDeps {
|
|
91
|
-
createJob(params: {
|
|
92
|
-
prompt: string;
|
|
93
|
-
schedule: string;
|
|
94
|
-
name?: string;
|
|
95
|
-
repeat?: number | null;
|
|
96
|
-
allowedTools?: string[];
|
|
97
|
-
}): Promise<CronResult>;
|
|
98
|
-
listJobs(): Promise<CronResult>;
|
|
99
|
-
getJob(jobId: string): Promise<CronResult>;
|
|
100
|
-
updateJob(jobId: string, updates: Partial<{
|
|
101
|
-
prompt: string;
|
|
102
|
-
schedule: string;
|
|
103
|
-
name: string;
|
|
104
|
-
enabled: boolean;
|
|
105
|
-
repeat: number | null;
|
|
106
|
-
allowedTools: string[];
|
|
107
|
-
}>): Promise<CronResult>;
|
|
108
|
-
deleteJob(jobId: string): Promise<CronResult>;
|
|
109
|
-
pauseJob(jobId: string): Promise<CronResult>;
|
|
110
|
-
resumeJob(jobId: string): Promise<CronResult>;
|
|
111
|
-
triggerJob(jobId: string): Promise<CronResult>;
|
|
112
|
-
/** Validate cron schedule expression. Returns error or null. */
|
|
113
|
-
validateSchedule?(schedule: string): string | null;
|
|
114
|
-
}
|
|
115
|
-
export declare const MAX_CRON_JOBS = 50;
|
|
116
|
-
export declare function createCronTool(deps: CronToolDeps): PortableTool<CronToolParams>;
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// Cron Tool — scheduled task management (CRUD).
|
|
3
|
-
// Reference: hermes-agent-main/tools/cronjob_tools.py
|
|
4
|
-
// Category: system
|
|
5
|
-
// ============================================================
|
|
6
|
-
export const CRON_TOOL_NAME = "cron";
|
|
7
|
-
export const CRON_TOOL_SCHEMA = {
|
|
8
|
-
type: "object",
|
|
9
|
-
properties: {
|
|
10
|
-
action: {
|
|
11
|
-
type: "string",
|
|
12
|
-
enum: ["create", "list", "get", "update", "delete", "pause", "resume", "trigger"],
|
|
13
|
-
description: "CRUD action: create/list/get/update/delete/pause/resume/trigger.",
|
|
14
|
-
},
|
|
15
|
-
jobId: {
|
|
16
|
-
type: "string",
|
|
17
|
-
description: "Job ID. Required for get/update/delete/pause/resume/trigger.",
|
|
18
|
-
},
|
|
19
|
-
prompt: {
|
|
20
|
-
type: "string",
|
|
21
|
-
description: "Task prompt to execute on schedule. Required for create.",
|
|
22
|
-
},
|
|
23
|
-
schedule: {
|
|
24
|
-
type: "string",
|
|
25
|
-
description: "Schedule expression. Supports:\n" +
|
|
26
|
-
"- Cron: '0 9 * * *' (every day at 9am)\n" +
|
|
27
|
-
"- Shorthand: '5m' (every 5 min), '1h' (hourly), '1d' (daily)\n" +
|
|
28
|
-
"Required for create.",
|
|
29
|
-
},
|
|
30
|
-
name: {
|
|
31
|
-
type: "string",
|
|
32
|
-
description: "Human-readable job name.",
|
|
33
|
-
},
|
|
34
|
-
repeat: {
|
|
35
|
-
type: "number",
|
|
36
|
-
description: "Number of times to repeat (null = infinite). Default: null.",
|
|
37
|
-
},
|
|
38
|
-
allowedTools: {
|
|
39
|
-
type: "array",
|
|
40
|
-
items: { type: "string" },
|
|
41
|
-
description: "Tools the scheduled task is allowed to use.",
|
|
42
|
-
},
|
|
43
|
-
enabled: {
|
|
44
|
-
type: "boolean",
|
|
45
|
-
description: "Whether the job is enabled (for update).",
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
required: ["action"],
|
|
49
|
-
};
|
|
50
|
-
export const MAX_CRON_JOBS = 50;
|
|
51
|
-
export function createCronTool(deps) {
|
|
52
|
-
return {
|
|
53
|
-
name: CRON_TOOL_NAME,
|
|
54
|
-
label: "Cron",
|
|
55
|
-
description: "Manage scheduled tasks. Create recurring jobs with cron expressions or shorthand " +
|
|
56
|
-
"('5m', '1h', '0 9 * * *'). Jobs persist locally and survive restarts. " +
|
|
57
|
-
"Actions: create, list, get, update, delete, pause, resume, trigger (run now).",
|
|
58
|
-
parameters: CRON_TOOL_SCHEMA,
|
|
59
|
-
execute: async (_toolCallId, params) => {
|
|
60
|
-
switch (params.action) {
|
|
61
|
-
case "create": {
|
|
62
|
-
if (!params.prompt) {
|
|
63
|
-
return { content: [{ type: "text", text: "Error: prompt is required for create." }], details: { type: "cron", error: "missing_prompt" } };
|
|
64
|
-
}
|
|
65
|
-
if (!params.schedule) {
|
|
66
|
-
return { content: [{ type: "text", text: "Error: schedule is required for create." }], details: { type: "cron", error: "missing_schedule" } };
|
|
67
|
-
}
|
|
68
|
-
if (deps.validateSchedule) {
|
|
69
|
-
const err = deps.validateSchedule(params.schedule);
|
|
70
|
-
if (err)
|
|
71
|
-
return { content: [{ type: "text", text: `Error: invalid schedule — ${err}` }], details: { type: "cron", error: "invalid_schedule" } };
|
|
72
|
-
}
|
|
73
|
-
// Check max jobs limit
|
|
74
|
-
const existing = await deps.listJobs();
|
|
75
|
-
if (existing.jobs && existing.jobs.length >= MAX_CRON_JOBS) {
|
|
76
|
-
return { content: [{ type: "text", text: `Error: maximum ${MAX_CRON_JOBS} jobs reached. Delete unused jobs first.` }], details: { type: "cron", error: "max_jobs_reached" } };
|
|
77
|
-
}
|
|
78
|
-
const r = await deps.createJob({ prompt: params.prompt, schedule: params.schedule, name: params.name, repeat: params.repeat, allowedTools: params.allowedTools });
|
|
79
|
-
if (!r.success)
|
|
80
|
-
return { content: [{ type: "text", text: `Error: ${r.error}` }], details: { type: "cron", error: r.error } };
|
|
81
|
-
return { content: [{ type: "text", text: formatJob(r.job) }], details: { type: "cron", action: "create", jobId: r.job.id } };
|
|
82
|
-
}
|
|
83
|
-
case "list": {
|
|
84
|
-
const r = await deps.listJobs();
|
|
85
|
-
if (!r.jobs || r.jobs.length === 0) {
|
|
86
|
-
return { content: [{ type: "text", text: "No scheduled jobs." }], details: { type: "cron", action: "list", count: 0 } };
|
|
87
|
-
}
|
|
88
|
-
const lines = [`Scheduled jobs (${r.jobs.length}):`, ""];
|
|
89
|
-
for (const j of r.jobs) {
|
|
90
|
-
lines.push(`- **${j.name || j.id}** [${j.state}] ${j.scheduleDisplay} — next: ${j.nextRunAt || "N/A"}`);
|
|
91
|
-
}
|
|
92
|
-
return { content: [{ type: "text", text: lines.join("\n") }], details: { type: "cron", action: "list", count: r.jobs.length } };
|
|
93
|
-
}
|
|
94
|
-
case "get": {
|
|
95
|
-
if (!params.jobId)
|
|
96
|
-
return { content: [{ type: "text", text: "Error: jobId required." }], details: { type: "cron", error: "missing_jobId" } };
|
|
97
|
-
const r = await deps.getJob(params.jobId);
|
|
98
|
-
if (!r.success)
|
|
99
|
-
return { content: [{ type: "text", text: `Error: ${r.error}` }], details: { type: "cron", error: r.error } };
|
|
100
|
-
return { content: [{ type: "text", text: formatJob(r.job) }], details: { type: "cron", action: "get", jobId: params.jobId } };
|
|
101
|
-
}
|
|
102
|
-
case "update": {
|
|
103
|
-
if (!params.jobId)
|
|
104
|
-
return { content: [{ type: "text", text: "Error: jobId required." }], details: { type: "cron", error: "missing_jobId" } };
|
|
105
|
-
const updates = {};
|
|
106
|
-
if (params.prompt !== undefined)
|
|
107
|
-
updates.prompt = params.prompt;
|
|
108
|
-
if (params.schedule !== undefined)
|
|
109
|
-
updates.schedule = params.schedule;
|
|
110
|
-
if (params.name !== undefined)
|
|
111
|
-
updates.name = params.name;
|
|
112
|
-
if (params.enabled !== undefined)
|
|
113
|
-
updates.enabled = params.enabled;
|
|
114
|
-
if (params.repeat !== undefined)
|
|
115
|
-
updates.repeat = params.repeat;
|
|
116
|
-
if (params.allowedTools !== undefined)
|
|
117
|
-
updates.allowedTools = params.allowedTools;
|
|
118
|
-
const r = await deps.updateJob(params.jobId, updates);
|
|
119
|
-
if (!r.success)
|
|
120
|
-
return { content: [{ type: "text", text: `Error: ${r.error}` }], details: { type: "cron", error: r.error } };
|
|
121
|
-
return { content: [{ type: "text", text: `Job updated.\n${formatJob(r.job)}` }], details: { type: "cron", action: "update", jobId: params.jobId } };
|
|
122
|
-
}
|
|
123
|
-
case "delete": {
|
|
124
|
-
if (!params.jobId)
|
|
125
|
-
return { content: [{ type: "text", text: "Error: jobId required." }], details: { type: "cron", error: "missing_jobId" } };
|
|
126
|
-
const r = await deps.deleteJob(params.jobId);
|
|
127
|
-
if (!r.success)
|
|
128
|
-
return { content: [{ type: "text", text: `Error: ${r.error}` }], details: { type: "cron", error: r.error } };
|
|
129
|
-
return { content: [{ type: "text", text: `Job ${params.jobId} deleted.` }], details: { type: "cron", action: "delete", jobId: params.jobId } };
|
|
130
|
-
}
|
|
131
|
-
case "pause": {
|
|
132
|
-
if (!params.jobId)
|
|
133
|
-
return { content: [{ type: "text", text: "Error: jobId required." }], details: { type: "cron", error: "missing_jobId" } };
|
|
134
|
-
const r = await deps.pauseJob(params.jobId);
|
|
135
|
-
if (!r.success)
|
|
136
|
-
return { content: [{ type: "text", text: `Error: ${r.error}` }], details: { type: "cron", error: r.error } };
|
|
137
|
-
return { content: [{ type: "text", text: `Job ${params.jobId} paused.` }], details: { type: "cron", action: "pause", jobId: params.jobId } };
|
|
138
|
-
}
|
|
139
|
-
case "resume": {
|
|
140
|
-
if (!params.jobId)
|
|
141
|
-
return { content: [{ type: "text", text: "Error: jobId required." }], details: { type: "cron", error: "missing_jobId" } };
|
|
142
|
-
const r = await deps.resumeJob(params.jobId);
|
|
143
|
-
if (!r.success)
|
|
144
|
-
return { content: [{ type: "text", text: `Error: ${r.error}` }], details: { type: "cron", error: r.error } };
|
|
145
|
-
return { content: [{ type: "text", text: `Job ${params.jobId} resumed.` }], details: { type: "cron", action: "resume", jobId: params.jobId } };
|
|
146
|
-
}
|
|
147
|
-
case "trigger": {
|
|
148
|
-
if (!params.jobId)
|
|
149
|
-
return { content: [{ type: "text", text: "Error: jobId required." }], details: { type: "cron", error: "missing_jobId" } };
|
|
150
|
-
const r = await deps.triggerJob(params.jobId);
|
|
151
|
-
if (!r.success)
|
|
152
|
-
return { content: [{ type: "text", text: `Error: ${r.error}` }], details: { type: "cron", error: r.error } };
|
|
153
|
-
return { content: [{ type: "text", text: `Job ${params.jobId} triggered (running now).` }], details: { type: "cron", action: "trigger", jobId: params.jobId } };
|
|
154
|
-
}
|
|
155
|
-
default:
|
|
156
|
-
return { content: [{ type: "text", text: `Error: unknown action "${params.action}".` }], details: { type: "cron", error: "unknown_action" } };
|
|
157
|
-
}
|
|
158
|
-
},
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
function formatJob(job) {
|
|
162
|
-
const lines = [
|
|
163
|
-
`Job: ${job.name || job.id}`,
|
|
164
|
-
`ID: ${job.id}`,
|
|
165
|
-
`Schedule: ${job.scheduleDisplay} (${job.schedule})`,
|
|
166
|
-
`State: ${job.state}`,
|
|
167
|
-
`Repeat: ${job.repeat.times === null ? "infinite" : `${job.repeat.completed}/${job.repeat.times}`}`,
|
|
168
|
-
];
|
|
169
|
-
if (job.nextRunAt)
|
|
170
|
-
lines.push(`Next run: ${job.nextRunAt}`);
|
|
171
|
-
if (job.lastRunAt)
|
|
172
|
-
lines.push(`Last run: ${job.lastRunAt} (${job.lastStatus || "unknown"})`);
|
|
173
|
-
lines.push(`Prompt: ${job.prompt.slice(0, 100)}${job.prompt.length > 100 ? "..." : ""}`);
|
|
174
|
-
return lines.join("\n");
|
|
175
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import type { PortableTool } from "../portable-tool.js";
|
|
2
|
-
export declare const EDIT_TOOL_NAME: "edit";
|
|
3
|
-
export interface EditToolParams {
|
|
4
|
-
path: string;
|
|
5
|
-
oldText: string;
|
|
6
|
-
newText: string;
|
|
7
|
-
}
|
|
8
|
-
export declare const EDIT_TOOL_SCHEMA: {
|
|
9
|
-
readonly type: "object";
|
|
10
|
-
readonly properties: {
|
|
11
|
-
readonly path: {
|
|
12
|
-
readonly type: "string";
|
|
13
|
-
readonly description: "Path to the file to edit (relative or absolute).";
|
|
14
|
-
};
|
|
15
|
-
readonly oldText: {
|
|
16
|
-
readonly type: "string";
|
|
17
|
-
readonly description: "Exact text to find and replace (must match exactly, including whitespace).";
|
|
18
|
-
};
|
|
19
|
-
readonly newText: {
|
|
20
|
-
readonly type: "string";
|
|
21
|
-
readonly description: "New text to replace the old text with.";
|
|
22
|
-
};
|
|
23
|
-
};
|
|
24
|
-
readonly required: readonly ["path", "oldText", "newText"];
|
|
25
|
-
};
|
|
26
|
-
/** Deps injected by the host runtime for file editing. */
|
|
27
|
-
export interface EditToolDeps {
|
|
28
|
-
/** Read file content as text. */
|
|
29
|
-
readFile(path: string): Promise<string>;
|
|
30
|
-
/** Write content back. */
|
|
31
|
-
writeFile(path: string, content: string): Promise<void>;
|
|
32
|
-
/** Resolve a relative path to absolute. */
|
|
33
|
-
resolvePath(input: string): string;
|
|
34
|
-
/**
|
|
35
|
-
* Check for concurrent modification before writing.
|
|
36
|
-
* The host tracks when each file was last read vs last modified on disk.
|
|
37
|
-
* Returns null if safe to write, or a descriptive warning if the file
|
|
38
|
-
* has been modified since last read (by user, another tool, or external process).
|
|
39
|
-
* If not provided, no concurrent modification check is performed.
|
|
40
|
-
*/
|
|
41
|
-
checkConcurrentModification?(path: string): string | null;
|
|
42
|
-
}
|
|
43
|
-
export declare function createEditTool(deps: EditToolDeps): PortableTool<EditToolParams>;
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// File Edit Tool — surgical text replacement in files.
|
|
3
|
-
// Category: coding
|
|
4
|
-
// ============================================================
|
|
5
|
-
export const EDIT_TOOL_NAME = "edit";
|
|
6
|
-
export const EDIT_TOOL_SCHEMA = {
|
|
7
|
-
type: "object",
|
|
8
|
-
properties: {
|
|
9
|
-
path: {
|
|
10
|
-
type: "string",
|
|
11
|
-
description: "Path to the file to edit (relative or absolute).",
|
|
12
|
-
},
|
|
13
|
-
oldText: {
|
|
14
|
-
type: "string",
|
|
15
|
-
description: "Exact text to find and replace (must match exactly, including whitespace).",
|
|
16
|
-
},
|
|
17
|
-
newText: {
|
|
18
|
-
type: "string",
|
|
19
|
-
description: "New text to replace the old text with.",
|
|
20
|
-
},
|
|
21
|
-
},
|
|
22
|
-
required: ["path", "oldText", "newText"],
|
|
23
|
-
};
|
|
24
|
-
export function createEditTool(deps) {
|
|
25
|
-
return {
|
|
26
|
-
name: EDIT_TOOL_NAME,
|
|
27
|
-
label: "Edit File",
|
|
28
|
-
description: "Edit a file by replacing exact text. The oldText must match exactly (including whitespace). " +
|
|
29
|
-
"Use this for precise, surgical edits. For multiple edits, call this tool multiple times.",
|
|
30
|
-
parameters: EDIT_TOOL_SCHEMA,
|
|
31
|
-
execute: async (_toolCallId, params) => {
|
|
32
|
-
const resolved = deps.resolvePath(params.path);
|
|
33
|
-
// Concurrent modification check
|
|
34
|
-
if (deps.checkConcurrentModification) {
|
|
35
|
-
const conflict = deps.checkConcurrentModification(resolved);
|
|
36
|
-
if (conflict) {
|
|
37
|
-
return {
|
|
38
|
-
content: [{ type: "text", text: `Concurrent modification detected: ${conflict}. Re-read the file first.` }],
|
|
39
|
-
details: { type: "edit", path: resolved, success: false, reason: "concurrent_modification" },
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
const content = await deps.readFile(resolved);
|
|
44
|
-
const index = content.indexOf(params.oldText);
|
|
45
|
-
if (index === -1) {
|
|
46
|
-
return {
|
|
47
|
-
content: [{ type: "text", text: `Error: oldText not found in ${resolved}. Ensure it matches exactly.` }],
|
|
48
|
-
details: { type: "edit", path: resolved, success: false, reason: "not_found" },
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
// Check for multiple matches
|
|
52
|
-
const secondIndex = content.indexOf(params.oldText, index + 1);
|
|
53
|
-
if (secondIndex !== -1) {
|
|
54
|
-
return {
|
|
55
|
-
content: [{ type: "text", text: `Error: oldText matches multiple locations in ${resolved}. Include more context to make the match unique.` }],
|
|
56
|
-
details: { type: "edit", path: resolved, success: false, reason: "ambiguous" },
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
const newContent = content.slice(0, index) + params.newText + content.slice(index + params.oldText.length);
|
|
60
|
-
await deps.writeFile(resolved, newContent);
|
|
61
|
-
// Compute first changed line
|
|
62
|
-
const preLines = content.slice(0, index).split("\n");
|
|
63
|
-
const firstChangedLine = preLines.length;
|
|
64
|
-
return {
|
|
65
|
-
content: [{ type: "text", text: `Edited ${resolved} (line ${firstChangedLine})` }],
|
|
66
|
-
details: { type: "edit", path: resolved, success: true, firstChangedLine },
|
|
67
|
-
};
|
|
68
|
-
},
|
|
69
|
-
};
|
|
70
|
-
}
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import type { PortableTool } from "../portable-tool.js";
|
|
2
|
-
export declare const EXEC_TOOL_NAME: "exec";
|
|
3
|
-
export interface ExecToolParams {
|
|
4
|
-
command: string;
|
|
5
|
-
description?: string;
|
|
6
|
-
workdir?: string;
|
|
7
|
-
timeout?: number;
|
|
8
|
-
background?: boolean;
|
|
9
|
-
}
|
|
10
|
-
export declare const EXEC_TOOL_SCHEMA: {
|
|
11
|
-
readonly type: "object";
|
|
12
|
-
readonly properties: {
|
|
13
|
-
readonly command: {
|
|
14
|
-
readonly type: "string";
|
|
15
|
-
readonly description: "Shell command to execute. On Windows uses PowerShell, on Unix uses bash.";
|
|
16
|
-
};
|
|
17
|
-
readonly description: {
|
|
18
|
-
readonly type: "string";
|
|
19
|
-
readonly description: string;
|
|
20
|
-
};
|
|
21
|
-
readonly workdir: {
|
|
22
|
-
readonly type: "string";
|
|
23
|
-
readonly description: "Working directory for the command.";
|
|
24
|
-
};
|
|
25
|
-
readonly timeout: {
|
|
26
|
-
readonly type: "number";
|
|
27
|
-
readonly description: "Timeout in seconds (default: 120). Only applies to foreground commands.";
|
|
28
|
-
};
|
|
29
|
-
readonly background: {
|
|
30
|
-
readonly type: "boolean";
|
|
31
|
-
readonly description: string;
|
|
32
|
-
};
|
|
33
|
-
};
|
|
34
|
-
readonly required: readonly ["command"];
|
|
35
|
-
};
|
|
36
|
-
export interface ExecResult {
|
|
37
|
-
exitCode: number;
|
|
38
|
-
stdout: string;
|
|
39
|
-
stderr: string;
|
|
40
|
-
timedOut?: boolean;
|
|
41
|
-
}
|
|
42
|
-
export interface BackgroundExecResult {
|
|
43
|
-
pid: string;
|
|
44
|
-
started: boolean;
|
|
45
|
-
hint?: string;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Deps injected by the host runtime for command execution.
|
|
49
|
-
* The host is responsible for sandboxing, approval, path restrictions,
|
|
50
|
-
* and security policies (dangerous command blocking).
|
|
51
|
-
*/
|
|
52
|
-
export interface ExecToolDeps {
|
|
53
|
-
/**
|
|
54
|
-
* Execute a shell command in the foreground and return the result.
|
|
55
|
-
*/
|
|
56
|
-
exec(command: string, options?: {
|
|
57
|
-
workdir?: string;
|
|
58
|
-
timeout?: number;
|
|
59
|
-
}): Promise<ExecResult>;
|
|
60
|
-
/**
|
|
61
|
-
* Start a background process and return its ID.
|
|
62
|
-
* The host manages the process lifecycle.
|
|
63
|
-
* If not provided, background=true will be rejected.
|
|
64
|
-
*/
|
|
65
|
-
execBackground?(command: string, options?: {
|
|
66
|
-
workdir?: string;
|
|
67
|
-
}): Promise<BackgroundExecResult>;
|
|
68
|
-
/**
|
|
69
|
-
* Retrieve partial output from a background process.
|
|
70
|
-
* If not provided, background output queries are not supported.
|
|
71
|
-
*/
|
|
72
|
-
getBackgroundOutput?(pid: string): Promise<{
|
|
73
|
-
stdout: string;
|
|
74
|
-
stderr: string;
|
|
75
|
-
running: boolean;
|
|
76
|
-
}>;
|
|
77
|
-
/**
|
|
78
|
-
* Validate a command before execution (skill-guard integration point).
|
|
79
|
-
* The host MUST implement this to block dangerous commands
|
|
80
|
-
* (rm -rf /, format, del /f /s /q, etc.).
|
|
81
|
-
* Returns null/undefined if allowed, or an error message string if blocked.
|
|
82
|
-
* If not provided, all commands are allowed (UNSAFE — only for tests).
|
|
83
|
-
*/
|
|
84
|
-
validateCommand?(command: string): Promise<string | null | undefined>;
|
|
85
|
-
/**
|
|
86
|
-
* Persist large output to disk and return a reference URI.
|
|
87
|
-
* Called when stdout+stderr exceeds MAX_OUTPUT_CHARS.
|
|
88
|
-
* If provided, the tool returns a truncated preview + the persisted URI.
|
|
89
|
-
* This avoids flooding the LLM context with huge outputs.
|
|
90
|
-
*/
|
|
91
|
-
persistOutput?(output: string, meta: {
|
|
92
|
-
command: string;
|
|
93
|
-
exitCode: number;
|
|
94
|
-
}): Promise<string>;
|
|
95
|
-
/**
|
|
96
|
-
* Interpret a non-zero exit code into a human-readable explanation.
|
|
97
|
-
* E.g. exit 127 → "command not found", exit 137 → "killed by SIGKILL (OOM?)".
|
|
98
|
-
* If not provided, raw exit code is shown.
|
|
99
|
-
*/
|
|
100
|
-
interpretExitCode?(exitCode: number, stderr: string): string | undefined;
|
|
101
|
-
}
|
|
102
|
-
export declare function createExecTool(deps: ExecToolDeps): PortableTool<ExecToolParams>;
|