@falkenslab/agent-kit 0.30.0 → 0.30.1
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.
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { askForChoice } from "./humanInput.js";
|
|
2
2
|
import { readLock, setExtensionConfirm } from "../externalExtensions.js";
|
|
3
3
|
import { t } from "../messages/index.js";
|
|
4
|
+
/** How much of a labelled tool's parameters its panel shows, as one line (#84). */
|
|
5
|
+
const MAX_PARAMETERS = 300;
|
|
4
6
|
/** The kit's approval tool: asking it ends a batch, and its yes starts one. */
|
|
5
7
|
const APPROVAL_TOOL = "mcp__approvals__request_human_approval";
|
|
6
8
|
/**
|
|
@@ -70,9 +72,13 @@ export function createGuidedGate(options) {
|
|
|
70
72
|
// For one that always asks, only what covers this call, or makes it stricter (#78).
|
|
71
73
|
const choices = alwaysAsks ? [answers.yes, answers.no, answers.never] : [answers.yes, answers.session, answers.always, answers.no, answers.never];
|
|
72
74
|
const label = options.labels?.()[full]?.label((pre.tool_input ?? {}));
|
|
75
|
+
// With a label saying what it does, its parameters in one line, cut short (#84): a rubric or a
|
|
76
|
+
// page's HTML as indented JSON filled the panel. Without one, the parameters are all it shows.
|
|
77
|
+
const compact = JSON.stringify(pre.tool_input ?? {});
|
|
78
|
+
const parameters = label ? (compact.length > MAX_PARAMETERS ? `${compact.slice(0, MAX_PARAMETERS)}…` : compact) : JSON.stringify(pre.tool_input, null, 2);
|
|
73
79
|
const answer = await askForChoice(options.runDir, {
|
|
74
80
|
title: t().guidedTitle(extension.name),
|
|
75
|
-
lines: [...(label ? [label] : []), t().toolLine(full), t().parametersLine(
|
|
81
|
+
lines: [...(label ? [label] : []), t().toolLine(full), t().parametersLine(parameters)],
|
|
76
82
|
}, choices);
|
|
77
83
|
const picked = answer.chosen[0];
|
|
78
84
|
if (picked === answers.yes || picked === answers.session || picked === answers.always) {
|
|
@@ -6,6 +6,21 @@ import { type SessionModel } from "./sessionModel.js";
|
|
|
6
6
|
import type { InkInteraction } from "./inkInteraction.js";
|
|
7
7
|
/** Replaces the default preview (title and lines) of an approval panel; the choices stay. */
|
|
8
8
|
export type RenderApproval = (prompt: ApprovalPrompt) => ReactNode;
|
|
9
|
+
/**
|
|
10
|
+
* The rows a checkpoint panel needs besides its preview, by its kind (#84): a choice has its
|
|
11
|
+
* options, "Other" and a line of keys, so the guided gate's five answers took four rows more than a
|
|
12
|
+
* decision's, and pushed them below the screen under a tool's long parameters. `reservedRows` is
|
|
13
|
+
* what the screen keeps for a decision's panel; the difference in frame is added to it.
|
|
14
|
+
*/
|
|
15
|
+
export declare function panelReservedRows(checkpoint: {
|
|
16
|
+
kind: string;
|
|
17
|
+
prompt: {
|
|
18
|
+
question?: string;
|
|
19
|
+
};
|
|
20
|
+
choice?: {
|
|
21
|
+
options: readonly string[];
|
|
22
|
+
};
|
|
23
|
+
}, reservedRows?: number): number;
|
|
9
24
|
/**
|
|
10
25
|
* The preview's lines, capped so the whole live area stays shorter than the terminal: Ink
|
|
11
26
|
* clears the entire screen (scrollback included) to redraw anything taller, and a step-gate
|
|
@@ -28,6 +28,26 @@ const DECISION_KEYS = { "1": "y", "2": "n", "3": "q", y: "y", n: "n", q: "q" };
|
|
|
28
28
|
const PANEL_RESERVED_ROWS = 12;
|
|
29
29
|
/** The panel's border and horizontal padding, on both sides. */
|
|
30
30
|
const PANEL_FRAME_COLUMNS = 4;
|
|
31
|
+
/** The rows `PANEL_RESERVED_ROWS` counts for the panel's own frame: a decision's (borders, title, a gap, "Proceed?", its three options). */
|
|
32
|
+
const DECISION_FRAME_ROWS = 8;
|
|
33
|
+
/**
|
|
34
|
+
* The rows a checkpoint panel needs besides its preview, by its kind (#84): a choice has its
|
|
35
|
+
* options, "Other" and a line of keys, so the guided gate's five answers took four rows more than a
|
|
36
|
+
* decision's, and pushed them below the screen under a tool's long parameters. `reservedRows` is
|
|
37
|
+
* what the screen keeps for a decision's panel; the difference in frame is added to it.
|
|
38
|
+
*/
|
|
39
|
+
export function panelReservedRows(checkpoint, reservedRows = PANEL_RESERVED_ROWS) {
|
|
40
|
+
const question = checkpoint.prompt.question ? 1 : 0;
|
|
41
|
+
// Borders and the title (3), then each kind's own rows.
|
|
42
|
+
const frame = checkpoint.kind === "decision"
|
|
43
|
+
? DECISION_FRAME_ROWS
|
|
44
|
+
: checkpoint.kind === "choice"
|
|
45
|
+
? 3 + question + 1 + (checkpoint.choice?.options.length ?? 0) + 1 + 1
|
|
46
|
+
: checkpoint.kind === "text"
|
|
47
|
+
? 3 + question + 1 + 1 + 1
|
|
48
|
+
: 3 + question + 1 + 1;
|
|
49
|
+
return reservedRows - DECISION_FRAME_ROWS + frame;
|
|
50
|
+
}
|
|
31
51
|
/**
|
|
32
52
|
* The preview's lines, capped so the whole live area stays shorter than the terminal: Ink
|
|
33
53
|
* clears the entire screen (scrollback included) to redraw anything taller, and a step-gate
|
|
@@ -62,7 +82,7 @@ function CheckpointPanel({ checkpoint, renderApproval, reservedRows, width, }) {
|
|
|
62
82
|
});
|
|
63
83
|
const { prompt } = checkpoint;
|
|
64
84
|
const { stdout } = useStdout();
|
|
65
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: inkColor("accent"), paddingX: 1, children: [renderApproval ? (renderApproval(prompt)) : (_jsxs(_Fragment, { children: [_jsx(Text, { bold: true, children: prompt.title }), previewLines(prompt.markdown ? renderMarkdown(prompt.lines.join("\n"), width - PANEL_FRAME_COLUMNS) : prompt.lines, stdout.rows, reservedRows, width - PANEL_FRAME_COLUMNS).map((line, index) => (_jsx(Text, { children: line }, index))), !decision && prompt.question ? _jsx(Text, { dimColor: true, children: prompt.question }) : null] })), decision ? (_jsx(Box, { marginTop: 1, children: _jsx(Text, { children: t().proceed }) })) : null, choice && checkpoint.choice ? (_jsx(ChoiceInput, { choice: checkpoint.choice, onAnswer: (value) => checkpoint.answer(value) }, checkpoint.id)) : text ? (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { children: "> " }), _jsx(TextInput, { placeholder: t().textAnswerHint, onSubmit: (value) => checkpoint.answer(value.trim()) }, checkpoint.id)] }), _jsx(Text, { dimColor: true, children: t().textAnswerKeys })] })) : (_jsx(Box, { marginTop: decision ? 0 : 1, children: _jsx(Select, { options: decision ? decisionOptions() : manualOptions(), onChange: (value) => checkpoint.answer(decision ? value : "") }, checkpoint.id) }))] }));
|
|
85
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: inkColor("accent"), paddingX: 1, children: [renderApproval ? (renderApproval(prompt)) : (_jsxs(_Fragment, { children: [_jsx(Text, { bold: true, children: prompt.title }), previewLines(prompt.markdown ? renderMarkdown(prompt.lines.join("\n"), width - PANEL_FRAME_COLUMNS) : prompt.lines, stdout.rows, panelReservedRows(checkpoint, reservedRows), width - PANEL_FRAME_COLUMNS).map((line, index) => (_jsx(Text, { children: line }, index))), !decision && prompt.question ? _jsx(Text, { dimColor: true, children: prompt.question }) : null] })), decision ? (_jsx(Box, { marginTop: 1, children: _jsx(Text, { children: t().proceed }) })) : null, choice && checkpoint.choice ? (_jsx(ChoiceInput, { choice: checkpoint.choice, onAnswer: (value) => checkpoint.answer(value) }, checkpoint.id)) : text ? (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { children: "> " }), _jsx(TextInput, { placeholder: t().textAnswerHint, onSubmit: (value) => checkpoint.answer(value.trim()) }, checkpoint.id)] }), _jsx(Text, { dimColor: true, children: t().textAnswerKeys })] })) : (_jsx(Box, { marginTop: decision ? 0 : 1, children: _jsx(Select, { options: decision ? decisionOptions() : manualOptions(), onChange: (value) => checkpoint.answer(decision ? value : "") }, checkpoint.id) }))] }));
|
|
66
86
|
}
|
|
67
87
|
/**
|
|
68
88
|
* A choice's options (one with Select, several with MultiSelect), plus "Other" to type an
|