@code-yeongyu/senpi 2026.9.23-4 → 2026.9.23-5
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 +18 -1
- package/dist/bundle/chunks/{app-server-command-QRBQLEXY.js → app-server-command-BGT65PGC.js} +1 -1
- package/dist/bundle/chunks/chunk-LTIMMSDM.js +8 -0
- package/dist/bundle/chunks/{chunk-N46LNXHU.js → chunk-RRSND33J.js} +19 -15
- package/dist/bundle/chunks/{cli-main-ROBDBYAB.js → cli-main-W55CWPEI.js} +1 -1
- package/dist/bundle/chunks/{interactive-mode-SLPAGRHH.js → interactive-mode-EDJZ4CSY.js} +1 -1
- package/dist/bundle/chunks/{multi-session-host-3PACMEHC.js → multi-session-host-GFSDQQUJ.js} +1 -1
- package/dist/bundle/chunks/{package-manager-cli-6UIUSRQO.js → package-manager-cli-J7244EJE.js} +1 -1
- package/dist/bundle/chunks/{rpc-mode-47EVLL6X.js → rpc-mode-75CRTY24.js} +1 -1
- package/dist/bundle/chunks/session-worker.js +19 -15
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/core/agent-session.d.ts +9 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +14 -1
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/output-format.d.ts +15 -0
- package/dist/core/extensions/builtin/terminal/output-format.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/output-format.js +43 -2
- package/dist/core/extensions/builtin/terminal/output-format.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/bash-output.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/bash-output.js +4 -3
- package/dist/core/extensions/builtin/terminal/tools/bash-output.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/bash.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/bash.js +3 -3
- package/dist/core/extensions/builtin/terminal/tools/bash.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/context.d.ts +7 -4
- package/dist/core/extensions/builtin/terminal/tools/context.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/context.js +5 -0
- package/dist/core/extensions/builtin/terminal/tools/context.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/render.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/render.js +5 -2
- package/dist/core/extensions/builtin/terminal/tools/render.js.map +1 -1
- package/dist/core/tool-call-display-name.d.ts +15 -0
- package/dist/core/tool-call-display-name.d.ts.map +1 -0
- package/dist/core/tool-call-display-name.js +14 -0
- package/dist/core/tool-call-display-name.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +3 -1
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/json-event.d.ts +1 -0
- package/dist/modes/json-event.d.ts.map +1 -1
- package/dist/modes/json-event.js +1 -0
- package/dist/modes/json-event.js.map +1 -1
- package/docs/json.md +4 -1
- package/docs/rpc.md +7 -1
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +12 -0
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +8 -23
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/tool-name-alias.d.ts +8 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/tool-name-alias.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/tool-name-alias.js +27 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/tool-name-alias.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +2 -2
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +7 -7
- package/dist/bundle/chunks/chunk-KBG7BJIL.js +0 -8
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* carriage-return/backspace redraws collapsed — then (b) tail-truncated to the
|
|
10
10
|
* same budget the core bash tool enforces.
|
|
11
11
|
*/
|
|
12
|
+
import type { TextContent } from "@earendil-works/pi-ai";
|
|
12
13
|
import { type TruncationResult } from "../../../tools/truncate.ts";
|
|
13
14
|
/** Mirrors the core bash tool budget (`DEFAULT_MAX_LINES` / `DEFAULT_MAX_BYTES`). */
|
|
14
15
|
export declare const TERMINAL_TOOL_MAX_LINES = 2000;
|
|
@@ -16,7 +17,12 @@ export declare const TERMINAL_TOOL_MAX_BYTES: number;
|
|
|
16
17
|
/** Strip escape sequences and collapse carriage-return/backspace redraws. */
|
|
17
18
|
export declare function sanitizeTerminalOutput(raw: string): string;
|
|
18
19
|
export interface FormattedTerminalToolOutput {
|
|
20
|
+
/** Model-facing text: the kept output, then the truncation marker when content was cut. */
|
|
19
21
|
readonly text: string;
|
|
22
|
+
/** The kept output alone, without the marker. */
|
|
23
|
+
readonly body: string;
|
|
24
|
+
/** Truncation marker addressed to the model; UIs never render it. */
|
|
25
|
+
readonly marker?: string;
|
|
20
26
|
readonly truncated: boolean;
|
|
21
27
|
readonly truncation: TruncationResult;
|
|
22
28
|
}
|
|
@@ -25,4 +31,13 @@ export interface FormattedTerminalToolOutput {
|
|
|
25
31
|
* tail (where exit status and errors live) with a marker when content was cut.
|
|
26
32
|
*/
|
|
27
33
|
export declare function formatTerminalToolOutput(raw: string): FormattedTerminalToolOutput;
|
|
34
|
+
/**
|
|
35
|
+
* Split a tool-result text into parts so each notice becomes its own model-only
|
|
36
|
+
* part. Providers join a tool result's text parts with "\n", so every notice
|
|
37
|
+
* must sit on its own line: the newline before it (and after it, when text
|
|
38
|
+
* follows) is taken out of the neighbouring parts and restored by that join.
|
|
39
|
+
* The joined parts are therefore byte-identical to `text`. A notice that is
|
|
40
|
+
* absent or not line-delimited leaves `text` as one visible part.
|
|
41
|
+
*/
|
|
42
|
+
export declare function splitModelOnlyNotices(text: string, notices: ReadonlyArray<string | undefined>): TextContent[];
|
|
28
43
|
//# sourceMappingURL=output-format.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output-format.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/output-format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAc,KAAK,gBAAgB,EAAgB,MAAM,4BAA4B,CAAC;AAE7F,qFAAqF;AACrF,eAAO,MAAM,uBAAuB,OAAO,CAAC;AAC5C,eAAO,MAAM,uBAAuB,QAAY,CAAC;AAsCjD,6EAA6E;AAC7E,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,MAAM,WAAW,2BAA2B;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC;CACtC;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,2BAA2B,CAajF"}
|
|
1
|
+
{"version":3,"file":"output-format.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/output-format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EAAc,KAAK,gBAAgB,EAAgB,MAAM,4BAA4B,CAAC;AAE7F,qFAAqF;AACrF,eAAO,MAAM,uBAAuB,OAAO,CAAC;AAC5C,eAAO,MAAM,uBAAuB,QAAY,CAAC;AAsCjD,6EAA6E;AAC7E,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,MAAM,WAAW,2BAA2B;IAC3C,2FAA2F;IAC3F,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,iDAAiD;IACjD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,qEAAqE;IACrE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC;CACtC;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,2BAA2B,CAajF;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,WAAW,EAAE,CAwB7G"}
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* carriage-return/backspace redraws collapsed — then (b) tail-truncated to the
|
|
10
10
|
* same budget the core bash tool enforces.
|
|
11
11
|
*/
|
|
12
|
+
import { modelOnlyText } from "../../../tools/model-only-text.js";
|
|
12
13
|
import { formatSize, truncateTail } from "../../../tools/truncate.js";
|
|
13
14
|
/** Mirrors the core bash tool budget (`DEFAULT_MAX_LINES` / `DEFAULT_MAX_BYTES`). */
|
|
14
15
|
export const TERMINAL_TOOL_MAX_LINES = 2000;
|
|
@@ -64,11 +65,51 @@ export function formatTerminalToolOutput(raw) {
|
|
|
64
65
|
maxBytes: TERMINAL_TOOL_MAX_BYTES,
|
|
65
66
|
});
|
|
66
67
|
if (!truncation.truncated) {
|
|
67
|
-
return { text: sanitized, truncated: false, truncation };
|
|
68
|
+
return { text: sanitized, body: sanitized, truncated: false, truncation };
|
|
68
69
|
}
|
|
69
70
|
const marker = truncation.lastLinePartial
|
|
70
71
|
? `[Showing last ${formatSize(truncation.outputBytes)} of a single line; earlier output dropped]`
|
|
71
72
|
: `[Showing lines ${truncation.totalLines - truncation.outputLines + 1}-${truncation.totalLines} of ${truncation.totalLines}; earlier output dropped]`;
|
|
72
|
-
return { text: `${truncation.content}\n\n${marker}`, truncated: true, truncation };
|
|
73
|
+
return { text: `${truncation.content}\n\n${marker}`, body: truncation.content, marker, truncated: true, truncation };
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Split a tool-result text into parts so each notice becomes its own model-only
|
|
77
|
+
* part. Providers join a tool result's text parts with "\n", so every notice
|
|
78
|
+
* must sit on its own line: the newline before it (and after it, when text
|
|
79
|
+
* follows) is taken out of the neighbouring parts and restored by that join.
|
|
80
|
+
* The joined parts are therefore byte-identical to `text`. A notice that is
|
|
81
|
+
* absent or not line-delimited leaves `text` as one visible part.
|
|
82
|
+
*/
|
|
83
|
+
export function splitModelOnlyNotices(text, notices) {
|
|
84
|
+
const parts = [];
|
|
85
|
+
let cursor = 0;
|
|
86
|
+
// True when the previous part is a notice whose trailing newline was consumed.
|
|
87
|
+
let afterNotice = false;
|
|
88
|
+
for (const notice of notices) {
|
|
89
|
+
if (notice === undefined || notice.length === 0)
|
|
90
|
+
continue;
|
|
91
|
+
const index = text.indexOf(notice, cursor);
|
|
92
|
+
if (index < 0)
|
|
93
|
+
continue;
|
|
94
|
+
const end = index + notice.length;
|
|
95
|
+
if (end < text.length && text[end] !== "\n")
|
|
96
|
+
continue;
|
|
97
|
+
if (afterNotice && index === cursor) {
|
|
98
|
+
parts.push(modelOnlyText(notice));
|
|
99
|
+
}
|
|
100
|
+
else if (index > cursor && text[index - 1] === "\n") {
|
|
101
|
+
parts.push({ type: "text", text: text.slice(cursor, index - 1) }, modelOnlyText(notice));
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
cursor = end < text.length ? end + 1 : end;
|
|
107
|
+
afterNotice = end < text.length;
|
|
108
|
+
}
|
|
109
|
+
if (parts.length === 0)
|
|
110
|
+
return [{ type: "text", text }];
|
|
111
|
+
if (cursor < text.length || text[text.length - 1] === "\n")
|
|
112
|
+
parts.push({ type: "text", text: text.slice(cursor) });
|
|
113
|
+
return parts;
|
|
73
114
|
}
|
|
74
115
|
//# sourceMappingURL=output-format.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output-format.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/output-format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;
|
|
1
|
+
{"version":3,"file":"output-format.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/terminal/output-format.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Model-facing formatting for PTY terminal output.\n *\n * The PTY bash tools capture a raw terminal stream: escape sequences, and one\n * redraw frame per spinner tick. Returned unbounded (up to the 1 MB session\n * buffer), a single `gh run view --log-failed` injected ~1M chars of ANSI soup\n * into the conversation and forced emergency compactions. Before output\n * reaches the model it is (a) sanitized — escape sequences stripped and\n * carriage-return/backspace redraws collapsed — then (b) tail-truncated to the\n * same budget the core bash tool enforces.\n */\n\nimport type { TextContent } from \"@earendil-works/pi-ai\";\nimport { modelOnlyText } from \"../../../tools/model-only-text.ts\";\nimport { formatSize, type TruncationResult, truncateTail } from \"../../../tools/truncate.ts\";\n\n/** Mirrors the core bash tool budget (`DEFAULT_MAX_LINES` / `DEFAULT_MAX_BYTES`). */\nexport const TERMINAL_TOOL_MAX_LINES = 2000;\nexport const TERMINAL_TOOL_MAX_BYTES = 50 * 1024;\n\n// Order matters: OSC can contain characters that later patterns would eat.\nconst OSC_PATTERN = /\\x1b\\][^\\x07\\x1b]*(?:\\x07|\\x1b\\\\)/g;\nconst CSI_PATTERN = /\\x1b\\[[0-?]*[ -/]*[@-~]/g;\nconst DESIGNATE_AND_SINGLE_PATTERN = /\\x1b(?:[()#%*+][0-9A-Za-z]|[0-9<=>@-Z\\\\-_])/g;\n// `\\x08` (backspace) and `\\r` are excluded: the redraw fold applies their semantics.\nconst C0_CONTROL_PATTERN = /[\\x00-\\x07\\x0b\\x0c\\x0e-\\x1f\\x7f]/g;\n\nfunction stripEscapeSequences(text: string): string {\n\treturn text\n\t\t.replace(OSC_PATTERN, \"\")\n\t\t.replace(CSI_PATTERN, \"\")\n\t\t.replace(DESIGNATE_AND_SINGLE_PATTERN, \"\")\n\t\t.replace(C0_CONTROL_PATTERN, \"\");\n}\n\n/**\n * Fold terminal redraw semantics into a flat line: `\\r` returns the cursor to\n * column 0 so spinner/progress frames overwrite each other, and `\\b` steps the\n * cursor back one cell. Only the final visible state survives.\n */\nfunction collapseRedraws(line: string): string {\n\tconst cells: string[] = [];\n\tlet cursor = 0;\n\tfor (const ch of line) {\n\t\tif (ch === \"\\r\") {\n\t\t\tcursor = 0;\n\t\t} else if (ch === \"\\b\") {\n\t\t\tif (cursor > 0) cursor -= 1;\n\t\t} else {\n\t\t\tcells[cursor] = ch;\n\t\t\tcursor += 1;\n\t\t}\n\t}\n\treturn cells.join(\"\");\n}\n\n/** Strip escape sequences and collapse carriage-return/backspace redraws. */\nexport function sanitizeTerminalOutput(raw: string): string {\n\treturn stripEscapeSequences(raw).replace(/\\r\\n/g, \"\\n\").split(\"\\n\").map(collapseRedraws).join(\"\\n\");\n}\n\nexport interface FormattedTerminalToolOutput {\n\t/** Model-facing text: the kept output, then the truncation marker when content was cut. */\n\treadonly text: string;\n\t/** The kept output alone, without the marker. */\n\treadonly body: string;\n\t/** Truncation marker addressed to the model; UIs never render it. */\n\treadonly marker?: string;\n\treadonly truncated: boolean;\n\treadonly truncation: TruncationResult;\n}\n\n/**\n * Sanitize `raw` PTY output and bound it to the core-bash budget, keeping the\n * tail (where exit status and errors live) with a marker when content was cut.\n */\nexport function formatTerminalToolOutput(raw: string): FormattedTerminalToolOutput {\n\tconst sanitized = sanitizeTerminalOutput(raw).trimEnd();\n\tconst truncation = truncateTail(sanitized, {\n\t\tmaxLines: TERMINAL_TOOL_MAX_LINES,\n\t\tmaxBytes: TERMINAL_TOOL_MAX_BYTES,\n\t});\n\tif (!truncation.truncated) {\n\t\treturn { text: sanitized, body: sanitized, truncated: false, truncation };\n\t}\n\tconst marker = truncation.lastLinePartial\n\t\t? `[Showing last ${formatSize(truncation.outputBytes)} of a single line; earlier output dropped]`\n\t\t: `[Showing lines ${truncation.totalLines - truncation.outputLines + 1}-${truncation.totalLines} of ${truncation.totalLines}; earlier output dropped]`;\n\treturn { text: `${truncation.content}\\n\\n${marker}`, body: truncation.content, marker, truncated: true, truncation };\n}\n\n/**\n * Split a tool-result text into parts so each notice becomes its own model-only\n * part. Providers join a tool result's text parts with \"\\n\", so every notice\n * must sit on its own line: the newline before it (and after it, when text\n * follows) is taken out of the neighbouring parts and restored by that join.\n * The joined parts are therefore byte-identical to `text`. A notice that is\n * absent or not line-delimited leaves `text` as one visible part.\n */\nexport function splitModelOnlyNotices(text: string, notices: ReadonlyArray<string | undefined>): TextContent[] {\n\tconst parts: TextContent[] = [];\n\tlet cursor = 0;\n\t// True when the previous part is a notice whose trailing newline was consumed.\n\tlet afterNotice = false;\n\tfor (const notice of notices) {\n\t\tif (notice === undefined || notice.length === 0) continue;\n\t\tconst index = text.indexOf(notice, cursor);\n\t\tif (index < 0) continue;\n\t\tconst end = index + notice.length;\n\t\tif (end < text.length && text[end] !== \"\\n\") continue;\n\t\tif (afterNotice && index === cursor) {\n\t\t\tparts.push(modelOnlyText(notice));\n\t\t} else if (index > cursor && text[index - 1] === \"\\n\") {\n\t\t\tparts.push({ type: \"text\", text: text.slice(cursor, index - 1) }, modelOnlyText(notice));\n\t\t} else {\n\t\t\tcontinue;\n\t\t}\n\t\tcursor = end < text.length ? end + 1 : end;\n\t\tafterNotice = end < text.length;\n\t}\n\tif (parts.length === 0) return [{ type: \"text\", text }];\n\tif (cursor < text.length || text[text.length - 1] === \"\\n\") parts.push({ type: \"text\", text: text.slice(cursor) });\n\treturn parts;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bash-output.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/terminal/tools/bash-output.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAI5C,OAAO,
|
|
1
|
+
{"version":3,"file":"bash-output.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/terminal/tools/bash-output.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAI5C,OAAO,EAIN,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EAEvB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAG3E,eAAO,MAAM,gBAAgB;;;;EAQ3B,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAwB9D,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,mBAAmB;;;;;;;;;;yBAShC,MAAM,SAAS,eAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC;;;EAmCxF"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Type } from "typebox";
|
|
2
2
|
import { formatTerminalToolOutput } from "../output-format.js";
|
|
3
3
|
import { safeRegExp, TERMINAL_OUTPUT_TOOL } from "../shared.js";
|
|
4
|
-
import { errorResult, resolveTerminalId, textResult, } from "./context.js";
|
|
4
|
+
import { errorResult, noticedResult, resolveTerminalId, textResult, } from "./context.js";
|
|
5
5
|
import { renderBashOutputCall, renderBashOutputResult } from "./render.js";
|
|
6
6
|
import { describeExit } from "./spawn.js";
|
|
7
7
|
export const bashOutputSchema = Type.Object({
|
|
@@ -62,8 +62,9 @@ export function createBashOutputTool(ctx) {
|
|
|
62
62
|
}
|
|
63
63
|
const delta = runtime.readDelta();
|
|
64
64
|
const formatted = formatTerminalToolOutput(applyFilter(delta.text, input.filter));
|
|
65
|
-
const
|
|
66
|
-
|
|
65
|
+
const droppedNotice = delta.droppedChars > 0 ? `[${delta.droppedChars} earlier chars dropped]` : undefined;
|
|
66
|
+
const dropped = droppedNotice === undefined ? "" : `${droppedNotice}\n`;
|
|
67
|
+
return noticedResult(`${prefix}${statusLine(runtime)}\n${dropped}${formatted.text || "(no new output)"}`, [droppedNotice, formatted.marker], extra);
|
|
67
68
|
},
|
|
68
69
|
renderCall: renderBashOutputCall,
|
|
69
70
|
renderResult: renderBashOutputResult,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bash-output.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/terminal/tools/bash-output.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAE/D,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EACN,WAAW,EACX,iBAAiB,EAGjB,UAAU,GACV,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC,MAAM,CAAC;IAC3C,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,uDAAuD,EAAE,CAAC;IAC9F,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,+CAA+C,EAAE,CAAC,CAAC;IACpG,IAAI,EAAE,IAAI,CAAC,QAAQ,CAClB,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE;QACzD,WAAW,EAAE,mFAAmF;KAChG,CAAC,CACF;CACD,CAAC,CAAC;AAIH,SAAS,UAAU,CAAC,OAA+B;IAClD,IAAI,CAAC,OAAO,CAAC,MAAM;QAAE,OAAO,iBAAiB,CAAC;IAC9C,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,QAAQ,CAAC;IACjD,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC;IAC1C,OAAO,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,MAAM,EAAE,CAAC,CAAC,CAAC,WAAW,MAAM,eAAe,IAAI,EAAE,CAAC;AAC3G,CAAC;AAED,SAAS,WAAW,CAAC,IAAY,EAAE,MAA0B;IAC5D,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAChC,OAAO,IAAI;SACT,KAAK,CAAC,IAAI,CAAC;SACX,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SAClC,IAAI,CAAC,IAAI,CAAC,CAAC;AACd,CAAC;AAED,SAAS,UAAU,CAAC,OAA+B;IAClD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IACpC,OAAO,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,GAAwB;IAC5D,OAAO;QACN,IAAI,EAAE,oBAAoB;QAC1B,KAAK,EAAE,aAAa;QACpB,WAAW,EACV,uRAAuR;QACxR,aAAa,EACZ,yIAAyI;QAC1I,UAAU,EAAE,gBAAgB;QAC5B,KAAK,CAAC,OAAO,CAAC,WAAmB,EAAE,KAAsB;YACxD,MAAM,SAAS,GAAG,iBAAiB,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;YAChE,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAC3C,IAAI,CAAC,OAAO;gBAAE,OAAO,WAAW,CAAC,sCAAsC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAExF,MAAM,YAAY,GAAG,GAAG,CAAC,eAAe,EAAE,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC;YAC7F,MAAM,KAAK,GAAG,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;YAC5C,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,eAAe,EAAE,YAAY,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACrF,IAAI,SAAS,GAAG,EAAE,CAAC;YACnB,IAAI,KAAK,EAAE,CAAC;gBACX,SAAS;oBACR,YAAY,GAAG,CAAC;wBACf,CAAC,CAAC,mBAAmB,YAAY,0EAA0E,KAAK,CAAC,OAAO,iBAAiB;wBACzI,CAAC,CAAC,2DAA2D,KAAK,CAAC,OAAO,iBAAiB,CAAC;YAC/F,CAAC;YACD,MAAM,KAAK,GAAG,YAAY,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;YAC5F,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YAE5D,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC7B,OAAO,UAAU,CAAC,GAAG,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,KAAK,UAAU,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;YACrF,CAAC;YAED,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;YAClC,MAAM,SAAS,GAAG,wBAAwB,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;YAClF,MAAM,
|
|
1
|
+
{"version":3,"file":"bash-output.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/terminal/tools/bash-output.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Static, Type } from \"typebox\";\nimport { formatTerminalToolOutput } from \"../output-format.ts\";\nimport type { TerminalRuntimeSession } from \"../runtime-session.ts\";\nimport { safeRegExp, TERMINAL_OUTPUT_TOOL } from \"../shared.ts\";\nimport {\n\terrorResult,\n\tnoticedResult,\n\tresolveTerminalId,\n\ttype TerminalToolContext,\n\ttype TerminalToolResult,\n\ttextResult,\n} from \"./context.ts\";\nimport { renderBashOutputCall, renderBashOutputResult } from \"./render.ts\";\nimport { describeExit } from \"./spawn.ts\";\n\nexport const bashOutputSchema = Type.Object({\n\tbash_id: Type.String({ description: \"Session id returned by a run_in_background bash call.\" }),\n\tfilter: Type.Optional(Type.String({ description: \"Only return output lines matching this regex.\" })),\n\tview: Type.Optional(\n\t\tType.Union([Type.Literal(\"log\"), Type.Literal(\"screen\")], {\n\t\t\tdescription: \"'log' returns new raw output (default); 'screen' returns the rendered xterm grid.\",\n\t\t}),\n\t),\n});\n\nexport type BashOutputInput = Static<typeof bashOutputSchema>;\n\nfunction statusLine(runtime: TerminalRuntimeSession): string {\n\tif (!runtime.exited) return \"status: running\";\n\tconst status = describeExit(runtime) ?? \"exited\";\n\tconst code = runtime.exitResult?.exitCode;\n\treturn code === null || code === undefined ? `status: ${status}` : `status: ${status} exit_code: ${code}`;\n}\n\nfunction applyFilter(text: string, filter: string | undefined): string {\n\tif (!filter) return text;\n\tconst regex = safeRegExp(filter);\n\tif (regex === null) return text;\n\treturn text\n\t\t.split(\"\\n\")\n\t\t.filter((line) => regex.test(line))\n\t\t.join(\"\\n\");\n}\n\nfunction screenView(runtime: TerminalRuntimeSession): string {\n\tconst snapshot = runtime.snapshot();\n\treturn snapshot.visibleGrid.join(\"\\n\").replace(/\\s+$/, \"\");\n}\n\nexport function createBashOutputTool(ctx: TerminalToolContext) {\n\treturn {\n\t\tname: TERMINAL_OUTPUT_TOOL,\n\t\tlabel: \"bash_output\",\n\t\tdescription:\n\t\t\t\"Read output from a background bash session without blocking: new output since the last read, the status line, or a rendered full-screen snapshot via view:'screen'. Pattern watches run through monitor; completion arrives as a notification carrying the exit code and output tail.\",\n\t\tpromptSnippet:\n\t\t\t\"Peek at background bash session output (filter, screen view, status); watch patterns with monitor, completion arrives as a notification\",\n\t\tparameters: bashOutputSchema,\n\t\tasync execute(_toolCallId: string, input: BashOutputInput): Promise<TerminalToolResult> {\n\t\t\tconst sessionId = resolveTerminalId(ctx.manager, input.bash_id);\n\t\t\tconst runtime = ctx.manager.get(sessionId);\n\t\t\tif (!runtime) return errorResult(`No terminal session found with id: ${input.bash_id}`);\n\n\t\t\tconst monitorEntry = ctx.monitorRegistry?.snapshot().find((entry) => entry.id === sessionId);\n\t\t\tconst muted = monitorEntry?.paused === true;\n\t\t\tconst mutedDropped = muted ? (ctx.monitorRegistry?.mutedDropped(sessionId) ?? 0) : 0;\n\t\t\tlet mutedNote = \"\";\n\t\t\tif (muted) {\n\t\t\t\tmutedNote =\n\t\t\t\t\tmutedDropped > 0\n\t\t\t\t\t\t? `monitor muted — ${mutedDropped} line(s) dropped while muted; run monitor({ action: \"rearm\", bash_id: \"${input.bash_id}\" }) to resume.`\n\t\t\t\t\t\t: `monitor muted; run monitor({ action: \"rearm\", bash_id: \"${input.bash_id}\" }) to resume.`;\n\t\t\t}\n\t\t\tconst extra = monitorEntry ? { details: { monitorMuted: muted, mutedDropped } } : undefined;\n\t\t\tconst prefix = mutedNote.length > 0 ? `${mutedNote}\\n` : \"\";\n\n\t\t\tif (input.view === \"screen\") {\n\t\t\t\treturn textResult(`${prefix}${statusLine(runtime)}\\n${screenView(runtime)}`, extra);\n\t\t\t}\n\n\t\t\tconst delta = runtime.readDelta();\n\t\t\tconst formatted = formatTerminalToolOutput(applyFilter(delta.text, input.filter));\n\t\t\tconst droppedNotice = delta.droppedChars > 0 ? `[${delta.droppedChars} earlier chars dropped]` : undefined;\n\t\t\tconst dropped = droppedNotice === undefined ? \"\" : `${droppedNotice}\\n`;\n\t\t\treturn noticedResult(\n\t\t\t\t`${prefix}${statusLine(runtime)}\\n${dropped}${formatted.text || \"(no new output)\"}`,\n\t\t\t\t[droppedNotice, formatted.marker],\n\t\t\t\textra,\n\t\t\t);\n\t\t},\n\t\trenderCall: renderBashOutputCall,\n\t\trenderResult: renderBashOutputResult,\n\t};\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/terminal/tools/bash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAWjE,OAAO,
|
|
1
|
+
{"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/terminal/tools/bash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAWjE,OAAO,EAGN,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EAEvB,MAAM,cAAc,CAAC;AAMtB,eAAO,MAAM,aAAa;;;;;;;EAiBxB,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,aAAa,CAAC,CAAC;AAcxD,MAAM,WAAW,gBAAgB;IAChC,QAAQ,IAAI,IAAI,CAAC;IACjB,KAAK,IAAI,IAAI,CAAC;IACd,OAAO,IAAI,IAAI,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,IAAI,EAAE,UAAU,SAA0B,GAAG,gBAAgB,CA2C/G;AAID,KAAK,gBAAgB,GAAG;IACvB,cAAc,CAAC,EAAE;QAAE,YAAY,EAAE,MAAM,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;IAC1F,KAAK,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAoSF,mDAAmD;AACnD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,mBAAmB;;cAG9C,MAAM;;;;;;;;;;;;;yBAQF,MAAM,SACZ,YAAY,WACV,WAAW,aACT,uBAAuB,YACxB,gBAAgB,GACxB,OAAO,CAAC,kBAAkB,CAAC;EAQ/B"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Type } from "typebox";
|
|
2
2
|
import { formatTerminalToolOutput } from "../output-format.js";
|
|
3
3
|
import { BACKGROUND_START_GRACE_MS, DEFAULT_COLS, DEFAULT_ROWS, FOREGROUND_ENV_OVERRIDES, KILLED_SESSION_EXIT_GRACE_MS, TERMINAL_BASH_TOOL, } from "../shared.js";
|
|
4
|
-
import { errorResult, textResult } from "./context.js";
|
|
4
|
+
import { errorResult, noticedResult, textResult, } from "./context.js";
|
|
5
5
|
import { createForegroundDetachGate } from "./foreground-detach.js";
|
|
6
6
|
import { resolveForegroundWindowSeconds, SLEEP_WAIT_WINDOW_SECONDS } from "./foreground-window.js";
|
|
7
7
|
import { classifySleepWait } from "./sleep-wait.js";
|
|
@@ -205,7 +205,7 @@ async function runForeground(ctx, input, cols, rows, signal, cwd, onUpdate, exec
|
|
|
205
205
|
const startedAt = Date.now();
|
|
206
206
|
const activity = `running ${input.command.slice(0, 80)}`;
|
|
207
207
|
const emitOutputUpdate = () => {
|
|
208
|
-
const text = formatTerminalToolOutput(runtime.fullOutput()).
|
|
208
|
+
const text = formatTerminalToolOutput(runtime.fullOutput()).body.slice(-2000);
|
|
209
209
|
onUpdate?.({ content: [{ type: "text", text }], details: { progress: { activity, startedAt } } });
|
|
210
210
|
};
|
|
211
211
|
const updateEmitter = onUpdate ? createThrottledEmitter(emitOutputUpdate) : undefined;
|
|
@@ -312,7 +312,7 @@ async function runForeground(ctx, input, cols, rows, signal, cwd, onUpdate, exec
|
|
|
312
312
|
if (exit && exit.exitCode !== 0 && exit.exitCode !== null) {
|
|
313
313
|
return errorResult(`${output ? `${output}\n\n` : ""}Command exited with code ${exit.exitCode}`);
|
|
314
314
|
}
|
|
315
|
-
return
|
|
315
|
+
return noticedResult(output || "(no output)", [formatted.marker], {
|
|
316
316
|
details: {
|
|
317
317
|
status,
|
|
318
318
|
...(formatted.truncated ? { truncation: formatted.truncation } : {}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bash.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/terminal/tools/bash.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Static, Type } from \"typebox\";\nimport type { AgentToolUpdateCallback } from \"../../../types.ts\";\nimport { formatTerminalToolOutput } from \"../output-format.ts\";\nimport type { TerminalRuntimeSession } from \"../runtime-session.ts\";\nimport {\n\tBACKGROUND_START_GRACE_MS,\n\tDEFAULT_COLS,\n\tDEFAULT_ROWS,\n\tFOREGROUND_ENV_OVERRIDES,\n\tKILLED_SESSION_EXIT_GRACE_MS,\n\tTERMINAL_BASH_TOOL,\n} from \"../shared.ts\";\nimport { errorResult, type TerminalToolContext, type TerminalToolResult, textResult } from \"./context.ts\";\nimport { createForegroundDetachGate } from \"./foreground-detach.ts\";\nimport { resolveForegroundWindowSeconds, SLEEP_WAIT_WINDOW_SECONDS } from \"./foreground-window.ts\";\nimport { classifySleepWait, type SleepWaitClassification } from \"./sleep-wait.ts\";\nimport { describeExit, spawnCommandSession } from \"./spawn.ts\";\n\nexport const ptyBashSchema = Type.Object({\n\tcommand: Type.String({ description: \"Shell command to execute in a PTY-backed session.\" }),\n\ttimeout: Type.Optional(\n\t\tType.Number({\n\t\t\tdescription:\n\t\t\t\t\"Process kill deadline in seconds (default 1800). Foreground blocking stops at the ~60s window: a command still running then auto-detaches to a live background session instead of being killed. Ignored for run_in_background sessions (they live until exit or kill_bash).\",\n\t\t}),\n\t),\n\tdescription: Type.Optional(Type.String({ description: \"Short human-readable label for this command.\" })),\n\trun_in_background: Type.Optional(\n\t\tType.Boolean({\n\t\t\tdescription:\n\t\t\t\t\"Run as a persistent background session. Returns a bash_id immediately; query it with bash_output, steer with bash_input, tear down with kill_bash.\",\n\t\t}),\n\t),\n\tcols: Type.Optional(Type.Number({ description: \"PTY width in columns (default 120).\" })),\n\trows: Type.Optional(Type.Number({ description: \"PTY height in rows (default 40).\" })),\n});\n\nexport type PtyBashInput = Static<typeof ptyBashSchema>;\n\nfunction resolveDimension(value: number | undefined, fallback: number): number {\n\tif (value === undefined || !Number.isFinite(value) || value < 1) return fallback;\n\treturn Math.trunc(value);\n}\n\nfunction delay(ms: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nconst MAX_TIMEOUT_MS = 2_147_483_647;\nconst BASH_UPDATE_THROTTLE_MS = 100;\n\nexport interface ThrottledEmitter {\n\tschedule(): void;\n\tflush(): void;\n\tdispose(): void;\n}\n\n/**\n * Emit immediately, then coalesce subsequent schedules into one trailing update.\n * `dispose` intentionally discards a pending update so callers can stop cleanly.\n */\nexport function createThrottledEmitter(emit: () => void, throttleMs = BASH_UPDATE_THROTTLE_MS): ThrottledEmitter {\n\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\tlet dirty = false;\n\tlet lastEmissionAt: number | undefined;\n\n\tconst emitIfDirty = () => {\n\t\tif (!dirty) return;\n\t\tdirty = false;\n\t\tlastEmissionAt = Date.now();\n\t\temit();\n\t};\n\n\tconst clearTimer = () => {\n\t\tif (timer !== undefined) {\n\t\t\tclearTimeout(timer);\n\t\t\ttimer = undefined;\n\t\t}\n\t};\n\n\treturn {\n\t\tschedule() {\n\t\t\tdirty = true;\n\t\t\tif (timer !== undefined) return;\n\t\t\tconst elapsed = lastEmissionAt === undefined ? throttleMs : Date.now() - lastEmissionAt;\n\t\t\tif (elapsed >= throttleMs) {\n\t\t\t\temitIfDirty();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttimer = setTimeout(() => {\n\t\t\t\ttimer = undefined;\n\t\t\t\temitIfDirty();\n\t\t\t}, throttleMs - elapsed);\n\t\t},\n\t\tflush() {\n\t\t\tclearTimer();\n\t\t\temitIfDirty();\n\t\t},\n\t\tdispose() {\n\t\t\tclearTimer();\n\t\t\tdirty = false;\n\t\t\tlastEmissionAt = undefined;\n\t\t},\n\t};\n}\n\ntype ForegroundWaitOutcome = \"exited\" | \"abort_grace\" | \"timeout_grace\";\n\ntype SessionEnvSource = {\n\tsessionManager?: { getSessionId: () => string; getSessionFile: () => string | undefined };\n\tmodel?: { provider: string; id: string };\n\tthinkingLevel?: string;\n\tcwd?: string;\n\tgoalStoreFile?: string;\n};\n\nfunction sessionSpawnContext(ctx: TerminalToolContext): TerminalToolContext {\n\treturn {\n\t\t...ctx,\n\t\t// Explicit deletions survive backends that merge overrides with the host environment.\n\t\tgetEnv: () => ({ ...ctx.getEnv(), PI_SESSION_CWD: undefined, PI_GOAL_STORE_FILE: undefined }),\n\t};\n}\n\nfunction sessionEnvOverrides(ctx: TerminalToolContext, execCtx?: SessionEnvSource): Record<string, string> {\n\tconst session = execCtx ?? ctx.getSessionContext?.();\n\tif (!session?.sessionManager) return {};\n\tconst env: Record<string, string> = {};\n\tenv.PI_SESSION_ID = session.sessionManager.getSessionId();\n\tif (session.cwd) env.PI_SESSION_CWD = session.cwd;\n\tif (session.goalStoreFile) env.PI_GOAL_STORE_FILE = session.goalStoreFile;\n\tconst sessionFile = session.sessionManager.getSessionFile();\n\tif (sessionFile) env.PI_SESSION_FILE = sessionFile;\n\tif (session.model) {\n\t\tenv.PI_PROVIDER = session.model.provider;\n\t\tenv.PI_MODEL = session.model.id;\n\t}\n\tif (session.thinkingLevel) env.PI_REASONING_LEVEL = session.thinkingLevel;\n\treturn env;\n}\n\n/**\n * Wait for the session's exit to settle, but stop waiting a bounded grace after\n * the session has been killed. The native wait joins the PTY reader thread,\n * which blocks while any surviving descendant holds the PTY open — without the\n * grace, an aborted or timed-out command can pin the agent forever.\n */\nfunction raceExitWithKillGrace(\n\truntime: TerminalRuntimeSession,\n\tsignal: AbortSignal | undefined,\n\ttimeoutMs: number | undefined,\n): Promise<ForegroundWaitOutcome> {\n\treturn new Promise((resolve, reject) => {\n\t\tlet settled = false;\n\t\tlet abortGraceTimer: ReturnType<typeof setTimeout> | undefined;\n\t\tlet timeoutGraceTimer: ReturnType<typeof setTimeout> | undefined;\n\t\tlet armAbortGrace: (() => void) | undefined;\n\t\tconst settle = (finish: () => void) => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tif (abortGraceTimer) clearTimeout(abortGraceTimer);\n\t\t\tif (timeoutGraceTimer) clearTimeout(timeoutGraceTimer);\n\t\t\tif (signal && armAbortGrace) signal.removeEventListener(\"abort\", armAbortGrace);\n\t\t\tfinish();\n\t\t};\n\t\truntime.session.waitExit().then(\n\t\t\t() => settle(() => resolve(\"exited\")),\n\t\t\t(error: unknown) => settle(() => reject(error instanceof Error ? error : new Error(String(error)))),\n\t\t);\n\t\tif (timeoutMs !== undefined) {\n\t\t\tconst timeoutGraceDeadlineMs = timeoutMs + KILLED_SESSION_EXIT_GRACE_MS;\n\t\t\t// Beyond the 32-bit setTimeout range the deadline cannot be represented;\n\t\t\t// keep the unbounded wait rather than firing a false early timeout.\n\t\t\tif (timeoutGraceDeadlineMs <= MAX_TIMEOUT_MS) {\n\t\t\t\ttimeoutGraceTimer = setTimeout(() => settle(() => resolve(\"timeout_grace\")), timeoutGraceDeadlineMs);\n\t\t\t}\n\t\t}\n\t\tif (signal) {\n\t\t\tarmAbortGrace = () => {\n\t\t\t\tabortGraceTimer ??= setTimeout(() => settle(() => resolve(\"abort_grace\")), KILLED_SESSION_EXIT_GRACE_MS);\n\t\t\t};\n\t\t\tif (signal.aborted) armAbortGrace();\n\t\t\telse signal.addEventListener(\"abort\", armAbortGrace, { once: true });\n\t\t}\n\t});\n}\n\n/**\n * How long the model blocks before a still-running command is handed to a live\n * background session. A sleep-wait detaches almost immediately: its remaining\n * time is pure waiting, which the completion notification delivers for free.\n */\nfunction resolveAutoDetachDelayMs(\n\tctx: TerminalToolContext,\n\tinput: PtyBashInput,\n\tsleepWait: SleepWaitClassification | undefined,\n): number | undefined {\n\tif (ctx.timeoutAction === \"kill\") return undefined;\n\tconst windowSeconds = sleepWait\n\t\t? Math.min(SLEEP_WAIT_WINDOW_SECONDS, resolveForegroundWindowSeconds(process.env))\n\t\t: resolveForegroundWindowSeconds(process.env);\n\tconst timeoutSeconds = input.timeout !== undefined && Number.isFinite(input.timeout) ? input.timeout : Infinity;\n\tif (timeoutSeconds <= windowSeconds) return undefined;\n\treturn Math.max(0, Math.trunc(windowSeconds * 1000));\n}\n\nfunction scheduleDetachedSweep(\n\tctx: TerminalToolContext,\n\tid: string,\n\truntime: TerminalRuntimeSession,\n\ttimeoutMs: number | undefined,\n\tstartedAt: number,\n): void {\n\tif (timeoutMs === undefined) return;\n\tconst deadlineMs = timeoutMs + KILLED_SESSION_EXIT_GRACE_MS;\n\tif (!Number.isFinite(deadlineMs) || deadlineMs > MAX_TIMEOUT_MS || runtime.exited) return;\n\n\tconst remainingMs = Math.max(0, deadlineMs - (Date.now() - startedAt));\n\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\tlet unsubscribeExit: (() => void) | undefined;\n\tconst clearSweep = () => {\n\t\tif (timer !== undefined) clearTimeout(timer);\n\t\ttimer = undefined;\n\t\tunsubscribeExit?.();\n\t\tunsubscribeExit = undefined;\n\t};\n\tunsubscribeExit = runtime.session.onExit(clearSweep);\n\tif (runtime.exited) {\n\t\tclearSweep();\n\t\treturn;\n\t}\n\ttimer = setTimeout(() => {\n\t\tclearSweep();\n\t\tif (!runtime.exited) void ctx.manager.stop(id).catch(() => {});\n\t}, remainingMs);\n}\n\nasync function runForeground(\n\tctx: TerminalToolContext,\n\tinput: PtyBashInput,\n\tcols: number,\n\trows: number,\n\tsignal: AbortSignal | undefined,\n\tcwd: string | undefined,\n\tonUpdate: AgentToolUpdateCallback | undefined,\n\texecCtx?: SessionEnvSource,\n): Promise<TerminalToolResult> {\n\tif (signal?.aborted) return errorResult(\"Command aborted\");\n\tconst timeoutMs = input.timeout !== undefined ? Math.trunc(input.timeout * 1000) : undefined;\n\tconst { id, runtime } = await spawnCommandSession(sessionSpawnContext(ctx), {\n\t\tcommand: input.command,\n\t\tcols,\n\t\trows,\n\t\ttimeoutMs,\n\t\tcwd,\n\t\tenvOverrides: { ...sessionEnvOverrides(ctx, execCtx), ...FOREGROUND_ENV_OVERRIDES },\n\t});\n\tconst startedAt = Date.now();\n\tconst activity = `running ${input.command.slice(0, 80)}`;\n\tconst emitOutputUpdate = () => {\n\t\tconst text = formatTerminalToolOutput(runtime.fullOutput()).text.slice(-2000);\n\t\tonUpdate?.({ content: [{ type: \"text\", text }], details: { progress: { activity, startedAt } } });\n\t};\n\tconst updateEmitter = onUpdate ? createThrottledEmitter(emitOutputUpdate) : undefined;\n\tonUpdate?.({ content: [], details: undefined });\n\tconst unsubscribeOutput = onUpdate ? runtime.onOutput(() => updateEmitter?.schedule()) : undefined;\n\n\tconst sleepWait = classifySleepWait(input.command);\n\tconst detachDelayMs = resolveAutoDetachDelayMs(ctx, input, sleepWait);\n\tlet outcome: ForegroundWaitOutcome | \"detached\";\n\tif (detachDelayMs === undefined) {\n\t\t// Interrupt means \"stop now\": SIGKILL the whole process group in one shot.\n\t\t// kill() is one-shot idempotent, so a gentle SIGTERM first would block any\n\t\t// escalation, and a SIGTERM-ignoring command would pin the agent forever.\n\t\tconst onAbort = () => runtime.session.kill(\"SIGKILL\");\n\t\tif (signal) {\n\t\t\tif (signal.aborted) onAbort();\n\t\t\telse signal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t}\n\t\ttry {\n\t\t\toutcome = await raceExitWithKillGrace(runtime, signal, timeoutMs);\n\t\t} finally {\n\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\tunsubscribeOutput?.();\n\t\t\tupdateEmitter?.flush();\n\t\t\tupdateEmitter?.dispose();\n\t\t}\n\t} else {\n\t\tconst abortGate = new AbortController();\n\t\tconst onAbort = () => {\n\t\t\truntime.session.kill(\"SIGKILL\");\n\t\t\tabortGate.abort();\n\t\t};\n\t\tif (signal) {\n\t\t\tif (signal.aborted) onAbort();\n\t\t\telse signal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t}\n\t\tconst detachGate = createForegroundDetachGate({\n\t\t\truntime,\n\t\t\tsignal,\n\t\t\tdelayMs: detachDelayMs,\n\t\t\tremoveAbortListener: () => signal?.removeEventListener(\"abort\", onAbort),\n\t\t});\n\t\ttry {\n\t\t\toutcome = await Promise.race([\n\t\t\t\traceExitWithKillGrace(runtime, abortGate.signal, timeoutMs),\n\t\t\t\tdetachGate.detached.then(() => \"detached\" as const),\n\t\t\t]);\n\t\t} finally {\n\t\t\tdetachGate.cancel();\n\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\tunsubscribeOutput?.();\n\t\t\tupdateEmitter?.flush();\n\t\t\tupdateEmitter?.dispose();\n\t\t}\n\t}\n\n\tif (outcome === \"detached\") {\n\t\tscheduleDetachedSweep(ctx, id, runtime, timeoutMs, startedAt);\n\t\tctx.onBackgroundStart?.(id, input.description ?? input.command, startedAt);\n\t\tif (ctx.onBackgroundExit) runtime.session.onExit(() => ctx.onBackgroundExit?.(id, runtime));\n\t\tconst delta = runtime.readDelta();\n\t\tconst partialOutput = formatTerminalToolOutput(delta.text).text || \"(no output yet)\";\n\t\tconst timeoutNote =\n\t\t\tinput.timeout !== undefined && Number.isFinite(input.timeout)\n\t\t\t\t? `not killed; the original ${input.timeout}s timeout still applies`\n\t\t\t\t: \"not killed; it will run until exit or kill_bash\";\n\t\tconst guidance = sleepWait\n\t\t\t? `This command is a wait (${sleepWait.seconds}s sleep), so it detached immediately; the wait continues in the background. Do nothing and end your turn — completion will be reported automatically with exit status and output tail. Do NOT poll bash_output({ bash_id: \"${id}\" }) for it. When you are waiting for a pattern in a command's output, launch it with monitor({ command, filter }) instead so matching lines arrive as events. Use kill_bash({ bash_id: \"${id}\" }) to stop this session.`\n\t\t\t: `Continue other work; completion will be reported automatically with exit status and output tail. Use bash_output({ bash_id: \"${id}\" }) only to peek at new output. monitor cannot attach to this session; use it for future event-driven launches. Use kill_bash({ bash_id: \"${id}\" }) to stop this session.`;\n\t\treturn textResult(\n\t\t\t`Command is still running; auto-detached to background with ID: ${id} (${timeoutNote}).\\n\\nPartial output:\\n${partialOutput}\\n\\n${guidance}`,\n\t\t\t{\n\t\t\t\tdetails: {\n\t\t\t\t\tbash_id: id,\n\t\t\t\t\tbackground: true,\n\t\t\t\t\tauto_detached: true,\n\t\t\t\t\t...(sleepWait ? { sleep_wait: true } : {}),\n\t\t\t\t\tstatus: \"running\",\n\t\t\t\t\t...(delta.droppedChars > 0 ? { droppedChars: delta.droppedChars } : {}),\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t}\n\n\tif (outcome !== \"exited\") {\n\t\t// Sweep the never-settling session: the bounded registry stop marks it\n\t\t// `stopping`, so later /exit teardown cannot hang on its exit wait.\n\t\tvoid ctx.manager.stop(id).catch(() => {});\n\t}\n\tconst formatted = formatTerminalToolOutput(runtime.fullOutput());\n\tconst output = formatted.text;\n\t// Aborted runs report \"Command aborted\" (core bash parity) whether the exit\n\t// settled normally or the kill grace released the wait. `outcome` matters\n\t// beyond that only for the timeout grace, where exitResult is still null.\n\tif (signal?.aborted) {\n\t\treturn errorResult(`${output ? `${output}\\n\\n` : \"\"}Command aborted`);\n\t}\n\tconst exit = runtime.exitResult;\n\tif (outcome === \"timeout_grace\" || exit?.timedOut) {\n\t\treturn errorResult(`${output ? `${output}\\n\\n` : \"\"}Command timed out after ${input.timeout} seconds`);\n\t}\n\tconst status = describeExit(runtime);\n\tif (exit && exit.exitCode !== 0 && exit.exitCode !== null) {\n\t\treturn errorResult(`${output ? `${output}\\n\\n` : \"\"}Command exited with code ${exit.exitCode}`);\n\t}\n\treturn textResult(output || \"(no output)\", {\n\t\tdetails: {\n\t\t\tstatus,\n\t\t\t...(formatted.truncated ? { truncation: formatted.truncation } : {}),\n\t\t},\n\t});\n}\n\nasync function runBackground(\n\tctx: TerminalToolContext,\n\tinput: PtyBashInput,\n\tcols: number,\n\trows: number,\n\tcwd: string | undefined,\n\texecCtx?: SessionEnvSource,\n): Promise<TerminalToolResult> {\n\t// Background sessions are NEVER killed by `timeout` (bash-timeout injects a default into\n\t// every bash call); they live until exit or kill_bash, so no timeoutMs is passed.\n\tconst { id, runtime } = await spawnCommandSession(sessionSpawnContext(ctx), {\n\t\tcommand: input.command,\n\t\tcols,\n\t\trows,\n\t\tcwd,\n\t\tenvOverrides: sessionEnvOverrides(ctx, execCtx),\n\t});\n\tctx.onBackgroundStart?.(id, input.description ?? input.command, Date.now());\n\tif (ctx.onBackgroundExit) runtime.session.onExit(() => ctx.onBackgroundExit?.(id, runtime));\n\n\t// Capture any output the command emits within a short grace window (or its exit).\n\tawait Promise.race([delay(BACKGROUND_START_GRACE_MS), runtime.session.waitExit()]);\n\tconst early = formatTerminalToolOutput(runtime.readDelta().text).text;\n\tconst header = `Command running in background with ID: ${id}`;\n\tconst backendNote =\n\t\truntime.backend === \"pipe-fallback\"\n\t\t\t? \"\\n(native PTY unavailable — running via pipe fallback; bash_input/bash_resize are limited.)\"\n\t\t\t: \"\";\n\tconst earlyBlock = early ? `\\n\\n${early}` : \"\";\n\treturn textResult(`${header}${backendNote}${earlyBlock}`, { details: { bash_id: id, background: true } });\n}\n\n/** Build the PTY-backed `bash` tool definition. */\nexport function createPtyBashTool(ctx: TerminalToolContext) {\n\treturn {\n\t\tname: TERMINAL_BASH_TOOL,\n\t\texposure: \"eval\" as const,\n\t\tlabel: \"bash\",\n\t\tdescription:\n\t\t\t\"Execute a shell command in a persistent PTY-backed session. Set run_in_background:true for long-lived or interactive sessions; steer them with bash_input, snapshot with bash_output, tear down with kill_bash. To wait on observable state (a build finishing, a server coming up, a log line), never run sleep or poll loops — subscribe with the monitor tool instead. Foreground blocking stops at the ~60s window and a still-running command auto-detaches to a live background session; `timeout` is the process kill deadline in seconds.\",\n\t\tpromptSnippet: \"Run shell commands; run_in_background:true for long-lived/interactive PTY sessions\",\n\t\tpromptGuidelines: [\"You can inspect PI_* environment variables for current model and session details.\"],\n\t\tparameters: ptyBashSchema,\n\t\tasync execute(\n\t\t\t_toolCallId: string,\n\t\t\tinput: PtyBashInput,\n\t\t\tsignal?: AbortSignal,\n\t\t\tonUpdate?: AgentToolUpdateCallback,\n\t\t\texecCtx?: SessionEnvSource,\n\t\t): Promise<TerminalToolResult> {\n\t\t\tconst cols = resolveDimension(input.cols, ctx.defaultCols || DEFAULT_COLS);\n\t\t\tconst rows = resolveDimension(input.rows, ctx.defaultRows || DEFAULT_ROWS);\n\t\t\tconst cwd = execCtx?.cwd;\n\t\t\tif (input.run_in_background) return runBackground(ctx, input, cols, rows, cwd, execCtx);\n\t\t\treturn runForeground(ctx, input, cols, rows, signal, cwd, onUpdate, execCtx);\n\t\t},\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"bash.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/terminal/tools/bash.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Static, Type } from \"typebox\";\nimport type { AgentToolUpdateCallback } from \"../../../types.ts\";\nimport { formatTerminalToolOutput } from \"../output-format.ts\";\nimport type { TerminalRuntimeSession } from \"../runtime-session.ts\";\nimport {\n\tBACKGROUND_START_GRACE_MS,\n\tDEFAULT_COLS,\n\tDEFAULT_ROWS,\n\tFOREGROUND_ENV_OVERRIDES,\n\tKILLED_SESSION_EXIT_GRACE_MS,\n\tTERMINAL_BASH_TOOL,\n} from \"../shared.ts\";\nimport {\n\terrorResult,\n\tnoticedResult,\n\ttype TerminalToolContext,\n\ttype TerminalToolResult,\n\ttextResult,\n} from \"./context.ts\";\nimport { createForegroundDetachGate } from \"./foreground-detach.ts\";\nimport { resolveForegroundWindowSeconds, SLEEP_WAIT_WINDOW_SECONDS } from \"./foreground-window.ts\";\nimport { classifySleepWait, type SleepWaitClassification } from \"./sleep-wait.ts\";\nimport { describeExit, spawnCommandSession } from \"./spawn.ts\";\n\nexport const ptyBashSchema = Type.Object({\n\tcommand: Type.String({ description: \"Shell command to execute in a PTY-backed session.\" }),\n\ttimeout: Type.Optional(\n\t\tType.Number({\n\t\t\tdescription:\n\t\t\t\t\"Process kill deadline in seconds (default 1800). Foreground blocking stops at the ~60s window: a command still running then auto-detaches to a live background session instead of being killed. Ignored for run_in_background sessions (they live until exit or kill_bash).\",\n\t\t}),\n\t),\n\tdescription: Type.Optional(Type.String({ description: \"Short human-readable label for this command.\" })),\n\trun_in_background: Type.Optional(\n\t\tType.Boolean({\n\t\t\tdescription:\n\t\t\t\t\"Run as a persistent background session. Returns a bash_id immediately; query it with bash_output, steer with bash_input, tear down with kill_bash.\",\n\t\t}),\n\t),\n\tcols: Type.Optional(Type.Number({ description: \"PTY width in columns (default 120).\" })),\n\trows: Type.Optional(Type.Number({ description: \"PTY height in rows (default 40).\" })),\n});\n\nexport type PtyBashInput = Static<typeof ptyBashSchema>;\n\nfunction resolveDimension(value: number | undefined, fallback: number): number {\n\tif (value === undefined || !Number.isFinite(value) || value < 1) return fallback;\n\treturn Math.trunc(value);\n}\n\nfunction delay(ms: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nconst MAX_TIMEOUT_MS = 2_147_483_647;\nconst BASH_UPDATE_THROTTLE_MS = 100;\n\nexport interface ThrottledEmitter {\n\tschedule(): void;\n\tflush(): void;\n\tdispose(): void;\n}\n\n/**\n * Emit immediately, then coalesce subsequent schedules into one trailing update.\n * `dispose` intentionally discards a pending update so callers can stop cleanly.\n */\nexport function createThrottledEmitter(emit: () => void, throttleMs = BASH_UPDATE_THROTTLE_MS): ThrottledEmitter {\n\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\tlet dirty = false;\n\tlet lastEmissionAt: number | undefined;\n\n\tconst emitIfDirty = () => {\n\t\tif (!dirty) return;\n\t\tdirty = false;\n\t\tlastEmissionAt = Date.now();\n\t\temit();\n\t};\n\n\tconst clearTimer = () => {\n\t\tif (timer !== undefined) {\n\t\t\tclearTimeout(timer);\n\t\t\ttimer = undefined;\n\t\t}\n\t};\n\n\treturn {\n\t\tschedule() {\n\t\t\tdirty = true;\n\t\t\tif (timer !== undefined) return;\n\t\t\tconst elapsed = lastEmissionAt === undefined ? throttleMs : Date.now() - lastEmissionAt;\n\t\t\tif (elapsed >= throttleMs) {\n\t\t\t\temitIfDirty();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttimer = setTimeout(() => {\n\t\t\t\ttimer = undefined;\n\t\t\t\temitIfDirty();\n\t\t\t}, throttleMs - elapsed);\n\t\t},\n\t\tflush() {\n\t\t\tclearTimer();\n\t\t\temitIfDirty();\n\t\t},\n\t\tdispose() {\n\t\t\tclearTimer();\n\t\t\tdirty = false;\n\t\t\tlastEmissionAt = undefined;\n\t\t},\n\t};\n}\n\ntype ForegroundWaitOutcome = \"exited\" | \"abort_grace\" | \"timeout_grace\";\n\ntype SessionEnvSource = {\n\tsessionManager?: { getSessionId: () => string; getSessionFile: () => string | undefined };\n\tmodel?: { provider: string; id: string };\n\tthinkingLevel?: string;\n\tcwd?: string;\n\tgoalStoreFile?: string;\n};\n\nfunction sessionSpawnContext(ctx: TerminalToolContext): TerminalToolContext {\n\treturn {\n\t\t...ctx,\n\t\t// Explicit deletions survive backends that merge overrides with the host environment.\n\t\tgetEnv: () => ({ ...ctx.getEnv(), PI_SESSION_CWD: undefined, PI_GOAL_STORE_FILE: undefined }),\n\t};\n}\n\nfunction sessionEnvOverrides(ctx: TerminalToolContext, execCtx?: SessionEnvSource): Record<string, string> {\n\tconst session = execCtx ?? ctx.getSessionContext?.();\n\tif (!session?.sessionManager) return {};\n\tconst env: Record<string, string> = {};\n\tenv.PI_SESSION_ID = session.sessionManager.getSessionId();\n\tif (session.cwd) env.PI_SESSION_CWD = session.cwd;\n\tif (session.goalStoreFile) env.PI_GOAL_STORE_FILE = session.goalStoreFile;\n\tconst sessionFile = session.sessionManager.getSessionFile();\n\tif (sessionFile) env.PI_SESSION_FILE = sessionFile;\n\tif (session.model) {\n\t\tenv.PI_PROVIDER = session.model.provider;\n\t\tenv.PI_MODEL = session.model.id;\n\t}\n\tif (session.thinkingLevel) env.PI_REASONING_LEVEL = session.thinkingLevel;\n\treturn env;\n}\n\n/**\n * Wait for the session's exit to settle, but stop waiting a bounded grace after\n * the session has been killed. The native wait joins the PTY reader thread,\n * which blocks while any surviving descendant holds the PTY open — without the\n * grace, an aborted or timed-out command can pin the agent forever.\n */\nfunction raceExitWithKillGrace(\n\truntime: TerminalRuntimeSession,\n\tsignal: AbortSignal | undefined,\n\ttimeoutMs: number | undefined,\n): Promise<ForegroundWaitOutcome> {\n\treturn new Promise((resolve, reject) => {\n\t\tlet settled = false;\n\t\tlet abortGraceTimer: ReturnType<typeof setTimeout> | undefined;\n\t\tlet timeoutGraceTimer: ReturnType<typeof setTimeout> | undefined;\n\t\tlet armAbortGrace: (() => void) | undefined;\n\t\tconst settle = (finish: () => void) => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tif (abortGraceTimer) clearTimeout(abortGraceTimer);\n\t\t\tif (timeoutGraceTimer) clearTimeout(timeoutGraceTimer);\n\t\t\tif (signal && armAbortGrace) signal.removeEventListener(\"abort\", armAbortGrace);\n\t\t\tfinish();\n\t\t};\n\t\truntime.session.waitExit().then(\n\t\t\t() => settle(() => resolve(\"exited\")),\n\t\t\t(error: unknown) => settle(() => reject(error instanceof Error ? error : new Error(String(error)))),\n\t\t);\n\t\tif (timeoutMs !== undefined) {\n\t\t\tconst timeoutGraceDeadlineMs = timeoutMs + KILLED_SESSION_EXIT_GRACE_MS;\n\t\t\t// Beyond the 32-bit setTimeout range the deadline cannot be represented;\n\t\t\t// keep the unbounded wait rather than firing a false early timeout.\n\t\t\tif (timeoutGraceDeadlineMs <= MAX_TIMEOUT_MS) {\n\t\t\t\ttimeoutGraceTimer = setTimeout(() => settle(() => resolve(\"timeout_grace\")), timeoutGraceDeadlineMs);\n\t\t\t}\n\t\t}\n\t\tif (signal) {\n\t\t\tarmAbortGrace = () => {\n\t\t\t\tabortGraceTimer ??= setTimeout(() => settle(() => resolve(\"abort_grace\")), KILLED_SESSION_EXIT_GRACE_MS);\n\t\t\t};\n\t\t\tif (signal.aborted) armAbortGrace();\n\t\t\telse signal.addEventListener(\"abort\", armAbortGrace, { once: true });\n\t\t}\n\t});\n}\n\n/**\n * How long the model blocks before a still-running command is handed to a live\n * background session. A sleep-wait detaches almost immediately: its remaining\n * time is pure waiting, which the completion notification delivers for free.\n */\nfunction resolveAutoDetachDelayMs(\n\tctx: TerminalToolContext,\n\tinput: PtyBashInput,\n\tsleepWait: SleepWaitClassification | undefined,\n): number | undefined {\n\tif (ctx.timeoutAction === \"kill\") return undefined;\n\tconst windowSeconds = sleepWait\n\t\t? Math.min(SLEEP_WAIT_WINDOW_SECONDS, resolveForegroundWindowSeconds(process.env))\n\t\t: resolveForegroundWindowSeconds(process.env);\n\tconst timeoutSeconds = input.timeout !== undefined && Number.isFinite(input.timeout) ? input.timeout : Infinity;\n\tif (timeoutSeconds <= windowSeconds) return undefined;\n\treturn Math.max(0, Math.trunc(windowSeconds * 1000));\n}\n\nfunction scheduleDetachedSweep(\n\tctx: TerminalToolContext,\n\tid: string,\n\truntime: TerminalRuntimeSession,\n\ttimeoutMs: number | undefined,\n\tstartedAt: number,\n): void {\n\tif (timeoutMs === undefined) return;\n\tconst deadlineMs = timeoutMs + KILLED_SESSION_EXIT_GRACE_MS;\n\tif (!Number.isFinite(deadlineMs) || deadlineMs > MAX_TIMEOUT_MS || runtime.exited) return;\n\n\tconst remainingMs = Math.max(0, deadlineMs - (Date.now() - startedAt));\n\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\tlet unsubscribeExit: (() => void) | undefined;\n\tconst clearSweep = () => {\n\t\tif (timer !== undefined) clearTimeout(timer);\n\t\ttimer = undefined;\n\t\tunsubscribeExit?.();\n\t\tunsubscribeExit = undefined;\n\t};\n\tunsubscribeExit = runtime.session.onExit(clearSweep);\n\tif (runtime.exited) {\n\t\tclearSweep();\n\t\treturn;\n\t}\n\ttimer = setTimeout(() => {\n\t\tclearSweep();\n\t\tif (!runtime.exited) void ctx.manager.stop(id).catch(() => {});\n\t}, remainingMs);\n}\n\nasync function runForeground(\n\tctx: TerminalToolContext,\n\tinput: PtyBashInput,\n\tcols: number,\n\trows: number,\n\tsignal: AbortSignal | undefined,\n\tcwd: string | undefined,\n\tonUpdate: AgentToolUpdateCallback | undefined,\n\texecCtx?: SessionEnvSource,\n): Promise<TerminalToolResult> {\n\tif (signal?.aborted) return errorResult(\"Command aborted\");\n\tconst timeoutMs = input.timeout !== undefined ? Math.trunc(input.timeout * 1000) : undefined;\n\tconst { id, runtime } = await spawnCommandSession(sessionSpawnContext(ctx), {\n\t\tcommand: input.command,\n\t\tcols,\n\t\trows,\n\t\ttimeoutMs,\n\t\tcwd,\n\t\tenvOverrides: { ...sessionEnvOverrides(ctx, execCtx), ...FOREGROUND_ENV_OVERRIDES },\n\t});\n\tconst startedAt = Date.now();\n\tconst activity = `running ${input.command.slice(0, 80)}`;\n\tconst emitOutputUpdate = () => {\n\t\tconst text = formatTerminalToolOutput(runtime.fullOutput()).body.slice(-2000);\n\t\tonUpdate?.({ content: [{ type: \"text\", text }], details: { progress: { activity, startedAt } } });\n\t};\n\tconst updateEmitter = onUpdate ? createThrottledEmitter(emitOutputUpdate) : undefined;\n\tonUpdate?.({ content: [], details: undefined });\n\tconst unsubscribeOutput = onUpdate ? runtime.onOutput(() => updateEmitter?.schedule()) : undefined;\n\n\tconst sleepWait = classifySleepWait(input.command);\n\tconst detachDelayMs = resolveAutoDetachDelayMs(ctx, input, sleepWait);\n\tlet outcome: ForegroundWaitOutcome | \"detached\";\n\tif (detachDelayMs === undefined) {\n\t\t// Interrupt means \"stop now\": SIGKILL the whole process group in one shot.\n\t\t// kill() is one-shot idempotent, so a gentle SIGTERM first would block any\n\t\t// escalation, and a SIGTERM-ignoring command would pin the agent forever.\n\t\tconst onAbort = () => runtime.session.kill(\"SIGKILL\");\n\t\tif (signal) {\n\t\t\tif (signal.aborted) onAbort();\n\t\t\telse signal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t}\n\t\ttry {\n\t\t\toutcome = await raceExitWithKillGrace(runtime, signal, timeoutMs);\n\t\t} finally {\n\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\tunsubscribeOutput?.();\n\t\t\tupdateEmitter?.flush();\n\t\t\tupdateEmitter?.dispose();\n\t\t}\n\t} else {\n\t\tconst abortGate = new AbortController();\n\t\tconst onAbort = () => {\n\t\t\truntime.session.kill(\"SIGKILL\");\n\t\t\tabortGate.abort();\n\t\t};\n\t\tif (signal) {\n\t\t\tif (signal.aborted) onAbort();\n\t\t\telse signal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t}\n\t\tconst detachGate = createForegroundDetachGate({\n\t\t\truntime,\n\t\t\tsignal,\n\t\t\tdelayMs: detachDelayMs,\n\t\t\tremoveAbortListener: () => signal?.removeEventListener(\"abort\", onAbort),\n\t\t});\n\t\ttry {\n\t\t\toutcome = await Promise.race([\n\t\t\t\traceExitWithKillGrace(runtime, abortGate.signal, timeoutMs),\n\t\t\t\tdetachGate.detached.then(() => \"detached\" as const),\n\t\t\t]);\n\t\t} finally {\n\t\t\tdetachGate.cancel();\n\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\tunsubscribeOutput?.();\n\t\t\tupdateEmitter?.flush();\n\t\t\tupdateEmitter?.dispose();\n\t\t}\n\t}\n\n\tif (outcome === \"detached\") {\n\t\tscheduleDetachedSweep(ctx, id, runtime, timeoutMs, startedAt);\n\t\tctx.onBackgroundStart?.(id, input.description ?? input.command, startedAt);\n\t\tif (ctx.onBackgroundExit) runtime.session.onExit(() => ctx.onBackgroundExit?.(id, runtime));\n\t\tconst delta = runtime.readDelta();\n\t\tconst partialOutput = formatTerminalToolOutput(delta.text).text || \"(no output yet)\";\n\t\tconst timeoutNote =\n\t\t\tinput.timeout !== undefined && Number.isFinite(input.timeout)\n\t\t\t\t? `not killed; the original ${input.timeout}s timeout still applies`\n\t\t\t\t: \"not killed; it will run until exit or kill_bash\";\n\t\tconst guidance = sleepWait\n\t\t\t? `This command is a wait (${sleepWait.seconds}s sleep), so it detached immediately; the wait continues in the background. Do nothing and end your turn — completion will be reported automatically with exit status and output tail. Do NOT poll bash_output({ bash_id: \"${id}\" }) for it. When you are waiting for a pattern in a command's output, launch it with monitor({ command, filter }) instead so matching lines arrive as events. Use kill_bash({ bash_id: \"${id}\" }) to stop this session.`\n\t\t\t: `Continue other work; completion will be reported automatically with exit status and output tail. Use bash_output({ bash_id: \"${id}\" }) only to peek at new output. monitor cannot attach to this session; use it for future event-driven launches. Use kill_bash({ bash_id: \"${id}\" }) to stop this session.`;\n\t\treturn textResult(\n\t\t\t`Command is still running; auto-detached to background with ID: ${id} (${timeoutNote}).\\n\\nPartial output:\\n${partialOutput}\\n\\n${guidance}`,\n\t\t\t{\n\t\t\t\tdetails: {\n\t\t\t\t\tbash_id: id,\n\t\t\t\t\tbackground: true,\n\t\t\t\t\tauto_detached: true,\n\t\t\t\t\t...(sleepWait ? { sleep_wait: true } : {}),\n\t\t\t\t\tstatus: \"running\",\n\t\t\t\t\t...(delta.droppedChars > 0 ? { droppedChars: delta.droppedChars } : {}),\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t}\n\n\tif (outcome !== \"exited\") {\n\t\t// Sweep the never-settling session: the bounded registry stop marks it\n\t\t// `stopping`, so later /exit teardown cannot hang on its exit wait.\n\t\tvoid ctx.manager.stop(id).catch(() => {});\n\t}\n\tconst formatted = formatTerminalToolOutput(runtime.fullOutput());\n\tconst output = formatted.text;\n\t// Aborted runs report \"Command aborted\" (core bash parity) whether the exit\n\t// settled normally or the kill grace released the wait. `outcome` matters\n\t// beyond that only for the timeout grace, where exitResult is still null.\n\tif (signal?.aborted) {\n\t\treturn errorResult(`${output ? `${output}\\n\\n` : \"\"}Command aborted`);\n\t}\n\tconst exit = runtime.exitResult;\n\tif (outcome === \"timeout_grace\" || exit?.timedOut) {\n\t\treturn errorResult(`${output ? `${output}\\n\\n` : \"\"}Command timed out after ${input.timeout} seconds`);\n\t}\n\tconst status = describeExit(runtime);\n\tif (exit && exit.exitCode !== 0 && exit.exitCode !== null) {\n\t\treturn errorResult(`${output ? `${output}\\n\\n` : \"\"}Command exited with code ${exit.exitCode}`);\n\t}\n\treturn noticedResult(output || \"(no output)\", [formatted.marker], {\n\t\tdetails: {\n\t\t\tstatus,\n\t\t\t...(formatted.truncated ? { truncation: formatted.truncation } : {}),\n\t\t},\n\t});\n}\n\nasync function runBackground(\n\tctx: TerminalToolContext,\n\tinput: PtyBashInput,\n\tcols: number,\n\trows: number,\n\tcwd: string | undefined,\n\texecCtx?: SessionEnvSource,\n): Promise<TerminalToolResult> {\n\t// Background sessions are NEVER killed by `timeout` (bash-timeout injects a default into\n\t// every bash call); they live until exit or kill_bash, so no timeoutMs is passed.\n\tconst { id, runtime } = await spawnCommandSession(sessionSpawnContext(ctx), {\n\t\tcommand: input.command,\n\t\tcols,\n\t\trows,\n\t\tcwd,\n\t\tenvOverrides: sessionEnvOverrides(ctx, execCtx),\n\t});\n\tctx.onBackgroundStart?.(id, input.description ?? input.command, Date.now());\n\tif (ctx.onBackgroundExit) runtime.session.onExit(() => ctx.onBackgroundExit?.(id, runtime));\n\n\t// Capture any output the command emits within a short grace window (or its exit).\n\tawait Promise.race([delay(BACKGROUND_START_GRACE_MS), runtime.session.waitExit()]);\n\tconst early = formatTerminalToolOutput(runtime.readDelta().text).text;\n\tconst header = `Command running in background with ID: ${id}`;\n\tconst backendNote =\n\t\truntime.backend === \"pipe-fallback\"\n\t\t\t? \"\\n(native PTY unavailable — running via pipe fallback; bash_input/bash_resize are limited.)\"\n\t\t\t: \"\";\n\tconst earlyBlock = early ? `\\n\\n${early}` : \"\";\n\treturn textResult(`${header}${backendNote}${earlyBlock}`, { details: { bash_id: id, background: true } });\n}\n\n/** Build the PTY-backed `bash` tool definition. */\nexport function createPtyBashTool(ctx: TerminalToolContext) {\n\treturn {\n\t\tname: TERMINAL_BASH_TOOL,\n\t\texposure: \"eval\" as const,\n\t\tlabel: \"bash\",\n\t\tdescription:\n\t\t\t\"Execute a shell command in a persistent PTY-backed session. Set run_in_background:true for long-lived or interactive sessions; steer them with bash_input, snapshot with bash_output, tear down with kill_bash. To wait on observable state (a build finishing, a server coming up, a log line), never run sleep or poll loops — subscribe with the monitor tool instead. Foreground blocking stops at the ~60s window and a still-running command auto-detaches to a live background session; `timeout` is the process kill deadline in seconds.\",\n\t\tpromptSnippet: \"Run shell commands; run_in_background:true for long-lived/interactive PTY sessions\",\n\t\tpromptGuidelines: [\"You can inspect PI_* environment variables for current model and session details.\"],\n\t\tparameters: ptyBashSchema,\n\t\tasync execute(\n\t\t\t_toolCallId: string,\n\t\t\tinput: PtyBashInput,\n\t\t\tsignal?: AbortSignal,\n\t\t\tonUpdate?: AgentToolUpdateCallback,\n\t\t\texecCtx?: SessionEnvSource,\n\t\t): Promise<TerminalToolResult> {\n\t\t\tconst cols = resolveDimension(input.cols, ctx.defaultCols || DEFAULT_COLS);\n\t\t\tconst rows = resolveDimension(input.rows, ctx.defaultRows || DEFAULT_ROWS);\n\t\t\tconst cwd = execCtx?.cwd;\n\t\t\tif (input.run_in_background) return runBackground(ctx, input, cols, rows, cwd, execCtx);\n\t\t\treturn runForeground(ctx, input, cols, rows, signal, cwd, onUpdate, execCtx);\n\t\t},\n\t};\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { TextContent } from "@earendil-works/pi-ai";
|
|
1
2
|
import type { TerminalManager } from "../manager.ts";
|
|
2
3
|
import type { MonitorEvent, MonitorRegistry } from "../monitor-registry.ts";
|
|
3
4
|
import type { TerminalRuntimeSession } from "../runtime-session.ts";
|
|
@@ -34,10 +35,7 @@ export interface TerminalToolContext {
|
|
|
34
35
|
}
|
|
35
36
|
/** Minimal tool-result shape returned by the terminal tools. */
|
|
36
37
|
export interface TerminalToolResult {
|
|
37
|
-
content:
|
|
38
|
-
type: "text";
|
|
39
|
-
text: string;
|
|
40
|
-
}>;
|
|
38
|
+
content: TextContent[];
|
|
41
39
|
details: Record<string, unknown> | undefined;
|
|
42
40
|
isError?: boolean;
|
|
43
41
|
}
|
|
@@ -54,4 +52,9 @@ export declare function textResult(text: string, extra?: {
|
|
|
54
52
|
isError?: boolean;
|
|
55
53
|
}): TerminalToolResult;
|
|
56
54
|
export declare function errorResult(text: string): TerminalToolResult;
|
|
55
|
+
/** A result whose truncation/drop notices are model-only parts (see `splitModelOnlyNotices`). */
|
|
56
|
+
export declare function noticedResult(text: string, notices: ReadonlyArray<string | undefined>, extra?: {
|
|
57
|
+
details?: Record<string, unknown>;
|
|
58
|
+
isError?: boolean;
|
|
59
|
+
}): TerminalToolResult;
|
|
57
60
|
//# sourceMappingURL=context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/terminal/tools/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/terminal/tools/context.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { splitModelOnlyNotices } from "../output-format.js";
|
|
1
2
|
/**
|
|
2
3
|
* Resolve a stable "mon_" monitor id to its current runtime id (bash_N/watch_N), passing a
|
|
3
4
|
* runtime id through unchanged. Companion tools may run against a manager that does not
|
|
@@ -14,4 +15,8 @@ export function textResult(text, extra) {
|
|
|
14
15
|
export function errorResult(text) {
|
|
15
16
|
return { content: [{ type: "text", text }], details: undefined, isError: true };
|
|
16
17
|
}
|
|
18
|
+
/** A result whose truncation/drop notices are model-only parts (see `splitModelOnlyNotices`). */
|
|
19
|
+
export function noticedResult(text, notices, extra) {
|
|
20
|
+
return { content: splitModelOnlyNotices(text, notices), details: extra?.details, isError: extra?.isError };
|
|
21
|
+
}
|
|
17
22
|
//# sourceMappingURL=context.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/terminal/tools/context.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/terminal/tools/context.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AA0C5D;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAChC,OAAmF,EACnF,EAAU;IAEV,OAAO,OAAO,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,UAAU,CACzB,IAAY,EACZ,KAAgE;IAEhE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAChG,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAY;IACvC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACjF,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,aAAa,CAC5B,IAAY,EACZ,OAA0C,EAC1C,KAAgE;IAEhE,OAAO,EAAE,OAAO,EAAE,qBAAqB,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAC5G,CAAC","sourcesContent":["import type { TextContent } from \"@earendil-works/pi-ai\";\nimport type { TerminalManager } from \"../manager.ts\";\nimport type { MonitorEvent, MonitorRegistry } from \"../monitor-registry.ts\";\nimport { splitModelOnlyNotices } from \"../output-format.ts\";\nimport type { TerminalRuntimeSession } from \"../runtime-session.ts\";\nimport type { TimeoutAction } from \"../settings.ts\";\n\n/** Shared dependencies handed to every terminal tool factory. */\nexport interface TerminalToolContext {\n\treadonly manager: TerminalManager;\n\treadonly cwd: string;\n\t/** Explicit shell path from settings (settings-manager `shellPath`), if any. */\n\treadonly shellPath?: string;\n\treadonly defaultCols: number;\n\treadonly defaultRows: number;\n\t/** Configured foreground deadline behavior; omitted direct contexts default to background. */\n\treadonly timeoutAction?: TimeoutAction;\n\t/** Resolve the environment for spawned sessions (mirrors core bash `getShellEnv`). */\n\treadonly getEnv: () => NodeJS.ProcessEnv;\n\t/**\n\t * Current extension session context (set on session_start/model_select), used to\n\t * expose PI_* session metadata to spawned commands like the core bash tool does.\n\t */\n\treadonly getSessionContext?: () => import(\"../../../types.ts\").ExtensionContext | undefined;\n\t/** Registers a session when it transitions to background liveness. */\n\treadonly onBackgroundStart?: (id: string, description: string, startedAtMs: number) => void;\n\t/** Notified when a background session exits, so the notify layer can wake the agent. */\n\treadonly onBackgroundExit?: (id: string, runtime: TerminalRuntimeSession) => void;\n\t/** Session-scoped monitor state, sharing the terminal manager's bash-id namespace. */\n\treadonly monitorRegistry?: MonitorRegistry;\n\t/** Receives filtered monitor line and terminal-summary events. */\n\treadonly onMonitorEvent?: (event: MonitorEvent) => void;\n\t/** Resets session-global wake-budget delivery for a fresh or explicitly rearmed monitor. */\n\treadonly onMonitorRearmed?: (id: string) => void;\n\t/** Clears notifier bookkeeping when multiple paused monitors are resumed. */\n\treadonly onMonitorsResumed?: (ids: readonly string[]) => void;\n}\n\n/** Minimal tool-result shape returned by the terminal tools. */\nexport interface TerminalToolResult {\n\tcontent: TextContent[];\n\tdetails: Record<string, unknown> | undefined;\n\tisError?: boolean;\n}\n\n/**\n * Resolve a stable \"mon_\" monitor id to its current runtime id (bash_N/watch_N), passing a\n * runtime id through unchanged. Companion tools may run against a manager that does not\n * implement `resolveId` (narrower embedder/test managers expose `get` only); such managers\n * have never seen a `mon_` id, so falling back to the id verbatim preserves the lookup they\n * already supported. This is the single choke point for that rule — do not inline it.\n */\nexport function resolveTerminalId(\n\tmanager: Pick<TerminalManager, \"get\"> & Partial<Pick<TerminalManager, \"resolveId\">>,\n\tid: string,\n): string {\n\treturn manager.resolveId?.(id) ?? id;\n}\n\nexport function textResult(\n\ttext: string,\n\textra?: { details?: Record<string, unknown>; isError?: boolean },\n): TerminalToolResult {\n\treturn { content: [{ type: \"text\", text }], details: extra?.details, isError: extra?.isError };\n}\n\nexport function errorResult(text: string): TerminalToolResult {\n\treturn { content: [{ type: \"text\", text }], details: undefined, isError: true };\n}\n\n/** A result whose truncation/drop notices are model-only parts (see `splitModelOnlyNotices`). */\nexport function noticedResult(\n\ttext: string,\n\tnotices: ReadonlyArray<string | undefined>,\n\textra?: { details?: Record<string, unknown>; isError?: boolean },\n): TerminalToolResult {\n\treturn { content: splitModelOnlyNotices(text, notices), details: extra?.details, isError: extra?.isError };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/terminal/tools/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/terminal/tools/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAG9C,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAEhE,KAAK,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;AAC7D,KAAK,wBAAwB,GAAG,cAAc,CAAC,OAAO,gBAAgB,EAAE,iBAAiB,CAAC,CAAC;AAC3F,KAAK,qBAAqB,GAAG,cAAc,CAAC,OAAO,aAAa,EAAE,iBAAiB,CAAC,CAAC;AACrF,KAAK,mBAAmB,GAAG,UAAU,CAAC,WAAW,CAAC,wBAAwB,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAIhG,cAAM,yBAAyB;;IAK9B,SAAS,CAAC,MAAM,EAAE,eAAe,CAAC,iBAAiB,CAAC,EAAE,OAAO,EAAE,mBAAmB,GAAG,IAAI,CAOxF;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAK9B;IAED,UAAU,IAAI,IAAI,CAAG;CACrB;AAED,wBAAgB,oBAAoB,CACnC,IAAI,EAAE,eAAe,EACrB,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,wBAAwB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GACvE,IAAI,CAEN;AAED,wBAAgB,iBAAiB,CAChC,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GACpE,IAAI,CAMN;AAED,wBAAgB,sBAAsB,CACrC,MAAM,EAAE,eAAe,CAAC,iBAAiB,CAAC,EAC1C,OAAO,EAAE,mBAAmB,EAC5B,MAAM,EAAE,UAAU,CAAC,WAAW,CAAC,wBAAwB,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAC5E,OAAO,EAAE,UAAU,CAAC,WAAW,CAAC,wBAAwB,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAC3E,yBAAyB,CAK3B"}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { Text } from "@earendil-works/pi-tui";
|
|
2
2
|
import { truncateToVisualLines } from "../../../../../modes/interactive/components/visual-truncate.js";
|
|
3
|
+
import { isModelOnlyText } from "../../../../tools/model-only-text.js";
|
|
3
4
|
const OUTPUT_PREVIEW_LINES = 8;
|
|
4
5
|
class BashOutputResultComponent {
|
|
5
6
|
#text = "";
|
|
6
7
|
#isPartial = false;
|
|
7
8
|
#expanded = false;
|
|
8
9
|
setResult(result, options) {
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
this.#text = result.content
|
|
11
|
+
.filter((content) => content.type === "text" && !isModelOnlyText(content))
|
|
12
|
+
.map((content) => (content.type === "text" ? content.text : ""))
|
|
13
|
+
.join("\n");
|
|
11
14
|
this.#isPartial = options.isPartial;
|
|
12
15
|
this.#expanded = options.expanded;
|
|
13
16
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/terminal/tools/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,gEAAgE,CAAC;
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/terminal/tools/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,gEAAgE,CAAC;AACvG,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAUvE,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAE/B,MAAM,yBAAyB;IAC9B,KAAK,GAAG,EAAE,CAAC;IACX,UAAU,GAAG,KAAK,CAAC;IACnB,SAAS,GAAG,KAAK,CAAC;IAElB,SAAS,CAAC,MAA0C,EAAE,OAA4B;QACjF,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,OAAO;aACzB,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;aACzE,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;aAC/D,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC;QACpC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC;IACnC,CAAC;IAED,MAAM,CAAC,KAAa;QACnB,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACtE,OAAO,qBAAqB,CAAC,IAAI,CAAC,KAAK,EAAE,oBAAoB,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAC3G,IAAI,CAAC,OAAO,EAAE,CACd,CAAC;IACH,CAAC;IAED,UAAU,KAAU,CAAC;CACrB;AAED,MAAM,UAAU,oBAAoB,CACnC,IAAqB,EACrB,KAAyE;IAEzE,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,eAAe,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AACzF,CAAC;AAED,MAAM,UAAU,iBAAiB,CAChC,IAAkB,EAClB,KAAsE;IAEtE,MAAM,KAAK,GACV,IAAI,CAAC,MAAM,KAAK,OAAO;QACtB,CAAC,CAAC,iBAAiB,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC,OAAO,EAAE;QACjD,CAAC,CAAC,WAAW,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC;IAClE,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,sBAAsB,CACrC,MAA0C,EAC1C,OAA4B,EAC5B,MAA4E,EAC5E,OAA6E;IAE7E,MAAM,SAAS,GACb,OAAO,CAAC,aAAuD,IAAI,IAAI,yBAAyB,EAAE,CAAC;IACrG,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,OAAO,SAAS,CAAC;AAClB,CAAC","sourcesContent":["import { Text } from \"@earendil-works/pi-tui\";\nimport { truncateToVisualLines } from \"../../../../../modes/interactive/components/visual-truncate.ts\";\nimport { isModelOnlyText } from \"../../../../tools/model-only-text.ts\";\nimport type { AgentToolResult, ToolDefinition } from \"../../../types.ts\";\nimport type { BashOutputInput, bashOutputSchema } from \"./bash-output.ts\";\nimport type { MonitorInput, monitorSchema } from \"./monitor.ts\";\n\ntype BashOutputDetails = Record<string, unknown> | undefined;\ntype BashOutputToolDefinition = ToolDefinition<typeof bashOutputSchema, BashOutputDetails>;\ntype MonitorToolDefinition = ToolDefinition<typeof monitorSchema, BashOutputDetails>;\ntype RenderResultOptions = Parameters<NonNullable<BashOutputToolDefinition[\"renderResult\"]>>[1];\n\nconst OUTPUT_PREVIEW_LINES = 8;\n\nclass BashOutputResultComponent {\n\t#text = \"\";\n\t#isPartial = false;\n\t#expanded = false;\n\n\tsetResult(result: AgentToolResult<BashOutputDetails>, options: RenderResultOptions): void {\n\t\tthis.#text = result.content\n\t\t\t.filter((content) => content.type === \"text\" && !isModelOnlyText(content))\n\t\t\t.map((content) => (content.type === \"text\" ? content.text : \"\"))\n\t\t\t.join(\"\\n\");\n\t\tthis.#isPartial = options.isPartial;\n\t\tthis.#expanded = options.expanded;\n\t}\n\n\trender(width: number): string[] {\n\t\tif (!this.#isPartial || this.#expanded) return this.#text.split(\"\\n\");\n\t\treturn truncateToVisualLines(this.#text, OUTPUT_PREVIEW_LINES, Math.max(1, width)).visualLines.map((line) =>\n\t\t\tline.trimEnd(),\n\t\t);\n\t}\n\n\tinvalidate(): void {}\n}\n\nexport function renderBashOutputCall(\n\targs: BashOutputInput,\n\ttheme: Parameters<NonNullable<BashOutputToolDefinition[\"renderCall\"]>>[1],\n): Text {\n\treturn new Text(theme.fg(\"toolTitle\", theme.bold(`bash_output ${args.bash_id}`)), 0, 0);\n}\n\nexport function renderMonitorCall(\n\targs: MonitorInput,\n\ttheme: Parameters<NonNullable<MonitorToolDefinition[\"renderCall\"]>>[1],\n): Text {\n\tconst label =\n\t\targs.action === \"rearm\"\n\t\t\t? `monitor rearm ${args.bash_id ?? \"\"}`.trimEnd()\n\t\t\t: `monitor ${args.description ?? args.command ?? \"\"}`.trimEnd();\n\treturn new Text(theme.fg(\"toolTitle\", theme.bold(label)), 0, 0);\n}\n\nexport function renderBashOutputResult(\n\tresult: AgentToolResult<BashOutputDetails>,\n\toptions: RenderResultOptions,\n\t_theme: Parameters<NonNullable<BashOutputToolDefinition[\"renderResult\"]>>[2],\n\tcontext: Parameters<NonNullable<BashOutputToolDefinition[\"renderResult\"]>>[3],\n): BashOutputResultComponent {\n\tconst component =\n\t\t(context.lastComponent as BashOutputResultComponent | undefined) ?? new BashOutputResultComponent();\n\tcomponent.setResult(result, options);\n\treturn component;\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { AgentEvent } from "@earendil-works/pi-agent-core";
|
|
2
|
+
export type AgentMessageUpdateEvent = Extract<AgentEvent, {
|
|
3
|
+
type: "message_update";
|
|
4
|
+
}>;
|
|
5
|
+
/**
|
|
6
|
+
* A `message_update` as the session publishes it. `toolcall_start` and
|
|
7
|
+
* `toolcall_end` carry `resolvedToolName`: the tool the call will run, by the
|
|
8
|
+
* rule the agent loop applies, so a client titles the call correctly before
|
|
9
|
+
* `tool_execution_start` (a gateway-namespaced `mcp__<id>__Edit` streams as `edit`).
|
|
10
|
+
*/
|
|
11
|
+
export type SessionMessageUpdateEvent = AgentMessageUpdateEvent & {
|
|
12
|
+
resolvedToolName?: string;
|
|
13
|
+
};
|
|
14
|
+
export declare function withResolvedToolName(event: AgentMessageUpdateEvent, resolve: (requested: string) => string): SessionMessageUpdateEvent;
|
|
15
|
+
//# sourceMappingURL=tool-call-display-name.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-call-display-name.d.ts","sourceRoot":"","sources":["../../src/core/tool-call-display-name.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAEhE,MAAM,MAAM,uBAAuB,GAAG,OAAO,CAAC,UAAU,EAAE;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,CAAC,CAAC;AAEtF;;;;;GAKG;AACH,MAAM,MAAM,yBAAyB,GAAG,uBAAuB,GAAG;IAAE,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAUhG,wBAAgB,oBAAoB,CACnC,KAAK,EAAE,uBAAuB,EAC9B,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,GACpC,yBAAyB,CAG3B"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
function streamedToolCallName(event) {
|
|
2
|
+
const update = event.assistantMessageEvent;
|
|
3
|
+
if (update.type === "toolcall_end")
|
|
4
|
+
return update.toolCall.name;
|
|
5
|
+
if (update.type !== "toolcall_start")
|
|
6
|
+
return undefined;
|
|
7
|
+
const block = update.partial.content[update.contentIndex];
|
|
8
|
+
return block?.type === "toolCall" && block.name.length > 0 ? block.name : undefined;
|
|
9
|
+
}
|
|
10
|
+
export function withResolvedToolName(event, resolve) {
|
|
11
|
+
const requested = streamedToolCallName(event);
|
|
12
|
+
return requested === undefined ? event : { ...event, resolvedToolName: resolve(requested) };
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=tool-call-display-name.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-call-display-name.js","sourceRoot":"","sources":["../../src/core/tool-call-display-name.ts"],"names":[],"mappings":"AAYA,SAAS,oBAAoB,CAAC,KAA8B;IAC3D,MAAM,MAAM,GAAG,KAAK,CAAC,qBAAqB,CAAC;IAC3C,IAAI,MAAM,CAAC,IAAI,KAAK,cAAc;QAAE,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;IAChE,IAAI,MAAM,CAAC,IAAI,KAAK,gBAAgB;QAAE,OAAO,SAAS,CAAC;IACvD,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IAC1D,OAAO,KAAK,EAAE,IAAI,KAAK,UAAU,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AACrF,CAAC;AAED,MAAM,UAAU,oBAAoB,CACnC,KAA8B,EAC9B,OAAsC;IAEtC,MAAM,SAAS,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAC9C,OAAO,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,gBAAgB,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;AAC7F,CAAC","sourcesContent":["import type { AgentEvent } from \"@earendil-works/pi-agent-core\";\n\nexport type AgentMessageUpdateEvent = Extract<AgentEvent, { type: \"message_update\" }>;\n\n/**\n * A `message_update` as the session publishes it. `toolcall_start` and\n * `toolcall_end` carry `resolvedToolName`: the tool the call will run, by the\n * rule the agent loop applies, so a client titles the call correctly before\n * `tool_execution_start` (a gateway-namespaced `mcp__<id>__Edit` streams as `edit`).\n */\nexport type SessionMessageUpdateEvent = AgentMessageUpdateEvent & { resolvedToolName?: string };\n\nfunction streamedToolCallName(event: AgentMessageUpdateEvent): string | undefined {\n\tconst update = event.assistantMessageEvent;\n\tif (update.type === \"toolcall_end\") return update.toolCall.name;\n\tif (update.type !== \"toolcall_start\") return undefined;\n\tconst block = update.partial.content[update.contentIndex];\n\treturn block?.type === \"toolCall\" && block.name.length > 0 ? block.name : undefined;\n}\n\nexport function withResolvedToolName(\n\tevent: AgentMessageUpdateEvent,\n\tresolve: (requested: string) => string,\n): SessionMessageUpdateEvent {\n\tconst requested = streamedToolCallName(event);\n\treturn requested === undefined ? event : { ...event, resolvedToolName: resolve(requested) };\n}\n"]}
|