feat(coding-agent): added coding-agent approval types and mode options

- Added `ToolTier`, `ToolApproval`, and `ToolApprovalDecision` types and exported approval APIs.
- Updated approval-mode options from `auto|prompt|custom` to `always-ask|write|yolo` and defaulted mode to `yolo`.
- Changed approval resolution to apply per-tool decisions first, then mode-tier limits, with legacy-mode migration.
- Assigned read/write/exec `approval` and approval-detail prompts across built-in, custom, extension, and MCP tools.
This commit is contained in:
can1357
2026-05-26 21:52:16 +02:00
parent be5837406b
commit e4a16451ec
49 changed files with 797 additions and 1011 deletions
+32
View File
@@ -5,6 +5,7 @@ import type {
AgentToolResult,
AgentToolUpdateCallback,
RenderResultOptions,
ToolApprovalDecision,
} from "@oh-my-pi/pi-agent-core";
import { type Component, Text } from "@oh-my-pi/pi-tui";
import { isEnoent, prompt } from "@oh-my-pi/pi-utils";
@@ -37,6 +38,7 @@ import debugDescription from "../prompts/tools/debug.md" with { type: "text" };
import { renderStatusLine } from "../tui";
import { CachedOutputBlock } from "../tui/output-block";
import type { ToolSession } from ".";
import { truncateForPrompt } from "./approval";
import type { OutputMeta } from "./output-meta";
import { formatPathRelativeToCwd, resolveToCwd } from "./path-utils";
import {
@@ -51,6 +53,23 @@ import { ToolError } from "./tool-errors";
import { toolResult } from "./tool-result";
import { clampTimeout } from "./tool-timeouts";
/**
* DAP debug actions that only read program state (no mutation, no execution).
* Execution-side actions (`launch`, `attach`, `continue`, `step_*`, `pause`,
* `evaluate`, breakpoint mutations, memory writes) are exec-tier.
*/
export const DEBUG_READONLY_ACTIONS: ReadonlySet<string> = new Set([
"output",
"threads",
"stack_trace",
"scopes",
"variables",
"disassemble",
"read_memory",
"loaded_sources",
"modules",
"sessions",
]);
const debugSchema = z.object({
action: z.enum([
"launch",
@@ -609,6 +628,19 @@ export const debugToolRenderer = {
export class DebugTool implements AgentTool<typeof debugSchema, DebugToolDetails> {
readonly name = "debug";
readonly approval = (args: unknown): ToolApprovalDecision => {
const rawAction = (args as Partial<DebugParams>).action;
const action = typeof rawAction === "string" ? rawAction.toLowerCase() : "";
return DEBUG_READONLY_ACTIONS.has(action) ? "read" : "exec";
};
readonly formatApprovalDetails = (args: unknown): string[] => {
const params = args as Partial<DebugParams>;
const lines = [`Action: ${typeof params.action === "string" ? params.action : "(missing)"}`];
if (typeof params.program === "string" && params.program.length > 0) {
lines.push(`Program: ${truncateForPrompt(params.program)}`);
}
return lines;
};
readonly label = "Debug";
readonly summary = "Debug a running process with DAP (debugger adapter protocol)";
readonly description: string;