@cjhyy/code-shell-core 0.5.0-rc.1 → 0.5.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/agent-definition-registry.d.ts +18 -3
- package/dist/agent/agent-definition-registry.js +47 -18
- package/dist/agent/agent-definition.d.ts +17 -0
- package/dist/agent/agent-definition.js +22 -1
- package/dist/arena/arena.js +11 -12
- package/dist/arena/context/context-tools.js +2 -4
- package/dist/arena/context/within-root.d.ts +7 -0
- package/dist/arena/context/within-root.js +15 -0
- package/dist/arena/iterate/phases/argue.js +8 -2
- package/dist/arena/iterate/phases/revise.js +1 -1
- package/dist/arena/iterate/phases/tournament.js +3 -3
- package/dist/arena/phases/adjudication.js +1 -4
- package/dist/arena/phases/build-consensus.js +1 -4
- package/dist/arena/phases/cross-review.js +2 -8
- package/dist/arena/phases/debate-rounds.js +1 -4
- package/dist/arena/phases/participant-research.js +1 -4
- package/dist/arena/phases/planning-detail-expansion.js +8 -10
- package/dist/arena/planner.js +0 -1
- package/dist/arena/providers/docs.d.ts +1 -0
- package/dist/arena/providers/docs.js +5 -2
- package/dist/arena/providers/repo.d.ts +1 -0
- package/dist/arena/providers/repo.js +5 -2
- package/dist/arena/strategies/utils.js +36 -3
- package/dist/arena/transitions.d.ts +7 -2
- package/dist/arena/transitions.js +9 -4
- package/dist/arena/types.d.ts +8 -2
- package/dist/automation/cron-expr.d.ts +31 -0
- package/dist/automation/cron-expr.js +151 -0
- package/dist/automation/index.d.ts +41 -0
- package/dist/automation/index.js +39 -0
- package/dist/automation/runner.d.ts +67 -0
- package/dist/automation/runner.js +56 -0
- package/dist/automation/scheduler.d.ts +156 -0
- package/dist/automation/scheduler.js +546 -0
- package/dist/automation/store.d.ts +39 -0
- package/dist/automation/store.js +119 -0
- package/dist/automation/write-policy.d.ts +34 -0
- package/dist/automation/write-policy.js +113 -0
- package/dist/automation/write-run.d.ts +51 -0
- package/dist/automation/write-run.js +38 -0
- package/dist/capability-control/index.d.ts +5 -0
- package/dist/capability-control/index.js +3 -0
- package/dist/capability-control/overlay.d.ts +49 -0
- package/dist/capability-control/overlay.js +89 -0
- package/dist/capability-control/project.d.ts +65 -0
- package/dist/capability-control/project.js +147 -0
- package/dist/capability-control/service.d.ts +70 -0
- package/dist/capability-control/service.js +147 -0
- package/dist/capability-control/types.d.ts +62 -0
- package/dist/capability-control/types.js +17 -0
- package/dist/cli/agent-server-stdio.d.ts +12 -1
- package/dist/cli/agent-server-stdio.js +114 -19
- package/dist/cli/agent-server-tcp.d.ts +20 -0
- package/dist/cli/agent-server-tcp.js +120 -0
- package/dist/cli/graceful-shutdown.d.ts +27 -0
- package/dist/cli/graceful-shutdown.js +30 -0
- package/dist/context/compaction.js +23 -15
- package/dist/context/manager.d.ts +0 -20
- package/dist/context/manager.js +0 -37
- package/dist/cron/cron-runtime.d.ts +2 -0
- package/dist/cron/cron-runtime.js +2 -0
- package/dist/cron/cron-store.d.ts +2 -0
- package/dist/cron/cron-store.js +2 -0
- package/dist/cron/scheduler.d.ts +5 -32
- package/dist/cron/scheduler.js +5 -113
- package/dist/data/openrouter-sync.js +1 -1
- package/dist/engine/engine.d.ts +208 -14
- package/dist/engine/engine.js +754 -169
- package/dist/engine/goal.d.ts +42 -0
- package/dist/engine/goal.js +52 -0
- package/dist/engine/image-compression.d.ts +81 -0
- package/dist/engine/image-compression.js +186 -0
- package/dist/engine/image-policy.d.ts +152 -0
- package/dist/engine/image-policy.js +165 -0
- package/dist/engine/reactive-threshold.d.ts +13 -0
- package/dist/engine/reactive-threshold.js +17 -0
- package/dist/engine/runtime.js +7 -0
- package/dist/engine/session-title.d.ts +13 -0
- package/dist/engine/session-title.js +34 -0
- package/dist/engine/turn-loop.d.ts +29 -8
- package/dist/engine/turn-loop.js +498 -316
- package/dist/git/parse-log.d.ts +13 -0
- package/dist/git/parse-log.js +21 -0
- package/dist/git/utils.d.ts +8 -6
- package/dist/git/utils.js +57 -26
- package/dist/git/worktree.js +33 -18
- package/dist/hooks/events.d.ts +23 -1
- package/dist/hooks/goal-stop-hook.d.ts +30 -0
- package/dist/hooks/goal-stop-hook.js +102 -0
- package/dist/hooks/hook-output.d.ts +33 -0
- package/dist/hooks/hook-output.js +79 -0
- package/dist/hooks/registry.d.ts +7 -0
- package/dist/hooks/registry.js +38 -1
- package/dist/hooks/shell-runner.d.ts +2 -0
- package/dist/hooks/shell-runner.js +43 -2
- package/dist/index.d.ts +31 -6
- package/dist/index.js +30 -3
- package/dist/llm/capabilities/reasoning-control.d.ts +24 -0
- package/dist/llm/capabilities/reasoning-control.js +38 -0
- package/dist/llm/capabilities/rules.js +33 -3
- package/dist/llm/capabilities/types.d.ts +22 -2
- package/dist/llm/clamp-max-tokens.d.ts +11 -0
- package/dist/llm/clamp-max-tokens.js +17 -0
- package/dist/llm/client-base.d.ts +41 -4
- package/dist/llm/client-base.js +67 -13
- package/dist/llm/client-factory.d.ts +3 -3
- package/dist/llm/client-factory.js +2 -2
- package/dist/llm/model-pool.d.ts +15 -11
- package/dist/llm/model-pool.js +23 -20
- package/dist/llm/provider-catalog.d.ts +2 -2
- package/dist/llm/providers/anthropic.d.ts +32 -2
- package/dist/llm/providers/anthropic.js +147 -8
- package/dist/llm/providers/openai.d.ts +11 -2
- package/dist/llm/providers/openai.js +253 -52
- package/dist/llm/reasoning-setting.d.ts +51 -0
- package/dist/llm/reasoning-setting.js +32 -0
- package/dist/llm/stop-reason.d.ts +13 -0
- package/dist/llm/stop-reason.js +21 -0
- package/dist/llm/strip-vision.d.ts +32 -0
- package/dist/llm/strip-vision.js +94 -0
- package/dist/llm/types.d.ts +5 -6
- package/dist/logging/logger.js +18 -4
- package/dist/logging/sanitize-messages.d.ts +10 -0
- package/dist/logging/sanitize-messages.js +90 -0
- package/dist/lsp/client.js +28 -8
- package/dist/lsp/manager.js +2 -1
- package/dist/lsp/root-path.d.ts +9 -0
- package/dist/lsp/root-path.js +12 -0
- package/dist/onboarding.js +18 -11
- package/dist/plugins/gitOps.d.ts +34 -0
- package/dist/plugins/gitOps.js +59 -3
- package/dist/plugins/installer/codex/convertAgents.d.ts +7 -0
- package/dist/plugins/installer/codex/convertAgents.js +55 -0
- package/dist/plugins/installer/codex/convertMcp.d.ts +8 -0
- package/dist/plugins/installer/codex/convertMcp.js +45 -0
- package/dist/plugins/installer/codex/convertSkills.d.ts +12 -0
- package/dist/plugins/installer/codex/convertSkills.js +33 -0
- package/dist/plugins/installer/detectFormat.d.ts +2 -0
- package/dist/plugins/installer/detectFormat.js +6 -0
- package/dist/plugins/installer/install.d.ts +7 -0
- package/dist/plugins/installer/install.js +99 -0
- package/dist/plugins/installer/installFromSource.d.ts +13 -0
- package/dist/plugins/installer/installFromSource.js +45 -0
- package/dist/plugins/installer/list.d.ts +9 -0
- package/dist/plugins/installer/list.js +30 -0
- package/dist/plugins/installer/loadPluginAgents.d.ts +3 -0
- package/dist/plugins/installer/loadPluginAgents.js +23 -0
- package/dist/plugins/installer/loadPluginMcp.d.ts +7 -0
- package/dist/plugins/installer/loadPluginMcp.js +74 -0
- package/dist/plugins/installer/parseSource.d.ts +20 -0
- package/dist/plugins/installer/parseSource.js +74 -0
- package/dist/plugins/installer/paths.d.ts +5 -0
- package/dist/plugins/installer/paths.js +25 -0
- package/dist/plugins/installer/types.d.ts +49 -0
- package/dist/plugins/installer/types.js +27 -0
- package/dist/plugins/installer/uninstall.d.ts +2 -0
- package/dist/plugins/installer/uninstall.js +14 -0
- package/dist/plugins/installer/update.d.ts +14 -0
- package/dist/plugins/installer/update.js +65 -0
- package/dist/plugins/loadPluginHooks.d.ts +8 -1
- package/dist/plugins/loadPluginHooks.js +11 -1
- package/dist/plugins/marketplaceManager.d.ts +8 -1
- package/dist/plugins/marketplaceManager.js +38 -4
- package/dist/plugins/pluginCommandHook.js +34 -0
- package/dist/plugins/pluginInstaller.d.ts +21 -0
- package/dist/plugins/pluginInstaller.js +128 -29
- package/dist/plugins/schemas.js +40 -6
- package/dist/plugins/types.d.ts +4 -0
- package/dist/preset/index.js +16 -0
- package/dist/prompt/composer.d.ts +4 -0
- package/dist/prompt/composer.js +28 -4
- package/dist/prompt/sections/orchestration.md +8 -0
- package/dist/protocol/chat-session-manager.d.ts +8 -1
- package/dist/protocol/chat-session-manager.js +10 -0
- package/dist/protocol/chat-session.d.ts +17 -0
- package/dist/protocol/chat-session.js +28 -0
- package/dist/protocol/redact.d.ts +50 -0
- package/dist/protocol/redact.js +71 -0
- package/dist/protocol/server.d.ts +41 -2
- package/dist/protocol/server.js +231 -33
- package/dist/protocol/tcp-transport.d.ts +45 -0
- package/dist/protocol/tcp-transport.js +74 -0
- package/dist/protocol/types.d.ts +23 -0
- package/dist/protocol/types.js +6 -0
- package/dist/remote/bridge.d.ts +11 -2
- package/dist/remote/bridge.js +61 -33
- package/dist/run/ArtifactTracker.js +5 -4
- package/dist/run/EngineRunner.d.ts +27 -1
- package/dist/run/EngineRunner.js +46 -8
- package/dist/run/FileRunStore.js +32 -8
- package/dist/run/RunLock.d.ts +28 -2
- package/dist/run/RunLock.js +49 -7
- package/dist/run/RunManager.js +51 -3
- package/dist/run/RunQueue.d.ts +1 -0
- package/dist/run/RunQueue.js +8 -2
- package/dist/run/factory.d.ts +7 -0
- package/dist/run/factory.js +1 -0
- package/dist/run/index.d.ts +2 -2
- package/dist/run/index.js +1 -1
- package/dist/run/redirect-target.d.ts +7 -0
- package/dist/run/redirect-target.js +13 -0
- package/dist/run/types.js +1 -1
- package/dist/services/browser-open.d.ts +13 -0
- package/dist/services/browser-open.js +16 -0
- package/dist/services/dream-consolidation.d.ts +57 -0
- package/dist/services/dream-consolidation.js +151 -0
- package/dist/services/memory-orchestrator.js +18 -0
- package/dist/services/notifier.d.ts +8 -0
- package/dist/services/notifier.js +39 -25
- package/dist/services/oauth.js +5 -7
- package/dist/services/session-memory-sort.d.ts +8 -0
- package/dist/services/session-memory-sort.js +9 -0
- package/dist/services/session-memory.js +8 -9
- package/dist/session/file-history.js +10 -3
- package/dist/session/session-manager.d.ts +23 -1
- package/dist/session/session-manager.js +73 -2
- package/dist/settings/disk-defaults.d.ts +35 -0
- package/dist/settings/disk-defaults.js +24 -0
- package/dist/settings/manager.d.ts +33 -0
- package/dist/settings/manager.js +94 -1
- package/dist/settings/personalization.d.ts +19 -0
- package/dist/settings/personalization.js +7 -0
- package/dist/settings/schema.d.ts +1142 -126
- package/dist/settings/schema.js +119 -10
- package/dist/tool-system/builtin/add-marketplace.d.ts +12 -0
- package/dist/tool-system/builtin/add-marketplace.js +76 -0
- package/dist/tool-system/builtin/agent-registry.d.ts +11 -0
- package/dist/tool-system/builtin/agent-registry.js +8 -4
- package/dist/tool-system/builtin/agent.d.ts +29 -10
- package/dist/tool-system/builtin/agent.js +108 -52
- package/dist/tool-system/builtin/apply-patch/index.js +22 -3
- package/dist/tool-system/builtin/arena.js +6 -7
- package/dist/tool-system/builtin/complete-goal.d.ts +25 -0
- package/dist/tool-system/builtin/complete-goal.js +45 -0
- package/dist/tool-system/builtin/cron.js +53 -9
- package/dist/tool-system/builtin/edit.d.ts +2 -1
- package/dist/tool-system/builtin/edit.js +6 -1
- package/dist/tool-system/builtin/generate-image.d.ts +25 -0
- package/dist/tool-system/builtin/generate-image.js +146 -0
- package/dist/tool-system/builtin/glob.js +7 -0
- package/dist/tool-system/builtin/grep.js +6 -0
- package/dist/tool-system/builtin/index.d.ts +18 -1
- package/dist/tool-system/builtin/index.js +62 -1
- package/dist/tool-system/builtin/notebook-edit.d.ts +2 -1
- package/dist/tool-system/builtin/notebook-edit.js +8 -1
- package/dist/tool-system/builtin/read.d.ts +2 -1
- package/dist/tool-system/builtin/read.js +9 -1
- package/dist/tool-system/builtin/sleep.js +9 -3
- package/dist/tool-system/builtin/task.js +4 -1
- package/dist/tool-system/builtin/update-automation-memory.d.ts +24 -0
- package/dist/tool-system/builtin/update-automation-memory.js +60 -0
- package/dist/tool-system/builtin/view-image.d.ts +18 -0
- package/dist/tool-system/builtin/view-image.js +96 -0
- package/dist/tool-system/builtin/web-search.d.ts +4 -1
- package/dist/tool-system/builtin/web-search.js +36 -3
- package/dist/tool-system/builtin/write.d.ts +2 -1
- package/dist/tool-system/builtin/write.js +7 -1
- package/dist/tool-system/context.d.ts +12 -0
- package/dist/tool-system/executor.d.ts +0 -1
- package/dist/tool-system/executor.js +34 -40
- package/dist/tool-system/investigation-guard.d.ts +4 -1
- package/dist/tool-system/investigation-guard.js +19 -3
- package/dist/tool-system/mcp-manager.d.ts +36 -12
- package/dist/tool-system/mcp-manager.js +173 -10
- package/dist/tool-system/path-policy.d.ts +94 -0
- package/dist/tool-system/path-policy.js +279 -0
- package/dist/tool-system/permission.js +43 -50
- package/dist/tool-system/plan-mode-allowlist.d.ts +21 -0
- package/dist/tool-system/plan-mode-allowlist.js +43 -0
- package/dist/tool-system/registry.js +12 -1
- package/dist/tool-system/validation.d.ts +10 -0
- package/dist/tool-system/validation.js +16 -3
- package/dist/types.d.ts +90 -15
- package/dist/utils/format.js +4 -2
- package/dist/utils/lockfile.js +9 -2
- package/dist/utils/theme.d.ts +6 -0
- package/dist/utils/theme.js +4 -2
- package/package.json +2 -1
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
import { fileCache } from "../file-cache.js";
|
|
18
18
|
import { applyPatch } from "./applier.js";
|
|
19
19
|
import { parsePatch } from "./parser.js";
|
|
20
|
+
import { enforcePathPolicy } from "../../path-policy.js";
|
|
21
|
+
import { resolve as resolvePath } from "node:path";
|
|
20
22
|
export const applyPatchToolDef = {
|
|
21
23
|
name: "ApplyPatch",
|
|
22
24
|
description: "Apply a V4A-format patch atomically across one or more files. " +
|
|
@@ -68,6 +70,20 @@ export async function applyPatchTool(args, ctx) {
|
|
|
68
70
|
// A4: resolve relative patch paths against the Engine's cwd, not the
|
|
69
71
|
// host process cwd. See standard §S5.
|
|
70
72
|
const cwd = ctx?.cwd ?? process.cwd();
|
|
73
|
+
// Path-policy gate every target before any IO. A multi-file patch is
|
|
74
|
+
// atomic — if *any* target is blocked the whole patch must reject so we
|
|
75
|
+
// don't end up writing some files and refusing others.
|
|
76
|
+
for (const hunk of parsed.hunks) {
|
|
77
|
+
const targets = [resolvePath(cwd, hunk.path)];
|
|
78
|
+
if (hunk.kind === "update" && hunk.movePath) {
|
|
79
|
+
targets.push(resolvePath(cwd, hunk.movePath));
|
|
80
|
+
}
|
|
81
|
+
for (const t of targets) {
|
|
82
|
+
const blocked = enforcePathPolicy(t, "write", cwd);
|
|
83
|
+
if (blocked)
|
|
84
|
+
return blocked;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
71
87
|
let result;
|
|
72
88
|
try {
|
|
73
89
|
result = await applyPatch(parsed.hunks, { cwd });
|
|
@@ -75,11 +91,14 @@ export async function applyPatchTool(args, ctx) {
|
|
|
75
91
|
catch (err) {
|
|
76
92
|
return `Error applying patch: ${err.message}`;
|
|
77
93
|
}
|
|
78
|
-
// Invalidate file cache for every touched path.
|
|
94
|
+
// Invalidate file cache for every touched path. The cache is keyed by
|
|
95
|
+
// ABSOLUTE path (see file-cache.ts), and patch paths are relative to the
|
|
96
|
+
// Engine cwd — resolve them the same way the path-policy gate did above, or
|
|
97
|
+
// the stale entry survives and a later Read returns pre-patch content.
|
|
79
98
|
for (const hunk of parsed.hunks) {
|
|
80
|
-
fileCache.invalidate(hunk.path);
|
|
99
|
+
fileCache.invalidate(resolvePath(cwd, hunk.path));
|
|
81
100
|
if (hunk.kind === "update" && hunk.movePath) {
|
|
82
|
-
fileCache.invalidate(hunk.movePath);
|
|
101
|
+
fileCache.invalidate(resolvePath(cwd, hunk.movePath));
|
|
83
102
|
}
|
|
84
103
|
}
|
|
85
104
|
const parts = [];
|
|
@@ -123,9 +123,8 @@ function resolveParticipant(nameOrPath, llmConfig, pool) {
|
|
|
123
123
|
maxTokens: preset.maxOutputTokens,
|
|
124
124
|
baseUrl: fallbackBaseUrl,
|
|
125
125
|
apiKey: fallbackApiKey,
|
|
126
|
-
temperature: ARENA_TEMPERATURE,
|
|
127
|
-
enableStreaming: false,
|
|
128
126
|
},
|
|
127
|
+
clientDefaults: { temperature: ARENA_TEMPERATURE },
|
|
129
128
|
};
|
|
130
129
|
}
|
|
131
130
|
// (3) Raw model path
|
|
@@ -138,9 +137,8 @@ function resolveParticipant(nameOrPath, llmConfig, pool) {
|
|
|
138
137
|
maxTokens: getMaxOutputTokens(nameOrPath),
|
|
139
138
|
baseUrl: fallbackBaseUrl,
|
|
140
139
|
apiKey: fallbackApiKey,
|
|
141
|
-
temperature: ARENA_TEMPERATURE,
|
|
142
|
-
enableStreaming: false,
|
|
143
140
|
},
|
|
141
|
+
clientDefaults: { temperature: ARENA_TEMPERATURE },
|
|
144
142
|
};
|
|
145
143
|
}
|
|
146
144
|
function participantFromPool(entry, llmConfig) {
|
|
@@ -156,9 +154,8 @@ function participantFromPool(entry, llmConfig) {
|
|
|
156
154
|
maxTokens: entry.maxOutputTokens ?? getMaxOutputTokens(entry.model),
|
|
157
155
|
baseUrl: entry.baseUrl ?? llmConfig.baseUrl,
|
|
158
156
|
apiKey: entry.apiKey ?? llmConfig.apiKey,
|
|
159
|
-
temperature: ARENA_TEMPERATURE,
|
|
160
|
-
enableStreaming: false,
|
|
161
157
|
},
|
|
158
|
+
clientDefaults: { temperature: ARENA_TEMPERATURE },
|
|
162
159
|
};
|
|
163
160
|
}
|
|
164
161
|
/**
|
|
@@ -411,6 +408,8 @@ export async function arenaTool(args, ctx) {
|
|
|
411
408
|
catch (err) {
|
|
412
409
|
if (signal?.aborted)
|
|
413
410
|
return "Arena aborted.";
|
|
414
|
-
|
|
411
|
+
// err may be a non-Error (string/null); `(err as Error).message` would be
|
|
412
|
+
// undefined → "Arena error: undefined", masking the real cause.
|
|
413
|
+
return `Arena error: ${err instanceof Error ? err.message : String(err)}`;
|
|
415
414
|
}
|
|
416
415
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* complete_goal — Goal mode P0.
|
|
3
|
+
*
|
|
4
|
+
* The model calls this to explicitly DECLARE the current goal complete
|
|
5
|
+
* (mirrors Codex's update_goal(status=Complete)). When the turn loop sees
|
|
6
|
+
* this tool call it short-circuits to a "completed" stop WITHOUT running the
|
|
7
|
+
* judge LLM (wired in Task 4). This tool itself just records an
|
|
8
|
+
* acknowledgement string into the transcript; the loop-level short-circuit
|
|
9
|
+
* lives in turn-loop.ts.
|
|
10
|
+
*
|
|
11
|
+
* Shape note: builtin tools in this codebase are a `ToolDefinition`
|
|
12
|
+
* (name/description/inputSchema only — see types.ts) plus a separate executor
|
|
13
|
+
* `(args: Record<string, unknown>) => Promise<string>`. The runtime metadata
|
|
14
|
+
* (source/permissionDefault/isReadOnly/...) is attached in builtin/index.ts at
|
|
15
|
+
* registration time, NOT on the def. Registration is Task 6.
|
|
16
|
+
*/
|
|
17
|
+
import type { ToolDefinition } from "../../types.js";
|
|
18
|
+
/**
|
|
19
|
+
* The tool name, shared with turn-loop.ts's short-circuit check so a rename
|
|
20
|
+
* can't silently break completion detection (the name lives in exactly one
|
|
21
|
+
* place).
|
|
22
|
+
*/
|
|
23
|
+
export declare const COMPLETE_GOAL_TOOL_NAME = "complete_goal";
|
|
24
|
+
export declare const completeGoalToolDef: ToolDefinition;
|
|
25
|
+
export declare function completeGoalTool(args: Record<string, unknown>): Promise<string>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* complete_goal — Goal mode P0.
|
|
3
|
+
*
|
|
4
|
+
* The model calls this to explicitly DECLARE the current goal complete
|
|
5
|
+
* (mirrors Codex's update_goal(status=Complete)). When the turn loop sees
|
|
6
|
+
* this tool call it short-circuits to a "completed" stop WITHOUT running the
|
|
7
|
+
* judge LLM (wired in Task 4). This tool itself just records an
|
|
8
|
+
* acknowledgement string into the transcript; the loop-level short-circuit
|
|
9
|
+
* lives in turn-loop.ts.
|
|
10
|
+
*
|
|
11
|
+
* Shape note: builtin tools in this codebase are a `ToolDefinition`
|
|
12
|
+
* (name/description/inputSchema only — see types.ts) plus a separate executor
|
|
13
|
+
* `(args: Record<string, unknown>) => Promise<string>`. The runtime metadata
|
|
14
|
+
* (source/permissionDefault/isReadOnly/...) is attached in builtin/index.ts at
|
|
15
|
+
* registration time, NOT on the def. Registration is Task 6.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* The tool name, shared with turn-loop.ts's short-circuit check so a rename
|
|
19
|
+
* can't silently break completion detection (the name lives in exactly one
|
|
20
|
+
* place).
|
|
21
|
+
*/
|
|
22
|
+
export const COMPLETE_GOAL_TOOL_NAME = "complete_goal";
|
|
23
|
+
export const completeGoalToolDef = {
|
|
24
|
+
name: COMPLETE_GOAL_TOOL_NAME,
|
|
25
|
+
description: "声明当前目标已完全达成。仅当目标确实完整完成时才调用本工具(模型在目标完全达成时显式调用以声明完成)。" +
|
|
26
|
+
"调用后应当停止。可选传入 summary 作为一句话完成总结。\n" +
|
|
27
|
+
"Declare the current goal complete. Call this ONLY when the goal is fully achieved. " +
|
|
28
|
+
"After calling, you should stop. Optionally pass a one-line summary of what was accomplished.",
|
|
29
|
+
inputSchema: {
|
|
30
|
+
type: "object",
|
|
31
|
+
properties: {
|
|
32
|
+
summary: {
|
|
33
|
+
type: "string",
|
|
34
|
+
description: "可选:一句话总结所完成的工作。Optional one-line summary of what was accomplished.",
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
required: [],
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
export async function completeGoalTool(args) {
|
|
41
|
+
const summary = typeof args.summary === "string" ? args.summary.trim() : "";
|
|
42
|
+
return summary
|
|
43
|
+
? `目标已完成 (goal complete). Summary: ${summary}`
|
|
44
|
+
: "目标已完成 (goal complete).";
|
|
45
|
+
}
|
|
@@ -1,17 +1,41 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Cron tools — CronCreate, CronDelete, CronList.
|
|
3
3
|
*/
|
|
4
|
-
import { cronScheduler } from "../../
|
|
4
|
+
import { cronScheduler } from "../../automation/scheduler.js";
|
|
5
5
|
export const cronCreateToolDef = {
|
|
6
6
|
name: "CronCreate",
|
|
7
|
-
description: "Create a scheduled
|
|
8
|
-
"
|
|
7
|
+
description: "Create a scheduled automation job that runs a prompt on a recurring schedule. " +
|
|
8
|
+
"Use this when the user asks to set up a recurring/automated/scheduled task " +
|
|
9
|
+
"(monitoring, daily reports, periodic checks, etc.).\n\n" +
|
|
10
|
+
"Translate the user's natural-language timing into the `schedule` field. Two forms:\n" +
|
|
11
|
+
" • Interval: '30s', '5m', '1h', '1d' (runs every N from creation).\n" +
|
|
12
|
+
" • Cron expression (5 fields: minute hour day-of-month month day-of-week) for " +
|
|
13
|
+
"calendar times. Examples: '0 9 * * 1-5' = 9am every weekday; '0 */6 * * *' = every 6 hours; " +
|
|
14
|
+
"'30 8 * * 1' = 8:30am every Monday. Day-of-week: 0=Sunday..6=Saturday.\n\n" +
|
|
15
|
+
"For calendar schedules, set `timezone` to the user's IANA zone (e.g. 'Asia/Shanghai', " +
|
|
16
|
+
"'America/New_York'); ask the user if unknown. Set `cwd` to the project the job operates on. " +
|
|
17
|
+
"Leave `permissionLevel` as 'read-only' unless the user explicitly wants the job to modify code.",
|
|
9
18
|
inputSchema: {
|
|
10
19
|
type: "object",
|
|
11
20
|
properties: {
|
|
12
|
-
name: { type: "string", description: "
|
|
13
|
-
schedule: {
|
|
14
|
-
|
|
21
|
+
name: { type: "string", description: "Short human-readable name for the job (e.g. '工作日晨间简报')" },
|
|
22
|
+
schedule: {
|
|
23
|
+
type: "string",
|
|
24
|
+
description: "Interval ('5m','1h','1d') or a 5-field cron expression ('0 9 * * 1-5'). " +
|
|
25
|
+
"Derive this from the user's described timing.",
|
|
26
|
+
},
|
|
27
|
+
prompt: { type: "string", description: "The task prompt the agent runs on each execution" },
|
|
28
|
+
timezone: {
|
|
29
|
+
type: "string",
|
|
30
|
+
description: "IANA timezone for cron-expression schedules (e.g. 'Asia/Shanghai'). Optional; defaults to UTC.",
|
|
31
|
+
},
|
|
32
|
+
cwd: { type: "string", description: "Working directory / project the job runs in. Optional." },
|
|
33
|
+
permissionLevel: {
|
|
34
|
+
type: "string",
|
|
35
|
+
enum: ["read-only", "workspace-write", "full"],
|
|
36
|
+
description: "What the job may do: 'read-only' (monitoring; default), 'workspace-write' (edit files), " +
|
|
37
|
+
"'full' (edit + run git/gh to open PRs). Use the least privilege the task needs.",
|
|
38
|
+
},
|
|
15
39
|
},
|
|
16
40
|
required: ["name", "schedule", "prompt"],
|
|
17
41
|
},
|
|
@@ -22,8 +46,27 @@ export async function cronCreateTool(args) {
|
|
|
22
46
|
const prompt = args.prompt;
|
|
23
47
|
if (!name || !schedule || !prompt)
|
|
24
48
|
return "Error: name, schedule, and prompt are required";
|
|
25
|
-
const
|
|
26
|
-
|
|
49
|
+
const timezone = typeof args.timezone === "string" ? args.timezone : undefined;
|
|
50
|
+
const cwd = typeof args.cwd === "string" ? args.cwd : undefined;
|
|
51
|
+
const permissionLevel = args.permissionLevel === "read-only" ||
|
|
52
|
+
args.permissionLevel === "workspace-write" ||
|
|
53
|
+
args.permissionLevel === "full"
|
|
54
|
+
? args.permissionLevel
|
|
55
|
+
: undefined;
|
|
56
|
+
let job;
|
|
57
|
+
try {
|
|
58
|
+
job = cronScheduler.create(name, schedule, prompt, {
|
|
59
|
+
...(timezone !== undefined ? { timezone } : {}),
|
|
60
|
+
...(cwd !== undefined ? { cwd } : {}),
|
|
61
|
+
...(permissionLevel !== undefined ? { permissionLevel } : {}),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
return `Error: ${err instanceof Error ? err.message : String(err)}`;
|
|
66
|
+
}
|
|
67
|
+
const tz = job.timezone ? ` (${job.timezone})` : "";
|
|
68
|
+
const next = job.nextRun ? new Date(job.nextRun).toLocaleString() : "n/a";
|
|
69
|
+
return `Cron job #${job.id} "${job.name}" created. Schedule: ${job.schedule}${tz}. Next run: ${next}.`;
|
|
27
70
|
}
|
|
28
71
|
export const cronDeleteToolDef = {
|
|
29
72
|
name: "CronDelete",
|
|
@@ -55,7 +98,8 @@ export async function cronListTool(_args) {
|
|
|
55
98
|
const lines = jobs.map((j) => {
|
|
56
99
|
const status = j.enabled ? "active" : "paused";
|
|
57
100
|
const lastRun = j.lastRun ? new Date(j.lastRun).toLocaleString() : "never";
|
|
58
|
-
|
|
101
|
+
const tz = j.timezone ? ` ${j.timezone}` : "";
|
|
102
|
+
return ` #${j.id} "${j.name}" [${status}] ${j.schedule}${tz} | runs: ${j.runCount} | last: ${lastRun}`;
|
|
59
103
|
});
|
|
60
104
|
return `Cron Jobs (${jobs.length}):\n${lines.join("\n")}`;
|
|
61
105
|
}
|
|
@@ -2,5 +2,6 @@
|
|
|
2
2
|
* Built-in Edit file tool — exact string replacement.
|
|
3
3
|
*/
|
|
4
4
|
import type { ToolDefinition } from "../../types.js";
|
|
5
|
+
import type { ToolContext } from "../context.js";
|
|
5
6
|
export declare const editToolDef: ToolDefinition;
|
|
6
|
-
export declare function editTool(args: Record<string, unknown
|
|
7
|
+
export declare function editTool(args: Record<string, unknown>, ctx?: ToolContext): Promise<string>;
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { readFile, writeFile } from "node:fs/promises";
|
|
5
5
|
import { existsSync } from "node:fs";
|
|
6
6
|
import { fileCache } from "./file-cache.js";
|
|
7
|
+
import { enforcePathPolicy } from "../path-policy.js";
|
|
7
8
|
export const editToolDef = {
|
|
8
9
|
name: "Edit",
|
|
9
10
|
description: "Perform exact string replacements in a file. " +
|
|
@@ -30,7 +31,7 @@ export const editToolDef = {
|
|
|
30
31
|
required: ["file_path", "old_string", "new_string"],
|
|
31
32
|
},
|
|
32
33
|
};
|
|
33
|
-
export async function editTool(args) {
|
|
34
|
+
export async function editTool(args, ctx) {
|
|
34
35
|
const filePath = args.file_path;
|
|
35
36
|
const oldString = args.old_string;
|
|
36
37
|
const newString = args.new_string;
|
|
@@ -45,6 +46,10 @@ export async function editTool(args) {
|
|
|
45
46
|
return "Error: old_string and new_string must be different";
|
|
46
47
|
if (!existsSync(filePath))
|
|
47
48
|
return `Error: File not found: ${filePath}`;
|
|
49
|
+
// Path policy gate before any IO.
|
|
50
|
+
const blocked = enforcePathPolicy(filePath, "write", ctx?.cwd);
|
|
51
|
+
if (blocked)
|
|
52
|
+
return blocked;
|
|
48
53
|
try {
|
|
49
54
|
const content = await readFile(filePath, "utf-8");
|
|
50
55
|
if (!content.includes(oldString)) {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in GenerateImage tool — text-to-image via the OpenAI Images API
|
|
3
|
+
* (`gpt-image-2`).
|
|
4
|
+
*
|
|
5
|
+
* Credentials come from config, not env: the tool finds the `kind: "openai"`
|
|
6
|
+
* entry in `settings.providers[]` and uses its `apiKey` + `baseUrl`. No
|
|
7
|
+
* `OPENAI_API_KEY` required, no new config — an existing OpenAI provider is
|
|
8
|
+
* reused as-is.
|
|
9
|
+
*
|
|
10
|
+
* The generated PNG is decoded from the API's base64 payload and written to
|
|
11
|
+
* `<cwd>/.code-shell/generated_images/<timestamp>.png`; the tool returns the
|
|
12
|
+
* absolute path so the model can Read or reference it on later turns. This
|
|
13
|
+
* mirrors codex's imagegen CLI fallback (`scripts/image_gen.py`): call API →
|
|
14
|
+
* take b64_json → decode → write → report path.
|
|
15
|
+
*
|
|
16
|
+
* Scope is deliberately narrow (text-to-image only). Edit/mask/transparent/
|
|
17
|
+
* batch are out of scope — see the design doc.
|
|
18
|
+
*
|
|
19
|
+
* Uses the native `fetch` (codeshell does not depend on the `openai` SDK).
|
|
20
|
+
*/
|
|
21
|
+
import type { ToolDefinition } from "../../types.js";
|
|
22
|
+
import type { ToolContext } from "../context.js";
|
|
23
|
+
export declare const generateImageToolDef: ToolDefinition;
|
|
24
|
+
export declare function isGenerateImageAvailable(cwd?: string, nowMs?: number): boolean;
|
|
25
|
+
export declare function generateImageTool(args: Record<string, unknown>, ctx?: ToolContext): Promise<string>;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in GenerateImage tool — text-to-image via the OpenAI Images API
|
|
3
|
+
* (`gpt-image-2`).
|
|
4
|
+
*
|
|
5
|
+
* Credentials come from config, not env: the tool finds the `kind: "openai"`
|
|
6
|
+
* entry in `settings.providers[]` and uses its `apiKey` + `baseUrl`. No
|
|
7
|
+
* `OPENAI_API_KEY` required, no new config — an existing OpenAI provider is
|
|
8
|
+
* reused as-is.
|
|
9
|
+
*
|
|
10
|
+
* The generated PNG is decoded from the API's base64 payload and written to
|
|
11
|
+
* `<cwd>/.code-shell/generated_images/<timestamp>.png`; the tool returns the
|
|
12
|
+
* absolute path so the model can Read or reference it on later turns. This
|
|
13
|
+
* mirrors codex's imagegen CLI fallback (`scripts/image_gen.py`): call API →
|
|
14
|
+
* take b64_json → decode → write → report path.
|
|
15
|
+
*
|
|
16
|
+
* Scope is deliberately narrow (text-to-image only). Edit/mask/transparent/
|
|
17
|
+
* batch are out of scope — see the design doc.
|
|
18
|
+
*
|
|
19
|
+
* Uses the native `fetch` (codeshell does not depend on the `openai` SDK).
|
|
20
|
+
*/
|
|
21
|
+
import { writeFile, mkdir } from "node:fs/promises";
|
|
22
|
+
import { join } from "node:path";
|
|
23
|
+
import { SettingsManager } from "../../settings/manager.js";
|
|
24
|
+
const DEFAULT_SIZE = "1024x1024";
|
|
25
|
+
const DEFAULT_QUALITY = "auto";
|
|
26
|
+
const MODEL = "gpt-image-2";
|
|
27
|
+
export const generateImageToolDef = {
|
|
28
|
+
name: "GenerateImage",
|
|
29
|
+
description: "Generate an image from a text prompt using the OpenAI Images API (gpt-image-2). " +
|
|
30
|
+
"Saves a PNG into the workspace and returns its absolute path; read or reference " +
|
|
31
|
+
"that path on later turns. Requires an OpenAI provider (kind: \"openai\") configured " +
|
|
32
|
+
"in settings. For raster assets (photos, illustrations, mockups, textures) — not for " +
|
|
33
|
+
"SVG/vector icons or anything better built directly in code.",
|
|
34
|
+
inputSchema: {
|
|
35
|
+
type: "object",
|
|
36
|
+
properties: {
|
|
37
|
+
prompt: {
|
|
38
|
+
type: "string",
|
|
39
|
+
description: "Description of the image to generate",
|
|
40
|
+
},
|
|
41
|
+
size: {
|
|
42
|
+
type: "string",
|
|
43
|
+
enum: ["1024x1024", "1536x1024", "1024x1536", "auto"],
|
|
44
|
+
description: "Image dimensions (default 1024x1024)",
|
|
45
|
+
},
|
|
46
|
+
quality: {
|
|
47
|
+
type: "string",
|
|
48
|
+
enum: ["low", "medium", "high", "auto"],
|
|
49
|
+
description: "Render quality (default auto). Use low for drafts, high for final assets.",
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
required: ["prompt"],
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
/** Resolve the OpenAI provider's apiKey + baseUrl from settings, or null. */
|
|
56
|
+
function resolveOpenAIProvider(cwd) {
|
|
57
|
+
const settings = new SettingsManager(cwd, "full").get();
|
|
58
|
+
const provider = settings.providers.find((p) => p.kind === "openai");
|
|
59
|
+
if (!provider || !provider.apiKey)
|
|
60
|
+
return null;
|
|
61
|
+
return { baseUrl: provider.baseUrl, apiKey: provider.apiKey };
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Tool-visibility guard: GenerateImage needs a kind:"openai" provider with a
|
|
65
|
+
* key. resolveOpenAIProvider returns null when none is configured.
|
|
66
|
+
*
|
|
67
|
+
* Cached per-cwd with a short TTL: the guard runs on EVERY message's toolDefs
|
|
68
|
+
* assembly (engine.ts), and resolveOpenAIProvider reads + parses settings from
|
|
69
|
+
* disk each call. The 1s TTL collapses the back-to-back reads (same message,
|
|
70
|
+
* rapid turns) while still picking up a newly-configured key well within the
|
|
71
|
+
* gap before the user's next message. The execution path
|
|
72
|
+
* (resolveOpenAIProvider) is intentionally NOT cached — only this boolean.
|
|
73
|
+
*/
|
|
74
|
+
const availCache = new Map();
|
|
75
|
+
const AVAIL_TTL_MS = 1000;
|
|
76
|
+
export function isGenerateImageAvailable(cwd = process.cwd(), nowMs = Date.now()) {
|
|
77
|
+
const hit = availCache.get(cwd);
|
|
78
|
+
if (hit && nowMs - hit.at < AVAIL_TTL_MS)
|
|
79
|
+
return hit.value;
|
|
80
|
+
let value = false;
|
|
81
|
+
try {
|
|
82
|
+
value = resolveOpenAIProvider(cwd) !== null;
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
value = false;
|
|
86
|
+
}
|
|
87
|
+
availCache.set(cwd, { at: nowMs, value });
|
|
88
|
+
return value;
|
|
89
|
+
}
|
|
90
|
+
export async function generateImageTool(args, ctx) {
|
|
91
|
+
const prompt = args.prompt;
|
|
92
|
+
if (typeof prompt !== "string" || !prompt.trim()) {
|
|
93
|
+
return "Error: prompt is required";
|
|
94
|
+
}
|
|
95
|
+
const size = typeof args.size === "string" ? args.size : DEFAULT_SIZE;
|
|
96
|
+
const quality = typeof args.quality === "string" ? args.quality : DEFAULT_QUALITY;
|
|
97
|
+
const cwd = ctx?.cwd ?? process.cwd();
|
|
98
|
+
const provider = resolveOpenAIProvider(cwd);
|
|
99
|
+
if (!provider) {
|
|
100
|
+
return ('Error: no OpenAI provider available. Configure a provider with kind: "openai" ' +
|
|
101
|
+
"(including an apiKey) in your code-shell settings to use GenerateImage.");
|
|
102
|
+
}
|
|
103
|
+
// Trim a trailing slash so `${baseUrl}/images/generations` doesn't double up.
|
|
104
|
+
const baseUrl = provider.baseUrl.replace(/\/+$/, "");
|
|
105
|
+
let resp;
|
|
106
|
+
try {
|
|
107
|
+
resp = await fetch(`${baseUrl}/images/generations`, {
|
|
108
|
+
method: "POST",
|
|
109
|
+
headers: {
|
|
110
|
+
Authorization: `Bearer ${provider.apiKey}`,
|
|
111
|
+
"Content-Type": "application/json",
|
|
112
|
+
},
|
|
113
|
+
body: JSON.stringify({ model: MODEL, prompt, size, quality, n: 1 }),
|
|
114
|
+
signal: ctx?.signal,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
return `Error generating image: ${err.message}`;
|
|
119
|
+
}
|
|
120
|
+
if (!resp.ok) {
|
|
121
|
+
const body = (await resp.text().catch(() => "")).slice(0, 500);
|
|
122
|
+
return `Error: image API returned ${resp.status}: ${body}`;
|
|
123
|
+
}
|
|
124
|
+
let json;
|
|
125
|
+
try {
|
|
126
|
+
json = await resp.json();
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
return `Error: could not parse image API response: ${err.message}`;
|
|
130
|
+
}
|
|
131
|
+
const b64 = json?.data?.[0]?.b64_json;
|
|
132
|
+
if (typeof b64 !== "string" || !b64) {
|
|
133
|
+
const preview = JSON.stringify(json).slice(0, 500);
|
|
134
|
+
return `Error: no image in response: ${preview}`;
|
|
135
|
+
}
|
|
136
|
+
try {
|
|
137
|
+
const dir = join(cwd, ".code-shell", "generated_images");
|
|
138
|
+
await mkdir(dir, { recursive: true });
|
|
139
|
+
const path = join(dir, `${Date.now()}.png`);
|
|
140
|
+
await writeFile(path, Buffer.from(b64, "base64"));
|
|
141
|
+
return `Generated image saved to ${path}`;
|
|
142
|
+
}
|
|
143
|
+
catch (err) {
|
|
144
|
+
return `Error saving generated image: ${err.message}`;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { glob } from "glob";
|
|
5
5
|
import { stat } from "node:fs/promises";
|
|
6
6
|
import * as path from "node:path";
|
|
7
|
+
import { enforcePathPolicy } from "../path-policy.js";
|
|
7
8
|
export const globToolDef = {
|
|
8
9
|
name: "Glob",
|
|
9
10
|
description: "Fast file pattern matching. Returns matching file paths sorted by modification time. " +
|
|
@@ -31,6 +32,12 @@ export async function globTool(args, ctx) {
|
|
|
31
32
|
? argPath
|
|
32
33
|
: path.resolve(baseDir, argPath)
|
|
33
34
|
: baseDir;
|
|
35
|
+
// Path policy: refuse to glob a search root the policy classifies as
|
|
36
|
+
// ask/deny for read. Stops a Glob("**/*", "/home/user/.ssh") from
|
|
37
|
+
// enumerating the keys directory under the existence-check radar.
|
|
38
|
+
const blocked = enforcePathPolicy(cwd, "read", ctx?.cwd);
|
|
39
|
+
if (blocked)
|
|
40
|
+
return blocked;
|
|
34
41
|
try {
|
|
35
42
|
const matches = await glob(pattern, {
|
|
36
43
|
cwd,
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { execFile } from "node:child_process";
|
|
5
5
|
import { promisify } from "node:util";
|
|
6
6
|
import { resolve, sep, isAbsolute } from "node:path";
|
|
7
|
+
import { enforcePathPolicy } from "../path-policy.js";
|
|
7
8
|
const execFileAsync = promisify(execFile);
|
|
8
9
|
/**
|
|
9
10
|
* Strip the cwd prefix from each line so results display as relative
|
|
@@ -58,6 +59,11 @@ export async function grepTool(args, ctx) {
|
|
|
58
59
|
? argPath
|
|
59
60
|
: resolve(baseDir, argPath)
|
|
60
61
|
: baseDir;
|
|
62
|
+
// Path policy: reading file contents under ~/.ssh, ~/.aws etc. by way
|
|
63
|
+
// of grep is the same exfiltration risk as Read. Gate the search root.
|
|
64
|
+
const blocked = enforcePathPolicy(searchPath, "read", ctx?.cwd);
|
|
65
|
+
if (blocked)
|
|
66
|
+
return blocked;
|
|
61
67
|
const fileGlob = args.glob;
|
|
62
68
|
const context = args.context || 0;
|
|
63
69
|
const maxResults = args.max_results || 50;
|
|
@@ -12,9 +12,26 @@ import type { RegisteredTool } from "../../types.js";
|
|
|
12
12
|
* ctx is optional in the signature so legacy call sites (and tests) that
|
|
13
13
|
* pass only args still type-check; ToolRegistry always passes ctx at runtime.
|
|
14
14
|
*/
|
|
15
|
-
|
|
15
|
+
/**
|
|
16
|
+
* 内置工具返回值:大多数返回纯文本字符串。需要回传图片(或其它结构化
|
|
17
|
+
* 内容块)的工具(view_image)可改为返回 `{ contentBlocks }`;此时
|
|
18
|
+
* registry 会把它放进 ToolResult.contentBlocks。可选的 `result` 字段是给
|
|
19
|
+
* transcript / 摘要用的纯文本镜像。
|
|
20
|
+
*/
|
|
21
|
+
export type BuiltinToolResult = string | {
|
|
22
|
+
contentBlocks: import("../../types.js").ContentBlock[];
|
|
23
|
+
result?: string;
|
|
24
|
+
};
|
|
25
|
+
export type BuiltinToolFn = (args: Record<string, unknown>, ctx?: import("../context.js").ToolContext) => Promise<BuiltinToolResult>;
|
|
16
26
|
export interface BuiltinTool {
|
|
17
27
|
definition: RegisteredTool;
|
|
18
28
|
execute: BuiltinToolFn;
|
|
19
29
|
}
|
|
20
30
|
export declare const BUILTIN_TOOLS: BuiltinTool[];
|
|
31
|
+
/**
|
|
32
|
+
* Per-tool availability predicates. A tool listed here is filtered OUT of the
|
|
33
|
+
* exposed toolDefs when its predicate returns false for the active cwd (see
|
|
34
|
+
* engine.ts toolDefs assembly). Tools NOT listed here are always visible.
|
|
35
|
+
* Keyed by the tool's `name` (must match the toolDef name).
|
|
36
|
+
*/
|
|
37
|
+
export declare const BUILTIN_TOOL_GUARDS: Map<string, (cwd: string) => boolean>;
|
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { readToolDef, readTool } from "./read.js";
|
|
5
5
|
import { writeToolDef, writeTool } from "./write.js";
|
|
6
|
+
import { generateImageToolDef, generateImageTool, isGenerateImageAvailable } from "./generate-image.js";
|
|
7
|
+
import { viewImageToolDef, viewImageTool } from "./view-image.js";
|
|
6
8
|
import { editToolDef, editTool } from "./edit.js";
|
|
7
9
|
import { applyPatchToolDef, applyPatchTool } from "./apply-patch/index.js";
|
|
8
10
|
import { globToolDef, globTool } from "./glob.js";
|
|
9
11
|
import { grepToolDef, grepTool } from "./grep.js";
|
|
10
12
|
import { bashToolDef, bashTool } from "./bash.js";
|
|
11
|
-
import { webSearchToolDef, webSearchTool } from "./web-search.js";
|
|
13
|
+
import { webSearchToolDef, webSearchTool, isWebSearchAvailable } from "./web-search.js";
|
|
12
14
|
import { webFetchToolDef, webFetchTool } from "./web-fetch.js";
|
|
13
15
|
import { askUserToolDef, askUserTool } from "./ask-user.js";
|
|
14
16
|
import { agentToolDef, agentTool, agentStatusToolDef, agentStatusTool, agentCancelToolDef, agentCancelTool, } from "./agent.js";
|
|
@@ -30,6 +32,8 @@ import { briefToolDef, briefTool } from "./brief.js";
|
|
|
30
32
|
import { powershellToolDef, powershellTool } from "./powershell.js";
|
|
31
33
|
import { arenaToolDef, arenaTool } from "./arena.js";
|
|
32
34
|
import { memoryListToolDef, memoryListTool, memoryReadToolDef, memoryReadTool, memorySaveToolDef, memorySaveTool, memoryDeleteToolDef, memoryDeleteTool, } from "./memory.js";
|
|
35
|
+
import { completeGoalToolDef, completeGoalTool } from "./complete-goal.js";
|
|
36
|
+
import { addMarketplaceToolDef, addMarketplaceTool } from "./add-marketplace.js";
|
|
33
37
|
export const BUILTIN_TOOLS = [
|
|
34
38
|
{
|
|
35
39
|
definition: {
|
|
@@ -51,6 +55,27 @@ export const BUILTIN_TOOLS = [
|
|
|
51
55
|
},
|
|
52
56
|
execute: writeTool,
|
|
53
57
|
},
|
|
58
|
+
{
|
|
59
|
+
definition: {
|
|
60
|
+
...generateImageToolDef,
|
|
61
|
+
source: "builtin",
|
|
62
|
+
permissionDefault: "ask",
|
|
63
|
+
isReadOnly: false,
|
|
64
|
+
isConcurrencySafe: false,
|
|
65
|
+
timeoutMs: 600_000, // 10min — high-quality / large image generation routinely exceeds the 120s default; give slow renders ample room while still bounding a hung request (Stop / ctx.signal cancels sooner)
|
|
66
|
+
},
|
|
67
|
+
execute: generateImageTool,
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
definition: {
|
|
71
|
+
...viewImageToolDef,
|
|
72
|
+
source: "builtin",
|
|
73
|
+
permissionDefault: "allow",
|
|
74
|
+
isReadOnly: true,
|
|
75
|
+
isConcurrencySafe: true,
|
|
76
|
+
},
|
|
77
|
+
execute: viewImageTool,
|
|
78
|
+
},
|
|
54
79
|
{
|
|
55
80
|
definition: {
|
|
56
81
|
...editToolDef,
|
|
@@ -446,4 +471,40 @@ export const BUILTIN_TOOLS = [
|
|
|
446
471
|
},
|
|
447
472
|
execute: memoryDeleteTool,
|
|
448
473
|
},
|
|
474
|
+
// ─── Goal mode: model-declared completion ──────────────────────
|
|
475
|
+
// Lets the model explicitly declare the active goal complete. The
|
|
476
|
+
// turn-loop short-circuits on this call; the tool itself only records an
|
|
477
|
+
// acknowledgement string, so it's read-only and concurrency-safe.
|
|
478
|
+
{
|
|
479
|
+
definition: {
|
|
480
|
+
...completeGoalToolDef,
|
|
481
|
+
source: "builtin",
|
|
482
|
+
permissionDefault: "allow",
|
|
483
|
+
isReadOnly: true,
|
|
484
|
+
isConcurrencySafe: true,
|
|
485
|
+
},
|
|
486
|
+
execute: completeGoalTool,
|
|
487
|
+
},
|
|
488
|
+
// ─── Plugin marketplace: model-driven source registration ──────
|
|
489
|
+
{
|
|
490
|
+
definition: {
|
|
491
|
+
...addMarketplaceToolDef,
|
|
492
|
+
source: "builtin",
|
|
493
|
+
permissionDefault: "ask",
|
|
494
|
+
isReadOnly: false,
|
|
495
|
+
isConcurrencySafe: false,
|
|
496
|
+
timeoutMs: 120_000, // git clone over network
|
|
497
|
+
},
|
|
498
|
+
execute: addMarketplaceTool,
|
|
499
|
+
},
|
|
449
500
|
];
|
|
501
|
+
/**
|
|
502
|
+
* Per-tool availability predicates. A tool listed here is filtered OUT of the
|
|
503
|
+
* exposed toolDefs when its predicate returns false for the active cwd (see
|
|
504
|
+
* engine.ts toolDefs assembly). Tools NOT listed here are always visible.
|
|
505
|
+
* Keyed by the tool's `name` (must match the toolDef name).
|
|
506
|
+
*/
|
|
507
|
+
export const BUILTIN_TOOL_GUARDS = new Map([
|
|
508
|
+
[webSearchToolDef.name, isWebSearchAvailable],
|
|
509
|
+
[generateImageToolDef.name, isGenerateImageAvailable],
|
|
510
|
+
]);
|
|
@@ -2,5 +2,6 @@
|
|
|
2
2
|
* NotebookEditTool — read and edit Jupyter notebook (.ipynb) cells.
|
|
3
3
|
*/
|
|
4
4
|
import type { ToolDefinition } from "../../types.js";
|
|
5
|
+
import type { ToolContext } from "../context.js";
|
|
5
6
|
export declare const notebookEditToolDef: ToolDefinition;
|
|
6
|
-
export declare function notebookEditTool(args: Record<string, unknown
|
|
7
|
+
export declare function notebookEditTool(args: Record<string, unknown>, ctx?: ToolContext): Promise<string>;
|