@sema-agent/core 4.0.0 → 5.0.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/CHANGELOG.md +37 -0
- package/dist/agents/cascade.d.ts +1 -0
- package/dist/agents/cascade.js +1 -1
- package/dist/agents/repair-loop.d.ts +2 -0
- package/dist/agents/repair-loop.js +21 -5
- package/dist/agents/roster-store.d.ts +1 -0
- package/dist/agents/roster-store.js +1 -1
- package/dist/agents/send-message-tool.d.ts +1 -0
- package/dist/agents/send-message-tool.js +2 -0
- package/dist/agents/subagent.d.ts +3 -1
- package/dist/agents/subagent.js +15 -32
- package/dist/agents/tool-filter.js +6 -7
- package/dist/agents/verify.d.ts +1 -0
- package/dist/agents/verify.js +1 -1
- package/dist/core/arg-summary.d.ts +21 -1
- package/dist/core/arg-summary.js +61 -14
- package/dist/core/auto-compaction.d.ts +1 -0
- package/dist/core/auto-compaction.js +1 -1
- package/dist/core/fs-write-gate-policy.js +2 -3
- package/dist/core/hooks.d.ts +1 -0
- package/dist/core/hooks.js +1 -1
- package/dist/core/mcp.js +0 -6
- package/dist/core/permission-rules.js +2 -3
- package/dist/core/runner/active-skill-scope.js +1 -2
- package/dist/core/runner/prepare-task.js +16 -8
- package/dist/core/runner/runtask.js +19 -16
- package/dist/core/runner/session-rule-policy.js +3 -4
- package/dist/core/sensitive-path-policy.js +2 -3
- package/dist/core/session-reconcile.js +1 -2
- package/dist/core/skill-tool-specifier.js +2 -3
- package/dist/core/skills-directory.js +2 -3
- package/dist/core/task-registry-shared.d.ts +1 -1
- package/dist/core/task-registry.d.ts +5 -1
- package/dist/core/task-registry.js +12 -30
- package/dist/core/task-tool-shape.d.ts +0 -2
- package/dist/core/task-tool-shape.js +2 -5
- package/dist/core/tool-name-aliases.d.ts +1 -2
- package/dist/core/tool-name-aliases.js +42 -60
- package/dist/core/tool-policy.js +11 -12
- package/dist/core/trace.d.ts +7 -0
- package/dist/core/untrusted-egress.d.ts +4 -2
- package/dist/core/untrusted-egress.js +21 -9
- package/dist/engine/execution-env/node-execution-env.js +1 -1
- package/dist/engine/loop/agent-loop.js +3 -12
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -2
- package/dist/orchestration/run-spec.js +2 -3
- package/dist/orchestration/run-workflow-tool.js +0 -1
- package/dist/orchestration/workflow-governance.js +2 -1
- package/dist/orchestration/workflow.d.ts +1 -0
- package/dist/orchestration/workflow.js +1 -1
- package/dist/prompt-assembly/packs/sema-default.js +1 -3
- package/dist/prompts/default.js +1 -3
- package/dist/prompts/simple-sections.d.ts +0 -1
- package/dist/prompts/simple-sections.js +0 -1
- package/dist/tools/fs/fs-bash.js +6 -8
- package/dist/tools/fs/fs-write.js +0 -1
- package/package.json +1 -1
|
@@ -1,60 +1,42 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
"If no # Memory section is present, memory is not enabled for this task; do not retry this tool.";
|
|
44
|
-
export const TOMBSTONED_TOOLS = {
|
|
45
|
-
Sleep: 'Sleep was removed. To pause and resume later, schedule a self-contained re-wake with CronCreate({ schedule: { kind: "delay", delaySec: … }, prompt: "<what to do on wake>" }) and then end your turn. To wait for an external condition or a long-running command, use Monitor. Do not poll in a loop.',
|
|
46
|
-
Fork: 'Fork was removed as a standalone tool. Use Agent with subagent_type: "fork" instead — it spawns the same context-inheriting child (pass your directive as \'prompt\'; run_in_background is supported).',
|
|
47
|
-
Remember: MEMORY_TOOLS_TOMBSTONE,
|
|
48
|
-
remember: MEMORY_TOOLS_TOMBSTONE,
|
|
49
|
-
Recall: MEMORY_TOOLS_TOMBSTONE,
|
|
50
|
-
recall: MEMORY_TOOLS_TOMBSTONE,
|
|
51
|
-
};
|
|
52
|
-
const MCP_PREFIX = "mcp__";
|
|
53
|
-
const MCP_NAME_SEP = "__";
|
|
54
|
-
export function canonicalToolName(name) {
|
|
55
|
-
const mapped = Object.hasOwn(OLD_TO_NEW, name) ? OLD_TO_NEW[name] : undefined;
|
|
56
|
-
const renamed = typeof mapped === "string" ? mapped : name;
|
|
57
|
-
if (renamed.includes(MCP_NAME_SEP) && !renamed.startsWith(MCP_PREFIX))
|
|
58
|
-
return MCP_PREFIX + renamed;
|
|
59
|
-
return renamed;
|
|
60
|
-
}
|
|
1
|
+
export const RETIRED_TOOL_NAMES = new Map([
|
|
2
|
+
["read_file", 'renamed "Read"'],
|
|
3
|
+
["edit_file", 'renamed "Edit"'],
|
|
4
|
+
["write_file", 'renamed "Write"'],
|
|
5
|
+
["bash", 'renamed "Bash"'],
|
|
6
|
+
["bash_readonly", 'folded into "Bash" (read-only posture rides handsReadOnly/shellGate, not a tool name)'],
|
|
7
|
+
["glob", 'renamed "Glob"'],
|
|
8
|
+
["grep", 'renamed "Grep"'],
|
|
9
|
+
["web_fetch", 'renamed "WebFetch"'],
|
|
10
|
+
["tool_search", 'renamed "ToolSearch"'],
|
|
11
|
+
["skill", 'renamed "Skill"'],
|
|
12
|
+
["present_plan", 'renamed "ExitPlanMode"'],
|
|
13
|
+
["enter_plan_mode", 'renamed "EnterPlanMode"'],
|
|
14
|
+
["spawn_subagent", 'renamed "Agent"'],
|
|
15
|
+
["CronCancel", 'renamed "CronDelete"'],
|
|
16
|
+
["lsp", 'renamed "LSP"'],
|
|
17
|
+
["submit_output", 'renamed "StructuredOutput"'],
|
|
18
|
+
["repo_map", 'renamed "RepoMap"'],
|
|
19
|
+
["read_tool_result", 'renamed "ReadToolResult"'],
|
|
20
|
+
["report_blocked", 'renamed "ReportBlocked"'],
|
|
21
|
+
["declare_done", 'renamed "DeclareDone"'],
|
|
22
|
+
["run_workflow", 'renamed "Workflow"'],
|
|
23
|
+
["RunWorkflow", 'renamed "Workflow"'],
|
|
24
|
+
["Task", 'renamed "Agent" (a deployment-defined tool named "Task" is fine — this fires only when the name matches nothing in the roster)'],
|
|
25
|
+
["BashOutput", 'renamed "TaskOutput"'],
|
|
26
|
+
["AgentOutputTool", 'renamed "TaskOutput"'],
|
|
27
|
+
["BashOutputTool", 'renamed "TaskOutput"'],
|
|
28
|
+
["AgentOutput", 'renamed "TaskOutput"'],
|
|
29
|
+
["WorkflowStatus", 'folded into "TaskOutput" (poll by runId)'],
|
|
30
|
+
["KillShell", 'renamed "TaskStop"'],
|
|
31
|
+
["KillBash", 'renamed "TaskStop"'],
|
|
32
|
+
["ListMcpResources", 'renamed "ListMcpResourcesTool"'],
|
|
33
|
+
["ReadMcpResource", 'renamed "ReadMcpResourceTool"'],
|
|
34
|
+
["ReadMcpResourceDir", 'renamed "ReadMcpResourceDirTool"'],
|
|
35
|
+
["MultiEdit", 'removed — "Edit" accepts the edits[] shape'],
|
|
36
|
+
["Fork", 'removed — use Agent with subagent_type: "fork"'],
|
|
37
|
+
["Sleep", "removed — schedule a re-wake with CronCreate({schedule:{kind:\"delay\"}}) or wait with Monitor"],
|
|
38
|
+
["Remember", "removed — memory is file-based; write the memory directory with the ordinary file tools"],
|
|
39
|
+
["remember", "removed — memory is file-based; write the memory directory with the ordinary file tools"],
|
|
40
|
+
["Recall", "removed — memory is file-based; read the memory directory with the ordinary file tools"],
|
|
41
|
+
["recall", "removed — memory is file-based; read the memory directory with the ordinary file tools"],
|
|
42
|
+
]);
|
package/dist/core/tool-policy.js
CHANGED
|
@@ -2,7 +2,6 @@ import { homedir } from "node:os";
|
|
|
2
2
|
import { isAbsolute, join, normalize as normalizePath, sep } from "node:path";
|
|
3
3
|
import { BASH_READONLY_DEFAULT_ALLOW, parseLeadingCommandName } from "../tools/fs/index.js";
|
|
4
4
|
import { writeTargetPath } from "../tools/fs/safety.js";
|
|
5
|
-
import { canonicalToolName } from "./tool-name-aliases.js";
|
|
6
5
|
export function decisionText(d) {
|
|
7
6
|
return d.message ?? d.reason;
|
|
8
7
|
}
|
|
@@ -33,12 +32,12 @@ export function toolPolicyNameSets(p) {
|
|
|
33
32
|
return Array.isArray(sets) ? sets : [];
|
|
34
33
|
}
|
|
35
34
|
export function createAllowDenyPolicy(opts) {
|
|
36
|
-
const allow = opts.allow ? new Set(opts.allow
|
|
37
|
-
const deny = new Set(
|
|
35
|
+
const allow = opts.allow ? new Set(opts.allow) : undefined;
|
|
36
|
+
const deny = new Set(opts.deny ?? []);
|
|
38
37
|
return {
|
|
39
38
|
nameSets: [{ ...(opts.allow ? { allow: [...opts.allow] } : {}), ...(opts.deny ? { deny: [...opts.deny] } : {}) }],
|
|
40
39
|
check(req) {
|
|
41
|
-
const toolName =
|
|
40
|
+
const toolName = req.toolName;
|
|
42
41
|
if (deny.has(toolName)) {
|
|
43
42
|
return { action: "deny", reason: `tool "${req.toolName}" is denied by policy` };
|
|
44
43
|
}
|
|
@@ -53,9 +52,9 @@ export function createApprovalPolicy(opts) {
|
|
|
53
52
|
if (opts.approvalTimeoutMs !== undefined && !Number.isFinite(opts.approvalTimeoutMs)) {
|
|
54
53
|
throw new Error(`createApprovalPolicy: approvalTimeoutMs must be a finite number of ms (got ${opts.approvalTimeoutMs}) — omit it to wait indefinitely`);
|
|
55
54
|
}
|
|
56
|
-
const need = new Set(opts.requireApproval
|
|
57
|
-
const deny = new Set(
|
|
58
|
-
const auto = new Set(
|
|
55
|
+
const need = new Set(opts.requireApproval);
|
|
56
|
+
const deny = new Set(opts.deny ?? []);
|
|
57
|
+
const auto = new Set(opts.autoAllow ?? []);
|
|
59
58
|
return {
|
|
60
59
|
nameSets: [
|
|
61
60
|
{
|
|
@@ -65,7 +64,7 @@ export function createApprovalPolicy(opts) {
|
|
|
65
64
|
},
|
|
66
65
|
],
|
|
67
66
|
async check(req, signal) {
|
|
68
|
-
const toolName =
|
|
67
|
+
const toolName = req.toolName;
|
|
69
68
|
if (deny.has(toolName)) {
|
|
70
69
|
return { action: "deny", reason: `tool "${req.toolName}" is denied by policy` };
|
|
71
70
|
}
|
|
@@ -123,7 +122,7 @@ export function combinePolicies(...policies) {
|
|
|
123
122
|
}
|
|
124
123
|
export const COARSE_SHELL_TOOLS = ["Bash", "Monitor"];
|
|
125
124
|
function canonicalToolNameSet(tools) {
|
|
126
|
-
return new Set(
|
|
125
|
+
return new Set(tools ?? COARSE_SHELL_TOOLS);
|
|
127
126
|
}
|
|
128
127
|
export function createCoarseCommandNamePolicy(opts) {
|
|
129
128
|
const allow = opts.allow ? new Set(opts.allow) : undefined;
|
|
@@ -135,7 +134,7 @@ export function createCoarseCommandNamePolicy(opts) {
|
|
|
135
134
|
: { action: "ask", message: reason, decisionReason: "rule" };
|
|
136
135
|
return {
|
|
137
136
|
check(req) {
|
|
138
|
-
if (!shellTools.has(
|
|
137
|
+
if (!shellTools.has(req.toolName))
|
|
139
138
|
return ALLOW;
|
|
140
139
|
const command = req.args?.command;
|
|
141
140
|
if (typeof command !== "string") {
|
|
@@ -383,7 +382,7 @@ export function createUnverifiableDeletePolicy(opts) {
|
|
|
383
382
|
const shellTools = canonicalToolNameSet(opts?.tools);
|
|
384
383
|
return {
|
|
385
384
|
check(req) {
|
|
386
|
-
if (!shellTools.has(
|
|
385
|
+
if (!shellTools.has(req.toolName))
|
|
387
386
|
return ALLOW;
|
|
388
387
|
const command = req.args?.command;
|
|
389
388
|
if (typeof command !== "string")
|
|
@@ -476,7 +475,7 @@ export function createTranscriptIntegrityPolicy(opts) {
|
|
|
476
475
|
});
|
|
477
476
|
return {
|
|
478
477
|
check(req) {
|
|
479
|
-
const toolName =
|
|
478
|
+
const toolName = req.toolName;
|
|
480
479
|
if (shellTools.has(toolName)) {
|
|
481
480
|
const command = req.args?.command;
|
|
482
481
|
if (typeof command !== "string")
|
package/dist/core/trace.d.ts
CHANGED
|
@@ -176,6 +176,13 @@ export type TraceEvent = {
|
|
|
176
176
|
reason: "breaker_open" | "rate_limit" | "budget" | "server_error" | "last_resort";
|
|
177
177
|
atTurn: number;
|
|
178
178
|
ts: number;
|
|
179
|
+
} | {
|
|
180
|
+
kind: "observer.notify_failed";
|
|
181
|
+
version: 1;
|
|
182
|
+
taskId: string;
|
|
183
|
+
site: string;
|
|
184
|
+
message: string;
|
|
185
|
+
ts: number;
|
|
179
186
|
} | {
|
|
180
187
|
kind: "brain.failover";
|
|
181
188
|
version: 1;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
1
|
+
import { type RedactionReport } from "./arg-summary.js";
|
|
2
|
+
export type { RedactionFinding, RedactionReport, RedactionConfidence } from "./arg-summary.js";
|
|
3
|
+
export declare function redactSecrets(s: string, report?: RedactionReport): string;
|
|
4
|
+
export declare function redactHostLeaks(s: string, report?: RedactionReport): string;
|
|
3
5
|
export declare function boundedRedactedSummary(value: unknown, max: number): string;
|
|
4
6
|
export declare function untrustedEgressForHuman(value: unknown, opts: {
|
|
5
7
|
label: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { delimitUntrusted } from "./untrusted-text.js";
|
|
2
|
-
import { scrubSecrets } from "./arg-summary.js";
|
|
2
|
+
import { scrubSecrets, SECRET_PASSES, runRedactionPasses } from "./arg-summary.js";
|
|
3
3
|
import { sliceHeadSafe } from "./surrogate-safe-slice.js";
|
|
4
4
|
const URI_SCHEME = String.raw `[A-Za-z][A-Za-z0-9+.\-_]{0,63}`;
|
|
5
5
|
const CREDENTIALS_IN_AUTHORITY = new RegExp(String.raw `(${URI_SCHEME}:\/\/)((?:[^/\s"'@]*@)+)`, "gi");
|
|
@@ -15,15 +15,27 @@ function redactUserinfo(scheme, userinfoWithAt) {
|
|
|
15
15
|
}
|
|
16
16
|
return `${scheme}${userinfo.slice(0, colonIdx)}:[redacted-credentials]@`;
|
|
17
17
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
const SECRET_TIER_PASSES = [
|
|
19
|
+
...SECRET_PASSES,
|
|
20
|
+
{
|
|
21
|
+
kind: "url-credentials",
|
|
22
|
+
confidence: "medium",
|
|
23
|
+
marker: "[redacted-credentials]",
|
|
24
|
+
re: CREDENTIALS_IN_AUTHORITY,
|
|
25
|
+
replace: (_m, scheme, userinfo) => redactUserinfo(scheme, userinfo),
|
|
26
|
+
},
|
|
27
|
+
{ kind: "signed-url-param", confidence: "high", marker: "[redacted]", re: /([?&#](?:sig|signature|sas|code)=)[^&\s"'#]+/gi, replace: "$1[redacted]" },
|
|
28
|
+
];
|
|
29
|
+
export function redactSecrets(s, report) {
|
|
30
|
+
return runRedactionPasses(s, SECRET_TIER_PASSES, report);
|
|
22
31
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
32
|
+
const HOST_LEAK_PASSES = [
|
|
33
|
+
...SECRET_TIER_PASSES,
|
|
34
|
+
{ kind: "url", confidence: "medium", marker: "[redacted-url]", re: URL_OF_ANY_PROTOCOL, replace: "[redacted-url]" },
|
|
35
|
+
{ kind: "fs-path", confidence: "low", marker: "[redacted-path]", re: /(?:\/[A-Za-z0-9_.-]+){2,}/g, replace: "[redacted-path]" },
|
|
36
|
+
];
|
|
37
|
+
export function redactHostLeaks(s, report) {
|
|
38
|
+
return runRedactionPasses(s, HOST_LEAK_PASSES, report);
|
|
27
39
|
}
|
|
28
40
|
const REDACTION_MARKER_RE = /\[redacted(?:-[a-z]+)?\]/g;
|
|
29
41
|
function countRedactionMarkers(s) {
|
|
@@ -270,7 +270,7 @@ export class NodeExecutionEnv {
|
|
|
270
270
|
this.backgroundCapabilities = {
|
|
271
271
|
supported: true,
|
|
272
272
|
maxConcurrent: 8,
|
|
273
|
-
defaultBgTimeoutSec:
|
|
273
|
+
defaultBgTimeoutSec: 60 * 60,
|
|
274
274
|
maxBgTimeoutSec: 2 * 60 * 60,
|
|
275
275
|
supportsDetach: true,
|
|
276
276
|
retainBackgroundProcesses: this.retainBackgroundProcesses,
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { findToolByName, validateToolArguments } from "../llm/index.js";
|
|
2
|
-
import { TOMBSTONED_TOOLS } from "../../core/tool-name-aliases.js";
|
|
3
2
|
import { resolveAgentCoreStreamFn } from "./runtime-deps.js";
|
|
4
3
|
function appendTextDeltaToAssistantMessage(message, contentIndex, delta) {
|
|
5
4
|
const content = [...message.content];
|
|
@@ -933,19 +932,11 @@ function prepareToolCallArguments(tool, toolCall) {
|
|
|
933
932
|
async function prepareToolCall(currentContext, assistantMessage, toolCall, config, signal) {
|
|
934
933
|
const tool = findToolByName(currentContext.tools, toolCall.name);
|
|
935
934
|
if (!tool) {
|
|
936
|
-
const
|
|
937
|
-
const
|
|
938
|
-
if (tombstone !== undefined) {
|
|
939
|
-
return {
|
|
940
|
-
kind: "immediate",
|
|
941
|
-
result: createErrorToolResult(tombstone),
|
|
942
|
-
isError: true,
|
|
943
|
-
};
|
|
944
|
-
}
|
|
945
|
-
const available = (currentContext.tools ?? []).map((t) => t.name).join(", ");
|
|
935
|
+
const availableTools = (currentContext.tools ?? []).map((t) => t.name);
|
|
936
|
+
const available = availableTools.join(", ");
|
|
946
937
|
return {
|
|
947
938
|
kind: "immediate",
|
|
948
|
-
result: createErrorToolResult(`Tool ${toolCall.name} not found.${available ? ` Available tools: ${available}` : ""}
|
|
939
|
+
result: createErrorToolResult(`Tool ${toolCall.name} not found.${available ? ` Available tools: ${available}` : ""}`, { details: { code: "tool.not_found", toolName: toolCall.name, availableTools } }),
|
|
949
940
|
isError: true,
|
|
950
941
|
};
|
|
951
942
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -82,8 +82,8 @@ export { maybeCompact, type MaybeCompactOptions, type CompactionWindowSafetyInfo
|
|
|
82
82
|
export { brainToRuntime } from "./core/runtime.js";
|
|
83
83
|
export { createSensitivePathPolicy, RECOMMENDED_SENSITIVE_PATTERNS } from "./core/sensitive-path-policy.js";
|
|
84
84
|
export { createFsWriteGatePolicy, type FsWriteGatePolicyOptions } from "./core/fs-write-gate-policy.js";
|
|
85
|
-
export {
|
|
86
|
-
export { DEFAULT_SUBAGENT_TOOL_NAME,
|
|
85
|
+
export { RETIRED_TOOL_NAMES } from "./core/tool-name-aliases.js";
|
|
86
|
+
export { DEFAULT_SUBAGENT_TOOL_NAME, SESSION_BG_DEFAULT_TIMEOUT_SEC } from "./agents/subagent.js";
|
|
87
87
|
export { renderTaskNotificationXml, taskNotificationDedupKey, SystemInjectionQueue, type TaskNotificationPayload, type TaskNotificationStatus, type ExternalNotificationInput, type SystemInjection, type SystemInjectionPriority, } from "./core/task-notification.js";
|
|
88
88
|
export { TaskRegistry, defaultTaskRegistry, createTaskOutputTool, createTaskStopTool, type SemaTaskType, type SemaTaskStatus, type SemaTaskHandle, type ParkedClaimTicket, type TaskAccess, type UnifiedTaskOutput, type TaskRetrievalStatus, type StopSource, type RegisterMonitorInput, type MonitorTimers, MONITOR_BATCH_WINDOW_MS, MONITOR_DEFAULT_TIMEOUT_MS, MONITOR_MAX_TIMEOUT_MS, MONITOR_MAX_BATCHES_PER_MINUTE, canAccessWorkflowRun, DURABLE_AGENT_HANDLE_RE, } from "./core/task-registry.js";
|
|
89
89
|
export { InMemoryMailboxStore, type MailboxStore, type MailboxMessage, type MailboxLease } from "./core/mailbox-store.js";
|
|
@@ -166,6 +166,7 @@ export { type BackgroundAgentStore, type BackgroundAgentRecord, type BackgroundA
|
|
|
166
166
|
export { FileBackgroundAgentStore, type FileBackgroundAgentStoreOptions } from "./stores/file/background-agent-store.js";
|
|
167
167
|
export { type WorkflowJournalStore, type WorkflowJournalEntry, InMemoryWorkflowJournalStore, callKeyOrdinal, JOURNAL_OVERSIZE_ERROR_CODE, } from "./core/workflow-journal-store.js";
|
|
168
168
|
export { untrustedEgressForHuman, redactHostLeaks, redactSecrets, boundedRedactedSummary } from "./core/untrusted-egress.js";
|
|
169
|
+
export type { RedactionFinding, RedactionReport, RedactionConfidence } from "./core/untrusted-egress.js";
|
|
169
170
|
export { MemoryRosterStore, FileRosterStore, type RosterStore, type RosterEntry, type RosterAccess, type RosterGcOptions } from "./agents/roster-store.js";
|
|
170
171
|
export { CONFIG_CATALOG_VERSION, describeConfigCatalog, resolveEffectiveConfig, type ConfigKnob, type ConfigOverrideDeclaration, type ConfigProvenance, type EffectiveConfigField, } from "./config/catalog.js";
|
|
171
172
|
export { normalizeAgentName } from "./core/task-registry.js";
|
package/dist/index.js
CHANGED
|
@@ -71,8 +71,8 @@ export { maybeCompact } from "./core/auto-compaction.js";
|
|
|
71
71
|
export { brainToRuntime } from "./core/runtime.js";
|
|
72
72
|
export { createSensitivePathPolicy, RECOMMENDED_SENSITIVE_PATTERNS } from "./core/sensitive-path-policy.js";
|
|
73
73
|
export { createFsWriteGatePolicy } from "./core/fs-write-gate-policy.js";
|
|
74
|
-
export {
|
|
75
|
-
export { DEFAULT_SUBAGENT_TOOL_NAME,
|
|
74
|
+
export { RETIRED_TOOL_NAMES } from "./core/tool-name-aliases.js";
|
|
75
|
+
export { DEFAULT_SUBAGENT_TOOL_NAME, SESSION_BG_DEFAULT_TIMEOUT_SEC } from "./agents/subagent.js";
|
|
76
76
|
export { renderTaskNotificationXml, taskNotificationDedupKey, SystemInjectionQueue, } from "./core/task-notification.js";
|
|
77
77
|
export { TaskRegistry, defaultTaskRegistry, createTaskOutputTool, createTaskStopTool, MONITOR_BATCH_WINDOW_MS, MONITOR_DEFAULT_TIMEOUT_MS, MONITOR_MAX_TIMEOUT_MS, MONITOR_MAX_BATCHES_PER_MINUTE, canAccessWorkflowRun, DURABLE_AGENT_HANDLE_RE, } from "./core/task-registry.js";
|
|
78
78
|
export { InMemoryMailboxStore } from "./core/mailbox-store.js";
|
|
@@ -5,9 +5,8 @@ import { combinePolicies } from "../core/tool-policy.js";
|
|
|
5
5
|
import { delimitUntrusted } from "../core/untrusted-text.js";
|
|
6
6
|
import { isDurablePause } from "../agents/suspend-guard.js";
|
|
7
7
|
import { isAbsolutePathForm, writeTargetPath } from "../tools/fs/safety.js";
|
|
8
|
-
import { canonicalToolName } from "../core/tool-name-aliases.js";
|
|
9
8
|
import { captureBaseline, resolveFrozenPaths, restoreFrozenPaths, runOracle, snapshotFrozenPaths, specError, } from "../core/spec-contract.js";
|
|
10
|
-
const WRITE_TOOLS = new Set(["Write", "Edit", "
|
|
9
|
+
const WRITE_TOOLS = new Set(["Write", "Edit", "NotebookEdit"]);
|
|
11
10
|
const CASE_INSENSITIVE_FS = process.platform === "darwin" || process.platform === "win32";
|
|
12
11
|
const pathKey = (p) => {
|
|
13
12
|
let n = p.replace(/\\/g, "/");
|
|
@@ -19,7 +18,7 @@ function frozenDenyPolicy(rootDir, frozenResolved) {
|
|
|
19
18
|
const frozen = new Set(frozenResolved.map(pathKey));
|
|
20
19
|
return {
|
|
21
20
|
check(req) {
|
|
22
|
-
const toolName =
|
|
21
|
+
const toolName = req.toolName;
|
|
23
22
|
if (!WRITE_TOOLS.has(toolName))
|
|
24
23
|
return { action: "allow" };
|
|
25
24
|
const args = req.args;
|
|
@@ -175,7 +175,6 @@ export async function createRunWorkflowTool(d) {
|
|
|
175
175
|
const structuredError = (message) => errorResult(JSON.stringify({ error: message }));
|
|
176
176
|
return defineTool({
|
|
177
177
|
name: RUN_WORKFLOW_TOOL_NAME,
|
|
178
|
-
aliases: ["RunWorkflow", "run_workflow"],
|
|
179
178
|
contract: { contractId: "core.workflow@1", implementationRevision: "1" },
|
|
180
179
|
approvalPreview: (raw) => {
|
|
181
180
|
const a = (raw ?? {});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { tightenTaskSpec } from "../core/tighten-task-spec.js";
|
|
2
|
+
import { sanitizeUntrustedText } from "../core/untrusted-text.js";
|
|
2
3
|
import { WorkflowScriptError } from "./workflow-meta.js";
|
|
3
4
|
export class WorkflowModelNotAllowedError extends Error {
|
|
4
5
|
modelName;
|
|
@@ -81,7 +82,7 @@ function pickWhitelist(scriptSpec) {
|
|
|
81
82
|
if (s.systemPrompt !== undefined) {
|
|
82
83
|
if (typeof s.systemPrompt !== "string")
|
|
83
84
|
throw new WorkflowScriptError("agent(spec): `systemPrompt` must be a string");
|
|
84
|
-
safe.systemPrompt = s.systemPrompt
|
|
85
|
+
safe.systemPrompt = `[workflow-script-authored persona — task guidance, not engine authority]\n${sanitizeUntrustedText(s.systemPrompt)}`;
|
|
85
86
|
}
|
|
86
87
|
if (s.images !== undefined) {
|
|
87
88
|
if (!Array.isArray(s.images))
|
|
@@ -89,6 +89,7 @@ export interface RunWorkflowOptions {
|
|
|
89
89
|
maxLogChars?: number;
|
|
90
90
|
maxResultChars?: number;
|
|
91
91
|
onEvent?: (e: WorkflowEvent) => void;
|
|
92
|
+
onNotifyError?: (failure: import("../core/safe-notify.js").SafeNotifyFailure) => void;
|
|
92
93
|
now?: () => number;
|
|
93
94
|
journalStore?: WorkflowJournalStore;
|
|
94
95
|
resumeFromRunId?: string;
|
|
@@ -321,7 +321,7 @@ export function startWorkflow(runner, fn, opts = {}, internals) {
|
|
|
321
321
|
const workflowSignal = signalSources.length === 1 ? signalSources[0] : AbortSignal.any(signalSources);
|
|
322
322
|
let timeoutTimer;
|
|
323
323
|
let storeRev = 0;
|
|
324
|
-
const notifier = createSafeNotifier();
|
|
324
|
+
const notifier = createSafeNotifier(opts.onNotifyError !== undefined ? { onError: opts.onNotifyError } : undefined);
|
|
325
325
|
const emit = (e) => {
|
|
326
326
|
publishWorkflowEvent(runId, e);
|
|
327
327
|
notifier.notify(() => opts.onEvent?.(e), "workflow.onEvent");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CYBER_RISK, EXECUTION_ENVIRONMENT, URL_SAFETY, SUMMARIZE_TOOL_RESULTS, WORKTREE_NOTICE, SUBAGENT_CONSENT_NOTICE, SUBAGENT_DELIVERY_NOTES, harnessHeadLines, } from "../../prompts/default.js";
|
|
2
2
|
import { GOAL_COMPLETION_GUIDANCE, ORCHESTRATION_AWARENESS, ORCHESTRATION_GUIDANCE, ORCHESTRATION_GUIDANCE_DEFERRED, SUPERVISOR_PROMPT, } from "../../prompts/supervisor.js";
|
|
3
3
|
import { TEAMMATE_COMMUNICATION_ADDENDUM } from "../../prompts/coordinator.js";
|
|
4
|
-
import { SIMPLE_ACTION_CAUTION, SIMPLE_ACT_DONT_REDERIVE, SIMPLE_AUTONOMY_FABLE, SIMPLE_COMMUNICATING_FABLE, SIMPLE_CORRECTIONS_FABLE, SIMPLE_DELIVERING_WORK_FABLE, SIMPLE_COMMUNICATING_LEAN, SIMPLE_CONTEXT_MANAGEMENT,
|
|
4
|
+
import { SIMPLE_ACTION_CAUTION, SIMPLE_ACT_DONT_REDERIVE, SIMPLE_AUTONOMY_FABLE, SIMPLE_COMMUNICATING_FABLE, SIMPLE_CORRECTIONS_FABLE, SIMPLE_DELIVERING_WORK_FABLE, SIMPLE_COMMUNICATING_LEAN, SIMPLE_CONTEXT_MANAGEMENT, SIMPLE_PRONOUNS, SIMPLE_TOOL_PARAM_JSON, SEMA_VERIFY_FRESH, SEMA_EVIDENCE_AUDIT, } from "../../prompts/simple-sections.js";
|
|
5
5
|
function harnessHeadText(inputs) {
|
|
6
6
|
return harnessHeadLines(inputs.facts);
|
|
7
7
|
}
|
|
@@ -47,9 +47,7 @@ export const SEMA_DEFAULT_PACK = {
|
|
|
47
47
|
{ id: "core/simple.communicating", slot: "harness", rank: 250, ...CORE, admit: (i) => i.facts.promptProfile !== "classic", content: (i) => (i.facts.fableMitigations === true ? SIMPLE_COMMUNICATING_FABLE : SIMPLE_COMMUNICATING_LEAN), legacyBlockId: "harness.context" },
|
|
48
48
|
{ id: "core/simple.pronouns", slot: "harness", rank: 252, ...CORE, admit: (i) => i.facts.promptProfile !== "classic", content: () => SIMPLE_PRONOUNS, legacyBlockId: "harness.context" },
|
|
49
49
|
{ id: "core/simple.action-caution", slot: "harness", rank: 254, ...CORE, admit: (i) => i.facts.promptProfile !== "classic", content: () => SIMPLE_ACTION_CAUTION, legacyBlockId: "harness.context" },
|
|
50
|
-
{ id: "core/simple.task-continuity", slot: "harness", rank: 256, ...CORE, admit: (i) => i.facts.promptProfile !== "classic", content: () => SIMPLE_TASK_CONTINUITY, legacyBlockId: "harness.context" },
|
|
51
50
|
{ id: "core/simple.tool-param-json", slot: "harness", rank: 258, ...CORE, admit: (i) => i.facts.promptProfile !== "classic", content: () => SIMPLE_TOOL_PARAM_JSON, legacyBlockId: "harness.context" },
|
|
52
|
-
{ id: "core/simple.investigate-first", slot: "harness", rank: 260, ...CORE, admit: (i) => i.facts.promptProfile !== "classic", content: () => SIMPLE_INVESTIGATE_FIRST, legacyBlockId: "harness.context" },
|
|
53
51
|
{ id: "core/simple.context-management", slot: "harness", rank: 262, ...CORE, admit: (i) => i.facts.promptProfile !== "classic" && i.facts.withinTaskCompactionEnabled, content: () => SIMPLE_CONTEXT_MANAGEMENT, legacyBlockId: "harness.context" },
|
|
54
52
|
{ id: "core/simple.act-dont-rederive", slot: "harness", rank: 264, ...CORE, admit: (i) => i.facts.promptProfile !== "classic", content: () => SIMPLE_ACT_DONT_REDERIVE, legacyBlockId: "harness.context" },
|
|
55
53
|
{ id: "core/simple.delivering-work", slot: "harness", rank: 265, ...CORE, admit: (i) => i.facts.promptProfile !== "classic" && i.facts.fableMitigations === true, content: () => SIMPLE_DELIVERING_WORK_FABLE, legacyBlockId: "harness.context" },
|
package/dist/prompts/default.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { inlineUntrusted, sanitizeUntrustedText } from "../core/untrusted-text.js";
|
|
2
2
|
import { GOAL_COMPLETION_GUIDANCE, ORCHESTRATION_AWARENESS, ORCHESTRATION_GUIDANCE, ORCHESTRATION_GUIDANCE_DEFERRED, SUPERVISOR_PROMPT } from "./supervisor.js";
|
|
3
|
-
import { SIMPLE_ACTION_CAUTION, SIMPLE_ACT_DONT_REDERIVE, SIMPLE_AUTONOMY_FABLE, SIMPLE_COMMUNICATING_FABLE, SIMPLE_COMMUNICATING_LEAN, SIMPLE_CONTEXT_MANAGEMENT, SIMPLE_CORRECTIONS_FABLE, SIMPLE_DELIVERING_WORK_FABLE,
|
|
3
|
+
import { SIMPLE_ACTION_CAUTION, SIMPLE_ACT_DONT_REDERIVE, SIMPLE_AUTONOMY_FABLE, SIMPLE_COMMUNICATING_FABLE, SIMPLE_COMMUNICATING_LEAN, SIMPLE_CONTEXT_MANAGEMENT, SIMPLE_CORRECTIONS_FABLE, SIMPLE_DELIVERING_WORK_FABLE, SIMPLE_PRONOUNS, SIMPLE_TOOL_PARAM_JSON, SEMA_VERIFY_FRESH, SEMA_EVIDENCE_AUDIT, } from "./simple-sections.js";
|
|
4
4
|
export const OUTPUT_EFFICIENCY = "If you can say it in one sentence, don't use three. Go straight to the point, don't go in circles, " +
|
|
5
5
|
"don't overdo it. (This does not apply to code or tool calls.)";
|
|
6
6
|
export const DEFAULT_SYSTEM_PROMPT = `You are a capable AI agent that acts through tools.
|
|
@@ -153,9 +153,7 @@ export function harnessContext(ctx) {
|
|
|
153
153
|
blocks.push(ctx.fableMitigations === true ? SIMPLE_COMMUNICATING_FABLE : SIMPLE_COMMUNICATING_LEAN);
|
|
154
154
|
blocks.push(SIMPLE_PRONOUNS);
|
|
155
155
|
blocks.push(SIMPLE_ACTION_CAUTION);
|
|
156
|
-
blocks.push(SIMPLE_TASK_CONTINUITY);
|
|
157
156
|
blocks.push(SIMPLE_TOOL_PARAM_JSON);
|
|
158
|
-
blocks.push(SIMPLE_INVESTIGATE_FIRST);
|
|
159
157
|
if (ctx.withinTaskCompactionEnabled)
|
|
160
158
|
blocks.push(SIMPLE_CONTEXT_MANAGEMENT);
|
|
161
159
|
blocks.push(SIMPLE_ACT_DONT_REDERIVE);
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
export declare const SIMPLE_COMMUNICATING_FABLE = "# Communicating with the user\n\nYour text output is what the user reads; they usually can't see your thinking or the raw tool results. Write it for a teammate who stepped away and is catching up, not for a log file: they don't know the codenames or shorthand you created along the way, and they didn't watch your process unfold. Before your first tool call, say in a sentence what you're about to do; while working, give brief updates when you find something load-bearing or change direction.\n\nText you write between tool calls may not be shown to the user. Everything the user needs from this turn \u2014 answers, summaries, findings, conclusions, deliverables \u2014 must be in the final text message of your turn, with no tool calls after it. Keep text between tool calls to brief status notes. If something important appeared only mid-turn or in your thinking, restate it in that final message.\n\nLead with the outcome. Your first sentence after finishing should answer \"what happened\" or \"what did you find\" \u2014 the thing the user would ask for if they said \"just give me the TLDR.\" Supporting detail and reasoning come after, for readers who want them.\n\nBeing readable and being concise are different things, and readable matters more. If the user has to reread your summary or ask you to explain, any time saved by brevity is gone. The way to keep output short is to be selective about what you include (drop details that don't change what the reader would do next), not to compress the writing into fragments, abbreviations, arrow chains like `A \u2192 B \u2192 fails`, or jargon. What you do include, write in complete sentences with the technical terms spelled out. Don't make the reader cross-reference labels or numbering you invented earlier; say what you mean in place.\n\nMatch the response to the question: a simple question gets a direct answer in prose, not headers and sections. Use tables only for short enumerable facts, with explanations in the surrounding prose rather than the cells. Calibrate to the user \u2014 a bit tighter for an expert, more explanatory for someone newer.\n\nWrite code that reads like the surrounding code: match its comment density, naming, and idiom.\nOnly write a code comment to state a constraint the code itself can't show \u2014 never to say where it came from, what the next line does, or why your change is correct; that's you talking to the reviewer, not the next reader, and it's noise the moment the PR merges.";
|
|
2
2
|
export declare const SIMPLE_COMMUNICATING_LEAN = "Write code that reads like the surrounding code: match its comment density, naming, and idiom.";
|
|
3
3
|
export declare const SIMPLE_ACTION_CAUTION = "For actions that are hard to reverse or outward-facing, confirm first unless durably authorized or explicitly told to proceed without asking; approval in one context doesn't extend to the next. Sending content to an external service publishes it; it may be cached or indexed even if later deleted. Before deleting or overwriting, look at the target \u2014 if what you find contradicts how it was described, or you didn't create it, surface that instead of proceeding. Report outcomes faithfully: if tests fail, say so with the output; if a step was skipped, say that; when something is done and verified, state it plainly without hedging.";
|
|
4
|
-
export declare const SIMPLE_TASK_CONTINUITY = "When a task has been agreed, the approval covers it end to end \u2014 in-scope steps don't need re-confirmation (irreversible or shared-system actions still do). Announcing a step without the tool call in the same turn hands control back with the work still pending; if the next step is decided, run it. Hand back only when done, waiting on something external, or the next step needs the user's decision. If the user asks something mid-task, answer and continue.";
|
|
5
4
|
export declare const SIMPLE_INVESTIGATE_FIRST = "Asking the user a clarifying question has a cost: it interrupts them, and often they could have answered it themselves with a grep. Before asking, spend up to a minute on read-only investigation (grep the codebase, check docs, search memory) so your question is specific. \"I found tunnels X and Y in the config \u2014 which one?\" beats \"what tunnel?\"";
|
|
6
5
|
export declare const SIMPLE_CONTEXT_MANAGEMENT = "# Context management\nWhen the conversation grows long, some or all of the current context is summarized; the summary, along with any remaining unsummarized context, is provided in the next context window so work can continue \u2014 you don't need to wrap up early or hand off mid-task.";
|
|
7
6
|
export declare const SIMPLE_ACT_DONT_REDERIVE = "When you have enough information to act, act. Do not re-derive facts already established in the conversation, re-litigate a decision the user has already made, or narrate options you will not pursue. If you are weighing a choice, give a recommendation, not an exhaustive survey";
|
|
@@ -14,7 +14,6 @@ Write code that reads like the surrounding code: match its comment density, nami
|
|
|
14
14
|
Only write a code comment to state a constraint the code itself can't show — never to say where it came from, what the next line does, or why your change is correct; that's you talking to the reviewer, not the next reader, and it's noise the moment the PR merges.`;
|
|
15
15
|
export const SIMPLE_COMMUNICATING_LEAN = "Write code that reads like the surrounding code: match its comment density, naming, and idiom.";
|
|
16
16
|
export const SIMPLE_ACTION_CAUTION = "For actions that are hard to reverse or outward-facing, confirm first unless durably authorized or explicitly told to proceed without asking; approval in one context doesn't extend to the next. Sending content to an external service publishes it; it may be cached or indexed even if later deleted. Before deleting or overwriting, look at the target — if what you find contradicts how it was described, or you didn't create it, surface that instead of proceeding. Report outcomes faithfully: if tests fail, say so with the output; if a step was skipped, say that; when something is done and verified, state it plainly without hedging.";
|
|
17
|
-
export const SIMPLE_TASK_CONTINUITY = "When a task has been agreed, the approval covers it end to end — in-scope steps don't need re-confirmation (irreversible or shared-system actions still do). Announcing a step without the tool call in the same turn hands control back with the work still pending; if the next step is decided, run it. Hand back only when done, waiting on something external, or the next step needs the user's decision. If the user asks something mid-task, answer and continue.";
|
|
18
17
|
export const SIMPLE_INVESTIGATE_FIRST = 'Asking the user a clarifying question has a cost: it interrupts them, and often they could have answered it themselves with a grep. Before asking, spend up to a minute on read-only investigation (grep the codebase, check docs, search memory) so your question is specific. "I found tunnels X and Y in the config — which one?" beats "what tunnel?"';
|
|
19
18
|
export const SIMPLE_CONTEXT_MANAGEMENT = `# Context management
|
|
20
19
|
When the conversation grows long, some or all of the current context is summarized; the summary, along with any remaining unsummarized context, is provided in the next context window so work can continue — you don't need to wrap up early or hand off mid-task.`;
|
package/dist/tools/fs/fs-bash.js
CHANGED
|
@@ -2,7 +2,7 @@ import { Type } from "typebox";
|
|
|
2
2
|
import { defineTool, errorResult } from "../../core/tools.js";
|
|
3
3
|
import { defaultTaskRegistry } from "../../core/task-registry.js";
|
|
4
4
|
import { accountDroppedBytes, spoolDropNote } from "../../core/task-registry-shared.js";
|
|
5
|
-
import { TASK_OUTPUT_TOOL_NAME, TASK_STOP_TOOL_NAME,
|
|
5
|
+
import { TASK_OUTPUT_TOOL_NAME, TASK_STOP_TOOL_NAME, TASK_OUTPUT_CONTRACT, TASK_STOP_CONTRACT, TASK_OUTPUT_MISSING_ID_MESSAGE, TASK_STOP_MISSING_ID_MESSAGE, TASK_STOP_PARAMS, resolveTaskIdArg, ENV_DIRECT_TASK_TOOL_CAPS, composeTaskOutputDescription, composeTaskOutputParams, composeTaskStopDescription, } from "../../core/task-tool-shape.js";
|
|
6
6
|
import { hasBackgroundShell } from "../../core/background-shell.js";
|
|
7
7
|
import { delimitUntrusted } from "../../core/untrusted-text.js";
|
|
8
8
|
import { MCP_IMAGE_MAX_BASE64 } from "../../core/mcp.js";
|
|
@@ -618,7 +618,7 @@ export function createBashTool(env, rootCanonical, coAuthor = false, cwdRef = {
|
|
|
618
618
|
budgetNote +
|
|
619
619
|
lifetimeNote;
|
|
620
620
|
}
|
|
621
|
-
return (`Started in background; task_id=${r.value.shellId}.
|
|
621
|
+
return (`Started in background; task_id=${r.value.shellId}. ` +
|
|
622
622
|
`Use TaskOutput("${r.value.shellId}") to read output (poll until status is no longer "running"); ` +
|
|
623
623
|
`TaskStop("${r.value.shellId}") to stop. No '&' needed.` +
|
|
624
624
|
budgetNote +
|
|
@@ -1003,14 +1003,13 @@ export function createBashReadonlyTool(env, rootCanonical, allow, execClamp, opt
|
|
|
1003
1003
|
export function createEnvTaskOutputTool(env) {
|
|
1004
1004
|
return defineTool({
|
|
1005
1005
|
name: TASK_OUTPUT_TOOL_NAME,
|
|
1006
|
-
aliases: [...TASK_OUTPUT_ALIASES],
|
|
1007
1006
|
contract: TASK_OUTPUT_CONTRACT,
|
|
1008
1007
|
description: composeTaskOutputDescription(ENV_DIRECT_TASK_TOOL_CAPS),
|
|
1009
1008
|
parameters: composeTaskOutputParams(ENV_DIRECT_TASK_TOOL_CAPS),
|
|
1010
1009
|
effect: "read",
|
|
1011
1010
|
execute: async (args) => {
|
|
1012
|
-
const { task_id,
|
|
1013
|
-
const id = resolveTaskIdArg(task_id
|
|
1011
|
+
const { task_id, filter } = args;
|
|
1012
|
+
const id = resolveTaskIdArg(task_id);
|
|
1014
1013
|
if (!id)
|
|
1015
1014
|
return errorResult(TASK_OUTPUT_MISSING_ID_MESSAGE);
|
|
1016
1015
|
if (!hasBackgroundShell(env)) {
|
|
@@ -1042,14 +1041,13 @@ export function createEnvTaskOutputTool(env) {
|
|
|
1042
1041
|
export function createEnvTaskStopTool(env, registry = defaultTaskRegistry) {
|
|
1043
1042
|
return defineTool({
|
|
1044
1043
|
name: TASK_STOP_TOOL_NAME,
|
|
1045
|
-
aliases: [...TASK_STOP_ALIASES],
|
|
1046
1044
|
contract: TASK_STOP_CONTRACT,
|
|
1047
1045
|
description: composeTaskStopDescription(ENV_DIRECT_TASK_TOOL_CAPS),
|
|
1048
1046
|
parameters: TASK_STOP_PARAMS,
|
|
1049
1047
|
effect: "write",
|
|
1050
1048
|
execute: async (args) => {
|
|
1051
|
-
const { task_id, shell_id
|
|
1052
|
-
const id = resolveTaskIdArg(task_id, shell_id
|
|
1049
|
+
const { task_id, shell_id } = args;
|
|
1050
|
+
const id = resolveTaskIdArg(task_id, shell_id);
|
|
1053
1051
|
if (!id)
|
|
1054
1052
|
return errorResult(TASK_STOP_MISSING_ID_MESSAGE);
|
|
1055
1053
|
if (!hasBackgroundShell(env)) {
|
|
@@ -28,7 +28,6 @@ export function createEditFileTool(env, state, rootCanonical, cwdRef, additional
|
|
|
28
28
|
"- `old_string` must match the file exactly, including indentation, and be unique — the edit fails otherwise. Strip the Read line prefix (line number + tab) before matching.\n" +
|
|
29
29
|
"- `replace_all: true` replaces every occurrence instead.\n" +
|
|
30
30
|
"- The edit also fails if the file changed on disk since you read it — Read it again first.",
|
|
31
|
-
aliases: ["MultiEdit"],
|
|
32
31
|
parameters: Type.Object({
|
|
33
32
|
...FILE_PATH_PARAMS,
|
|
34
33
|
old_string: Type.Optional(Type.String({ description: "The text to replace" })),
|