@tt-a1i/openpi 0.3.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +184 -59
- package/SETUP.md +23 -7
- package/assets/openpi-launch-card-v1.webp +0 -0
- package/bin/openpi.js +145 -0
- package/extensions/ask-user/index.ts +30 -14
- package/extensions/background-terminals/index.ts +30 -2
- package/extensions/background-terminals/src/domain.ts +2 -0
- package/extensions/background-terminals/src/manager.ts +486 -106
- package/extensions/background-terminals/src/output.ts +33 -0
- package/extensions/background-terminals/src/prompt.ts +14 -6
- package/extensions/background-terminals/src/result-delivery.ts +4 -1
- package/extensions/background-terminals/src/ui/ps.ts +132 -129
- package/extensions/capabilities/index.ts +30 -42
- package/extensions/capabilities/src/ui.ts +93 -0
- package/extensions/clear-context/index.ts +83 -0
- package/extensions/context-pivot/index.ts +16 -6
- package/extensions/cron/schedule.ts +7 -1
- package/extensions/file-mutation-display/index.ts +34 -76
- package/extensions/file-mutation-display/render.ts +146 -87
- package/extensions/file-search/index.ts +8 -7
- package/extensions/file-search/src/binaries.ts +75 -59
- package/extensions/git-info/src/changed-files-view.ts +47 -14
- package/extensions/git-read/index.ts +328 -0
- package/extensions/git-read/src/args.ts +171 -0
- package/extensions/git-read/src/process.ts +81 -0
- package/extensions/git-read/src/prompt.ts +56 -0
- package/extensions/model-info/index.ts +21 -33
- package/extensions/model-info/session-metrics.ts +96 -0
- package/extensions/plan-mode/bash-policy.ts +54 -9
- package/extensions/plan-mode/index.ts +7 -2
- package/extensions/post-edit/index.ts +16 -6
- package/extensions/sessions/git-stats.ts +258 -72
- package/extensions/sessions/index.ts +222 -140
- package/extensions/sessions/preview-cache.ts +104 -0
- package/extensions/sessions/preview-loader.ts +856 -0
- package/extensions/sessions/sessions.ts +43 -4
- package/extensions/setup/index.ts +127 -131
- package/extensions/shared/activity-status.ts +36 -5
- package/extensions/shared/agent-session-page.ts +319 -0
- package/extensions/shared/agent-tool-renderer.ts +218 -0
- package/extensions/shared/agent-transcript.ts +524 -0
- package/extensions/shared/below-editor-navigation.ts +26 -0
- package/extensions/shared/capability-intent.ts +53 -0
- package/extensions/shared/child-session.ts +444 -22
- package/extensions/shared/result-budget.ts +134 -0
- package/extensions/shared/result-delivery.ts +34 -0
- package/extensions/shared/screen-chrome.ts +133 -0
- package/extensions/shared/setup-config.ts +97 -38
- package/extensions/shared/setup-episode-state.ts +1 -1
- package/extensions/shared/spinner.ts +28 -0
- package/extensions/shared/terminal-text.ts +110 -23
- package/extensions/shared/text-projection.ts +113 -0
- package/extensions/shared/tool-activity.ts +382 -0
- package/extensions/shared/tool-surface.ts +42 -8
- package/extensions/shared/transcript-viewport.ts +46 -0
- package/extensions/shared/web-observer-registry.ts +390 -0
- package/extensions/shared/worktree.ts +11 -0
- package/extensions/subagents/index.ts +461 -186
- package/extensions/subagents/navigation.ts +86 -28
- package/extensions/subagents/src/agent-types.ts +37 -15
- package/extensions/subagents/src/backend.ts +12 -1
- package/extensions/subagents/src/backends/pi.ts +375 -66
- package/extensions/subagents/src/domain.ts +5 -0
- package/extensions/subagents/src/id-sequence.ts +84 -0
- package/extensions/subagents/src/manager.ts +651 -536
- package/extensions/subagents/src/prompt.ts +185 -42
- package/extensions/subagents/src/result-artifact.ts +146 -0
- package/extensions/subagents/src/result-delivery.ts +7 -1
- package/extensions/subagents/src/runtime.ts +23 -6
- package/extensions/subagents/src/ui/takeover.ts +128 -337
- package/extensions/subagents/src/ui/transcript.ts +38 -501
- package/extensions/subagents/src/ui/wait-result.ts +103 -15
- package/extensions/suggestions/src/ui.ts +10 -4
- package/extensions/tasks/index.ts +0 -3
- package/extensions/tasks/ui.ts +79 -62
- package/extensions/ui-customization/footer.ts +7 -44
- package/extensions/ui-customization/index.ts +0 -4
- package/extensions/user-input-fold/index.ts +185 -0
- package/extensions/web/index.ts +234 -0
- package/extensions/workflows/artifacts.ts +147 -22
- package/extensions/workflows/completion-projection.ts +457 -0
- package/extensions/workflows/controller.ts +14 -2
- package/extensions/workflows/coordinator.ts +62 -0
- package/extensions/workflows/dashboard.ts +458 -339
- package/extensions/workflows/handoff.ts +121 -25
- package/extensions/workflows/index.ts +1042 -492
- package/extensions/workflows/journal.ts +148 -13
- package/extensions/workflows/model.ts +131 -19
- package/extensions/workflows/navigation.ts +61 -18
- package/extensions/workflows/progress-projection.ts +306 -0
- package/extensions/workflows/prompt.ts +166 -10
- package/extensions/workflows/replay-safety.ts +58 -27
- package/extensions/workflows/result-delivery.ts +253 -0
- package/extensions/workflows/retention.ts +593 -0
- package/extensions/workflows/runner.ts +388 -279
- package/extensions/workflows/sandbox-child.cjs +36 -3
- package/extensions/workflows/sandbox.ts +62 -8
- package/extensions/workflows/serialization.ts +325 -17
- package/extensions/workflows/tool-renderer.ts +22 -0
- package/extensions/workflows/transcript.ts +149 -0
- package/extensions/workspace-cleanup-guard/index.ts +54 -0
- package/extensions/workspace-cleanup-guard/workspace-provenance.ts +563 -0
- package/package.json +28 -8
- package/skills/subagents/REFERENCE.md +189 -0
- package/skills/subagents/SKILL.md +2 -2
- package/skills/workflows/REFERENCE.md +10 -5
- package/skills/workflows/SKILL.md +53 -10
- package/web/adapter/pi-adapter.ts +661 -0
- package/web/host/browser-launcher.ts +20 -0
- package/web/host/static-assets.ts +4 -0
- package/web/host/terminal-status.ts +38 -0
- package/web/host/web-host.ts +789 -0
- package/web/http-dispatcher.ts +125 -0
- package/web/protocol/types.ts +462 -0
- package/web/runtime/pi-runtime.ts +991 -0
- package/web/runtime/types.ts +71 -0
- package/web/runtime/web-host-lease.ts +497 -0
- package/web/trace.ts +18 -0
- package/web/ui/app.js +1398 -0
- package/web/ui/index.html +139 -0
- package/web/ui/styles.css +598 -0
- package/web/vite.config.mjs +34 -0
- package/extensions/execution-convergence/active-evidence.ts +0 -129
- package/extensions/execution-convergence/index.ts +0 -442
- package/extensions/execution-convergence/workspace-provenance.ts +0 -338
- package/extensions/setup/intercom-fs-helper.cjs +0 -130
- package/extensions/setup/intercom.ts +0 -603
- package/extensions/subagents/src/backends/stub.ts +0 -296
- package/extensions/subagents/src/format.ts +0 -48
package/bin/openpi.js
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
import { createJiti } from "jiti";
|
|
5
|
+
|
|
6
|
+
function printHelp() {
|
|
7
|
+
console.log(`OpenPI Web Workbench
|
|
8
|
+
|
|
9
|
+
Usage:
|
|
10
|
+
openpi web [workspace]
|
|
11
|
+
openpi [workspace] Alias for openpi web [workspace]
|
|
12
|
+
|
|
13
|
+
Options:
|
|
14
|
+
--port <number> Bind a specific loopback port (development)
|
|
15
|
+
--no-open Do not open a browser (development)
|
|
16
|
+
|
|
17
|
+
Starts an isolated local Web runtime. Browser conversations and session changes
|
|
18
|
+
never enter an interactive terminal Pi session.`);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const args = process.argv.slice(2);
|
|
22
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
23
|
+
printHelp();
|
|
24
|
+
process.exit(0);
|
|
25
|
+
}
|
|
26
|
+
const command = args[0] === "web" ? args.slice(1) : args;
|
|
27
|
+
const noOpen = command.includes("--no-open");
|
|
28
|
+
const noWorkspace = command.includes("--no-workspace");
|
|
29
|
+
const portIndex = command.indexOf("--port");
|
|
30
|
+
const portText = portIndex >= 0 ? command[portIndex + 1] : undefined;
|
|
31
|
+
const workspaceArgs = [];
|
|
32
|
+
for (let index = 0; index < command.length; index++) {
|
|
33
|
+
const value = command[index];
|
|
34
|
+
if (value === "--no-open") continue;
|
|
35
|
+
if (value === "--no-workspace") continue;
|
|
36
|
+
if (value === "--port") {
|
|
37
|
+
index++;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
workspaceArgs.push(value);
|
|
41
|
+
}
|
|
42
|
+
const configuredPort = portText ?? process.env.OPENPI_WEB_PORT;
|
|
43
|
+
const port = configuredPort === undefined ? undefined : Number(configuredPort);
|
|
44
|
+
if (portIndex >= 0 && (!portText || portText.startsWith("--"))) {
|
|
45
|
+
console.error("--port requires a value");
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
if (port !== undefined && (!Number.isInteger(port) || port < 0 || port > 65535)) {
|
|
49
|
+
console.error("--port must be an integer between 0 and 65535");
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
if (workspaceArgs.length > 1) {
|
|
53
|
+
console.error("Usage: openpi web [workspace]");
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
if (noWorkspace && workspaceArgs.length > 0) {
|
|
57
|
+
console.error("--no-workspace cannot be combined with a workspace");
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
let host;
|
|
62
|
+
let runtime;
|
|
63
|
+
let stopping;
|
|
64
|
+
const stop = () => {
|
|
65
|
+
stopping ??= host?.stop() ?? runtime?.dispose() ?? Promise.resolve();
|
|
66
|
+
return stopping;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
const jiti = createJiti(import.meta.url);
|
|
71
|
+
const [browserModule, hostModule, runtimeModule, statusModule, traceModule] =
|
|
72
|
+
await Promise.all([
|
|
73
|
+
jiti.import("../web/host/browser-launcher.ts"),
|
|
74
|
+
jiti.import("../web/host/web-host.ts"),
|
|
75
|
+
jiti.import("../web/runtime/pi-runtime.ts"),
|
|
76
|
+
jiti.import("../web/host/terminal-status.ts"),
|
|
77
|
+
jiti.import("../web/trace.ts"),
|
|
78
|
+
]);
|
|
79
|
+
const { openBrowser } = browserModule;
|
|
80
|
+
const { WebHost } = hostModule;
|
|
81
|
+
const { PiWebRuntime } = runtimeModule;
|
|
82
|
+
const { formatWebReadyScreen } = statusModule;
|
|
83
|
+
const { traceWeb } = traceModule;
|
|
84
|
+
runtime = noWorkspace
|
|
85
|
+
? await PiWebRuntime.createWithoutWorkspace()
|
|
86
|
+
: await PiWebRuntime.create(resolve(workspaceArgs[0] ?? process.cwd()));
|
|
87
|
+
host = new WebHost({
|
|
88
|
+
runtime,
|
|
89
|
+
...(port === undefined ? {} : { port }),
|
|
90
|
+
...(process.env.OPENPI_WEB_TOKEN
|
|
91
|
+
? { token: process.env.OPENPI_WEB_TOKEN }
|
|
92
|
+
: {}),
|
|
93
|
+
...(process.env.OPENPI_WEB_ALLOWED_ORIGIN
|
|
94
|
+
? { allowedOrigins: [process.env.OPENPI_WEB_ALLOWED_ORIGIN] }
|
|
95
|
+
: {}),
|
|
96
|
+
});
|
|
97
|
+
await host.start();
|
|
98
|
+
traceWeb("web_started", {
|
|
99
|
+
...(runtime.workspaceSelected === true ? { cwd: runtime.cwd } : {}),
|
|
100
|
+
origin: host.origin,
|
|
101
|
+
});
|
|
102
|
+
const opened = noOpen ? false : await openBrowser(host.url);
|
|
103
|
+
if (noWorkspace) {
|
|
104
|
+
console.log(
|
|
105
|
+
formatWebReadyScreen({
|
|
106
|
+
origin: host.origin,
|
|
107
|
+
url: host.url,
|
|
108
|
+
opened,
|
|
109
|
+
}),
|
|
110
|
+
);
|
|
111
|
+
} else {
|
|
112
|
+
console.log(`OpenPI Web Workbench is running at ${host.origin}`);
|
|
113
|
+
if (!opened) console.log(`Open this URL in a browser: ${host.url}`);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
for (const signal of ["SIGINT", "SIGTERM"]) {
|
|
117
|
+
process.once(signal, () => {
|
|
118
|
+
void stop().then(
|
|
119
|
+
() => process.exit(0),
|
|
120
|
+
(error) => {
|
|
121
|
+
console.error(
|
|
122
|
+
`Failed to stop OpenPI Web Workbench: ${error instanceof Error ? error.message : String(error)}`,
|
|
123
|
+
);
|
|
124
|
+
process.exit(1);
|
|
125
|
+
},
|
|
126
|
+
);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
} catch (error) {
|
|
130
|
+
let cleanupError;
|
|
131
|
+
try {
|
|
132
|
+
await stop();
|
|
133
|
+
} catch (caught) {
|
|
134
|
+
cleanupError = caught;
|
|
135
|
+
}
|
|
136
|
+
console.error(
|
|
137
|
+
`Failed to start OpenPI Web Workbench: ${error instanceof Error ? error.message : String(error)}`,
|
|
138
|
+
);
|
|
139
|
+
if (cleanupError) {
|
|
140
|
+
console.error(
|
|
141
|
+
`Failed to clean up OpenPI Web Workbench: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`,
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
process.exit(1);
|
|
145
|
+
}
|
|
@@ -15,36 +15,37 @@ import type {
|
|
|
15
15
|
import {
|
|
16
16
|
Editor,
|
|
17
17
|
type EditorTheme,
|
|
18
|
+
type Focusable,
|
|
18
19
|
Key,
|
|
19
20
|
matchesKey,
|
|
20
21
|
Text,
|
|
21
22
|
truncateToWidth,
|
|
22
|
-
type Focusable,
|
|
23
23
|
wrapTextWithAnsi,
|
|
24
24
|
} from "@earendil-works/pi-tui";
|
|
25
25
|
import { Cause, Effect, Exit } from "effect";
|
|
26
|
-
import {
|
|
27
|
-
import { sanitizeTerminalText } from "../shared/terminal-text.ts";
|
|
26
|
+
import { type Static, Type } from "typebox";
|
|
28
27
|
import {
|
|
29
28
|
PLAN_MODE_CHANNEL,
|
|
30
29
|
type PlanModeState,
|
|
31
30
|
} from "../shared/plan-mode-state.ts";
|
|
31
|
+
import { hintLine } from "../shared/screen-chrome.ts";
|
|
32
32
|
import {
|
|
33
33
|
OPENPI_SETUP_EPISODE_CHANNEL,
|
|
34
34
|
type OpenPiSetupEpisodeState,
|
|
35
35
|
} from "../shared/setup-episode-state.ts";
|
|
36
|
+
import { sanitizeTerminalText } from "../shared/terminal-text.ts";
|
|
36
37
|
import {
|
|
37
38
|
OPENPI_TOOL_SURFACE,
|
|
38
39
|
patchOwnedTools,
|
|
39
40
|
} from "../shared/tool-surface.ts";
|
|
40
41
|
import { createHumanHandoffToolDefinition } from "./handoff.ts";
|
|
41
42
|
import {
|
|
42
|
-
BRACKETED_PASTE_END,
|
|
43
|
-
BRACKETED_PASTE_START,
|
|
44
|
-
MAX_ANSWER_DRAFT_UTF8_BYTES,
|
|
45
43
|
answerDraftByteLength,
|
|
46
44
|
answerDraftFits,
|
|
45
|
+
BRACKETED_PASTE_END,
|
|
46
|
+
BRACKETED_PASTE_START,
|
|
47
47
|
longerThanAnswerDraftLimit,
|
|
48
|
+
MAX_ANSWER_DRAFT_UTF8_BYTES,
|
|
48
49
|
prospectiveAnswerDraftFits,
|
|
49
50
|
sanitizeAnswerDraftEditorInput,
|
|
50
51
|
} from "./limits.ts";
|
|
@@ -63,7 +64,7 @@ const MAX_OPTIONS = 5;
|
|
|
63
64
|
/** Preview lines rendered before the tail is summarized. */
|
|
64
65
|
const PREVIEW_MAX_LINES = 20;
|
|
65
66
|
|
|
66
|
-
export {
|
|
67
|
+
export { answerDraftFits, MAX_ANSWER_DRAFT_UTF8_BYTES } from "./limits.ts";
|
|
67
68
|
|
|
68
69
|
const OptionSchema = Type.Object({
|
|
69
70
|
label: Type.String({
|
|
@@ -949,9 +950,15 @@ export default function askUser(pi: ExtensionAPI) {
|
|
|
949
950
|
);
|
|
950
951
|
lines.push("");
|
|
951
952
|
add(
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
953
|
+
hintLine(
|
|
954
|
+
theme,
|
|
955
|
+
[
|
|
956
|
+
["↑↓", "choose"],
|
|
957
|
+
[`1-${params.questions.length}`, "edit answer"],
|
|
958
|
+
["enter", "open/submit"],
|
|
959
|
+
["esc", "dismiss"],
|
|
960
|
+
],
|
|
961
|
+
width,
|
|
955
962
|
),
|
|
956
963
|
);
|
|
957
964
|
add(theme.fg("accent", "─".repeat(width)));
|
|
@@ -1043,11 +1050,20 @@ export default function askUser(pi: ExtensionAPI) {
|
|
|
1043
1050
|
|
|
1044
1051
|
lines.push("");
|
|
1045
1052
|
add(
|
|
1046
|
-
|
|
1047
|
-
|
|
1053
|
+
hintLine(
|
|
1054
|
+
theme,
|
|
1048
1055
|
editMode
|
|
1049
|
-
?
|
|
1050
|
-
|
|
1056
|
+
? [
|
|
1057
|
+
["enter", "save answer"],
|
|
1058
|
+
["esc", "keep draft and return"],
|
|
1059
|
+
]
|
|
1060
|
+
: [
|
|
1061
|
+
[`↑↓ or 1-${currentOptions.length}`, "select"],
|
|
1062
|
+
["tab", "add notes"],
|
|
1063
|
+
["enter", "save draft answer"],
|
|
1064
|
+
["esc", "dismiss"],
|
|
1065
|
+
],
|
|
1066
|
+
width,
|
|
1051
1067
|
),
|
|
1052
1068
|
);
|
|
1053
1069
|
add(theme.fg("accent", "─".repeat(width)));
|
|
@@ -32,6 +32,10 @@ import {
|
|
|
32
32
|
OPENPI_TOOL_SURFACE,
|
|
33
33
|
patchOwnedTools,
|
|
34
34
|
} from "../shared/tool-surface.ts";
|
|
35
|
+
import {
|
|
36
|
+
projectBackgroundTerminalCapability,
|
|
37
|
+
registerWebCapability,
|
|
38
|
+
} from "../shared/web-observer-registry.ts";
|
|
35
39
|
import type { TerminalSnapshot } from "./src/domain.ts";
|
|
36
40
|
import {
|
|
37
41
|
MAX_RUNNING,
|
|
@@ -95,6 +99,8 @@ interface WatchToolDetails {
|
|
|
95
99
|
export default function (pi: ExtensionAPI) {
|
|
96
100
|
let runtime: TerminalRuntime | undefined;
|
|
97
101
|
let managerPromise: Promise<TerminalManagerShape> | undefined;
|
|
102
|
+
let managerForHooks: TerminalManagerShape | undefined;
|
|
103
|
+
let unregisterWebCapability: (() => void) | undefined;
|
|
98
104
|
let sessionContext: ExtensionContext | undefined;
|
|
99
105
|
let ui: ExtensionUIContext | undefined;
|
|
100
106
|
let unsubStatus: (() => void) | undefined;
|
|
@@ -115,9 +121,21 @@ export default function (pi: ExtensionAPI) {
|
|
|
115
121
|
|
|
116
122
|
/** Resolve the manager service once per runtime and wire the extension hooks. */
|
|
117
123
|
const getManager = () => {
|
|
124
|
+
const scope = sessionContext?.sessionManager;
|
|
118
125
|
managerPromise ??= getRuntime()
|
|
119
126
|
.runPromise(TerminalManager)
|
|
120
127
|
.then((manager) => {
|
|
128
|
+
managerForHooks = manager;
|
|
129
|
+
unregisterWebCapability?.();
|
|
130
|
+
unregisterWebCapability =
|
|
131
|
+
scope && sessionContext?.sessionManager === scope
|
|
132
|
+
? registerWebCapability(scope, {
|
|
133
|
+
kind: "background-terminals",
|
|
134
|
+
snapshot: () =>
|
|
135
|
+
projectBackgroundTerminalCapability(manager.view.list()),
|
|
136
|
+
subscribe: (listener) => manager.view.subscribe(listener),
|
|
137
|
+
})
|
|
138
|
+
: undefined;
|
|
121
139
|
manager.view.setOnSettled(onSettled);
|
|
122
140
|
unsubStatus?.();
|
|
123
141
|
unsubStatus = manager.view.subscribe(() => updateWidget(manager));
|
|
@@ -214,6 +232,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
214
232
|
// costing a turn.
|
|
215
233
|
resultDeliveryOptions(wake),
|
|
216
234
|
);
|
|
235
|
+
for (const snap of snaps) managerForHooks?.view.releaseResult(snap.id);
|
|
217
236
|
return true;
|
|
218
237
|
} catch (error) {
|
|
219
238
|
// Session may be shutting down, but retain the snapshot so any later
|
|
@@ -253,6 +272,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
253
272
|
stdout: { ...snap.stdout },
|
|
254
273
|
stderr: { ...snap.stderr },
|
|
255
274
|
});
|
|
275
|
+
managerForHooks?.view.retainResult(snap.id);
|
|
256
276
|
// Pending settlements remain retractable while busy, so bg_status/bg_kill
|
|
257
277
|
// can consume them before they are committed to context. bg_start applies
|
|
258
278
|
// backpressure across running + pending + reserved work, keeping this map
|
|
@@ -310,7 +330,10 @@ export default function (pi: ExtensionAPI) {
|
|
|
310
330
|
ui = undefined;
|
|
311
331
|
const closing = runtime;
|
|
312
332
|
runtime = undefined;
|
|
333
|
+
unregisterWebCapability?.();
|
|
334
|
+
unregisterWebCapability = undefined;
|
|
313
335
|
managerPromise = undefined;
|
|
336
|
+
managerForHooks = undefined;
|
|
314
337
|
await closing?.dispose();
|
|
315
338
|
});
|
|
316
339
|
|
|
@@ -423,12 +446,16 @@ export default function (pi: ExtensionAPI) {
|
|
|
423
446
|
);
|
|
424
447
|
}
|
|
425
448
|
|
|
449
|
+
const text = buildStatusResult(snap);
|
|
426
450
|
// This status is returning the settlement itself; a pending automatic
|
|
427
451
|
// follow-up for the same settle would be a duplicate.
|
|
428
|
-
if (snap.status !== "running")
|
|
452
|
+
if (snap.status !== "running") {
|
|
453
|
+
resultDelivery.consume([snap.id]);
|
|
454
|
+
manager.view.releaseResult(snap.id);
|
|
455
|
+
}
|
|
429
456
|
|
|
430
457
|
return {
|
|
431
|
-
content: [{ type: "text", text
|
|
458
|
+
content: [{ type: "text", text }],
|
|
432
459
|
details: {
|
|
433
460
|
id: snap.id,
|
|
434
461
|
status: snap.status,
|
|
@@ -510,6 +537,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
510
537
|
// via the killInterest consumed flag). Remove any deferred automatic
|
|
511
538
|
// delivery now that this tool returns the final state itself.
|
|
512
539
|
resultDelivery.consume(ids);
|
|
540
|
+
for (const id of ids) manager.view.releaseResult(id);
|
|
513
541
|
|
|
514
542
|
return {
|
|
515
543
|
content: [{ type: "text", text: buildKillReport(report) }],
|
|
@@ -23,6 +23,8 @@ export type TerminalStatus =
|
|
|
23
23
|
export interface OutputView {
|
|
24
24
|
/** Decoded, possibly head-trimmed text (bounded by the in-memory cap). */
|
|
25
25
|
readonly text: string;
|
|
26
|
+
/** Stateful, bounded projection safe for model-facing output. */
|
|
27
|
+
readonly modelSafeText: string;
|
|
26
28
|
/** True total bytes ever received on this stream. */
|
|
27
29
|
readonly totalBytes: number;
|
|
28
30
|
/** Bytes dropped from the head of the in-memory view (0 = complete). */
|