@bastani/atomic 0.9.32-alpha.1 → 0.9.33-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +12 -0
- package/dist/builtin/workflows/builtin/{chunk-bnz4knhy.js → chunk-0d0pd4fz.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-v4scsq3y.js → chunk-119gt64q.js} +54 -16
- package/dist/builtin/workflows/builtin/{chunk-9ywkdsa9.js → chunk-s7y3hw0n.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-dx5sjaxe.js → chunk-y68758re.js} +1 -1
- package/dist/builtin/workflows/builtin/goal.js +2 -2
- package/dist/builtin/workflows/builtin/index.js +3 -3
- package/dist/builtin/workflows/builtin/ralph.js +2 -2
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +78 -20
- package/dist/builtin/workflows/src/index.js +53 -15
- package/dist/modes/interactive/interactive-agent-events.js +9 -1
- package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.js +1 -1
- package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
- package/dist/modes/interactive/program-status-reporter.d.ts +14 -0
- package/dist/modes/interactive/program-status-reporter.d.ts.map +1 -1
- package/dist/modes/interactive/program-status-reporter.js +92 -1
- package/dist/modes/interactive/program-status-reporter.js.map +1 -1
- package/dist/modes/interactive-engine/engine-workflow-activity.d.ts +23 -0
- package/dist/modes/interactive-engine/engine-workflow-activity.d.ts.map +1 -0
- package/dist/modes/interactive-engine/engine-workflow-activity.js +80 -0
- package/dist/modes/interactive-engine/engine-workflow-activity.js.map +1 -0
- package/dist/modes/interactive-engine/extension-ui-bridge.d.ts +8 -1
- package/dist/modes/interactive-engine/extension-ui-bridge.d.ts.map +1 -1
- package/dist/modes/interactive-engine/extension-ui-bridge.js +31 -1
- package/dist/modes/interactive-engine/extension-ui-bridge.js.map +1 -1
- package/dist/modes/interactive-engine/isolated-runtime.d.ts +3 -0
- package/dist/modes/interactive-engine/isolated-runtime.d.ts.map +1 -1
- package/dist/modes/interactive-engine/isolated-runtime.js +4 -0
- package/dist/modes/interactive-engine/isolated-runtime.js.map +1 -1
- package/dist/modes/interactive-engine/protocol.d.ts +6 -0
- package/dist/modes/interactive-engine/protocol.d.ts.map +1 -1
- package/dist/modes/interactive-engine/protocol.js +63 -0
- package/dist/modes/interactive-engine/protocol.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +7 -0
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +24 -0
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +1 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-session-binding.d.ts +5 -1
- package/dist/modes/rpc/rpc-session-binding.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-session-binding.js +10 -1
- package/dist/modes/rpc/rpc-session-binding.js.map +1 -1
- package/docs/terminal-setup.md +6 -4
- package/docs/workflows/operations.md +1 -1
- package/npm-shrinkwrap.json +32 -32
- package/package.json +3 -3
|
@@ -2,6 +2,10 @@ import { APP_NAME } from "../../config.js";
|
|
|
2
2
|
function firstLine(text) {
|
|
3
3
|
return text?.split(/\r?\n/, 1)[0]?.trim() || "Error";
|
|
4
4
|
}
|
|
5
|
+
/** A root whose run ended failed (or blocked) and awaits inspection; no execution or open prompt remains. */
|
|
6
|
+
function isSettledFailure(root) {
|
|
7
|
+
return root.state === "idle" && root.actionableBlockCount === 0 && root.needsAttention;
|
|
8
|
+
}
|
|
5
9
|
export class ProgramStatusReporter {
|
|
6
10
|
runActive = false;
|
|
7
11
|
compacting = false;
|
|
@@ -9,6 +13,11 @@ export class ProgramStatusReporter {
|
|
|
9
13
|
restingStatus = { state: "idle" };
|
|
10
14
|
blocked = new Map();
|
|
11
15
|
lastReport;
|
|
16
|
+
roots = new Map();
|
|
17
|
+
/** Roots that failed while this session watched; held until the user's next input. */
|
|
18
|
+
failedRoots = new Set();
|
|
19
|
+
/** Epoch of the source whose ready snapshot is the baseline; frames before it describe history, not new outcomes. */
|
|
20
|
+
baselineEpoch;
|
|
12
21
|
getTerminal;
|
|
13
22
|
getSessionName;
|
|
14
23
|
constructor(getTerminal, getSessionName) {
|
|
@@ -21,6 +30,12 @@ export class ProgramStatusReporter {
|
|
|
21
30
|
this.runActive = true;
|
|
22
31
|
this.runResult = { state: "done" };
|
|
23
32
|
break;
|
|
33
|
+
case "message_start":
|
|
34
|
+
// The user's next message answers a held workflow failure; lifecycle notices are custom messages.
|
|
35
|
+
if (event.message.role !== "user" || this.failedRoots.size === 0)
|
|
36
|
+
return;
|
|
37
|
+
this.failedRoots.clear();
|
|
38
|
+
break;
|
|
24
39
|
case "message_end":
|
|
25
40
|
if (event.message.role !== "assistant")
|
|
26
41
|
return;
|
|
@@ -60,6 +75,58 @@ export class ProgramStatusReporter {
|
|
|
60
75
|
}
|
|
61
76
|
this.report();
|
|
62
77
|
}
|
|
78
|
+
handleWorkflowActivity(frame) {
|
|
79
|
+
if (frame.kind === "snapshot") {
|
|
80
|
+
const sameSource = this.baselineEpoch === frame.cursor.epoch;
|
|
81
|
+
if (frame.availability === "recovering" && sameSource) {
|
|
82
|
+
this.report();
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const watched = sameSource ? new Map(this.roots) : new Map();
|
|
86
|
+
this.roots.clear();
|
|
87
|
+
this.baselineEpoch = frame.availability === "ready" ? frame.cursor.epoch : undefined;
|
|
88
|
+
if (frame.availability === "ready") {
|
|
89
|
+
for (const root of frame.roots) {
|
|
90
|
+
this.roots.set(root.rootRunId, root);
|
|
91
|
+
const previous = watched.get(root.rootRunId);
|
|
92
|
+
if (previous)
|
|
93
|
+
this.recordOutcome(previous, root);
|
|
94
|
+
}
|
|
95
|
+
for (const id of this.failedRoots) {
|
|
96
|
+
const root = this.roots.get(id);
|
|
97
|
+
if (!root || !isSettledFailure(root))
|
|
98
|
+
this.failedRoots.delete(id);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
else if (frame.kind === "changed") {
|
|
103
|
+
const previous = this.roots.get(frame.root.rootRunId);
|
|
104
|
+
this.roots.set(frame.root.rootRunId, frame.root);
|
|
105
|
+
if (this.baselineEpoch === frame.cursor.epoch)
|
|
106
|
+
this.recordOutcome(previous, frame.root);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
this.roots.delete(frame.rootRunId);
|
|
110
|
+
this.failedRoots.delete(frame.rootRunId);
|
|
111
|
+
}
|
|
112
|
+
this.report();
|
|
113
|
+
}
|
|
114
|
+
recordOutcome(previous, root) {
|
|
115
|
+
if (isSettledFailure(root)) {
|
|
116
|
+
if (!previous || !isSettledFailure(previous))
|
|
117
|
+
this.failedRoots.add(root.rootRunId);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
this.failedRoots.delete(root.rootRunId);
|
|
121
|
+
const finished = previous !== undefined &&
|
|
122
|
+
previous.state !== "idle" &&
|
|
123
|
+
previous.reason !== "stopping" &&
|
|
124
|
+
root.state === "idle" &&
|
|
125
|
+
root.reason !== "paused" &&
|
|
126
|
+
!root.needsAttention;
|
|
127
|
+
if (finished && this.restingStatus.state === "idle")
|
|
128
|
+
this.restingStatus = { state: "done" };
|
|
129
|
+
}
|
|
63
130
|
setBlocked(source, status) {
|
|
64
131
|
this.blocked.delete(source);
|
|
65
132
|
if (status)
|
|
@@ -85,12 +152,36 @@ export class ProgramStatusReporter {
|
|
|
85
152
|
const blocked = [...this.blocked.values()].at(-1);
|
|
86
153
|
if (blocked)
|
|
87
154
|
return { state: "blocked", ...blocked };
|
|
155
|
+
const workflowBlocked = this.workflowBlockedStatus();
|
|
156
|
+
if (workflowBlocked)
|
|
157
|
+
return workflowBlocked;
|
|
88
158
|
if (this.compacting)
|
|
89
159
|
return { state: "working", message: "Compacting context" };
|
|
90
|
-
const
|
|
160
|
+
const workflowWorking = [...this.roots.values()].some((root) => root.state === "working");
|
|
161
|
+
if (!this.runActive && !workflowWorking && this.failedRoots.size > 0) {
|
|
162
|
+
return { state: "error", message: "Workflow failed" };
|
|
163
|
+
}
|
|
164
|
+
const status = this.runActive || workflowWorking ? { state: "working" } : this.restingStatus;
|
|
91
165
|
if (status.state === "working" || status.state === "done")
|
|
92
166
|
return { ...status, message: this.getSessionName() };
|
|
93
167
|
return status;
|
|
94
168
|
}
|
|
169
|
+
/**
|
|
170
|
+
* A root waits for the user when it is blocked, or when a wait is open beside executing work: the
|
|
171
|
+
* projection reports such a root as `working`. Fixed text only: prompts raised by workflows never
|
|
172
|
+
* reach the terminal.
|
|
173
|
+
*/
|
|
174
|
+
workflowBlockedStatus() {
|
|
175
|
+
const waiting = [...this.roots.values()].filter((root) => root.state === "blocked" || root.actionableBlockCount > 0);
|
|
176
|
+
if (waiting.length === 0)
|
|
177
|
+
return undefined;
|
|
178
|
+
// A root that is still working cannot say whether its wait is a prompt or a manual decision.
|
|
179
|
+
const needsDecision = waiting.every((root) => root.reason === "manual_intervention");
|
|
180
|
+
return {
|
|
181
|
+
state: "blocked",
|
|
182
|
+
kind: "question",
|
|
183
|
+
message: needsDecision ? "Workflow needs attention" : "Workflow waiting for input",
|
|
184
|
+
};
|
|
185
|
+
}
|
|
95
186
|
}
|
|
96
187
|
//# sourceMappingURL=program-status-reporter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"program-status-reporter.js","sourceRoot":"","sources":["../../../src/modes/interactive/program-status-reporter.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ProgramStatus, Terminal } from \"@earendil-works/pi-tui\";\nimport { APP_NAME } from \"../../config.js\";\nimport type { AgentSessionEvent } from \"../../core/agent-session.js\";\nimport type { JsonAgentSessionEvent } from \"../json-event.ts\";\n\nexport type BlockedStatus = { kind: NonNullable<ProgramStatus[\"kind\"]>; message: string };\n\nfunction firstLine(text: string | undefined): string {\n\treturn text?.split(/\\r?\\n/, 1)[0]?.trim() || \"Error\";\n}\n\nexport class ProgramStatusReporter {\n\tprivate runActive = false;\n\tprivate compacting = false;\n\tprivate runResult: ProgramStatus = { state: \"done\" };\n\tprivate restingStatus: ProgramStatus = { state: \"idle\" };\n\tprivate readonly blocked = new Map<string, BlockedStatus>();\n\tprivate lastReport: string | undefined;\n\n\tprivate readonly getTerminal: () => Terminal;\n\tprivate readonly getSessionName: () => string | undefined;\n\n\tconstructor(getTerminal: () => Terminal, getSessionName: () => string | undefined) {\n\t\tthis.getTerminal = getTerminal;\n\t\tthis.getSessionName = getSessionName;\n\t}\n\n\thandleEvent(event: AgentSessionEvent | JsonAgentSessionEvent): void {\n\t\tswitch (event.type) {\n\t\t\tcase \"agent_start\":\n\t\t\t\tthis.runActive = true;\n\t\t\t\tthis.runResult = { state: \"done\" };\n\t\t\t\tbreak;\n\t\t\tcase \"message_end\":\n\t\t\t\tif (event.message.role !== \"assistant\") return;\n\t\t\t\tthis.runResult =\n\t\t\t\t\tevent.message.stopReason === \"error\"\n\t\t\t\t\t\t? { state: \"error\", message: firstLine(event.message.errorMessage) }\n\t\t\t\t\t\t: { state: \"done\" };\n\t\t\t\tbreak;\n\t\t\tcase \"compaction_start\":\n\t\t\t\tthis.compacting = true;\n\t\t\t\tbreak;\n\t\t\tcase \"compaction_end\":\n\t\t\t\tthis.compacting = false;\n\t\t\t\tif (this.runActive) {\n\t\t\t\t\tif (event.aborted) this.runResult = { state: \"idle\" };\n\t\t\t\t\telse if (event.errorMessage) this.runResult = { state: \"error\", message: firstLine(event.errorMessage) };\n\t\t\t\t} else if (event.aborted) {\n\t\t\t\t\tthis.restingStatus = { state: \"idle\" };\n\t\t\t\t} else if (event.reason === \"manual\") {\n\t\t\t\t\tthis.restingStatus = event.errorMessage\n\t\t\t\t\t\t? { state: \"error\", message: firstLine(event.errorMessage) }\n\t\t\t\t\t\t: { state: \"done\" };\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"agent_settled\":\n\t\t\t\tthis.runActive = false;\n\t\t\t\tthis.restingStatus = event.aborted ? { state: \"idle\" } : this.runResult;\n\t\t\t\tbreak;\n\t\t\tcase \"session_info_changed\":\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treturn;\n\t\t}\n\t\tthis.report();\n\t}\n\n\tsetBlocked(source: string, status: BlockedStatus | undefined): void {\n\t\tthis.blocked.delete(source);\n\t\tif (status) this.blocked.set(source, status);\n\t\tthis.report();\n\t}\n\n\treset(): void {\n\t\tthis.runActive = false;\n\t\tthis.compacting = false;\n\t\tthis.runResult = { state: \"done\" };\n\t\tthis.restingStatus = { state: \"idle\" };\n\t\tthis.report();\n\t}\n\n\treport(): void {\n\t\tconst status: ProgramStatus = { ...this.currentStatus(), app: APP_NAME };\n\t\tconst key = JSON.stringify(status);\n\t\tif (key === this.lastReport) return;\n\t\tthis.lastReport = key;\n\t\tthis.getTerminal().setProgramStatus(status);\n\t}\n\n\tprivate currentStatus(): ProgramStatus {\n\t\tconst blocked = [...this.blocked.values()].at(-1);\n\t\tif (blocked) return { state: \"blocked\", ...blocked };\n\t\tif (this.compacting) return { state: \"working\", message: \"Compacting context\" };\n\t\tconst status = this.runActive ? { state: \"working\" as const } : this.restingStatus;\n\t\tif (status.state === \"working\" || status.state === \"done\") return { ...status, message: this.getSessionName() };\n\t\treturn status;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"program-status-reporter.js","sourceRoot":"","sources":["../../../src/modes/interactive/program-status-reporter.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ProgramStatus, Terminal } from \"@earendil-works/pi-tui\";\nimport { APP_NAME } from \"../../config.js\";\nimport type { AgentSessionEvent } from \"../../core/agent-session.js\";\nimport type { WorkflowActivityFrame, WorkflowRootActivity } from \"../../core/extensions/workflow-events.js\";\nimport type { JsonAgentSessionEvent } from \"../json-event.ts\";\n\nexport type BlockedStatus = { kind: NonNullable<ProgramStatus[\"kind\"]>; message: string };\n\nfunction firstLine(text: string | undefined): string {\n\treturn text?.split(/\\r?\\n/, 1)[0]?.trim() || \"Error\";\n}\n\n/** A root whose run ended failed (or blocked) and awaits inspection; no execution or open prompt remains. */\nfunction isSettledFailure(root: WorkflowRootActivity): boolean {\n\treturn root.state === \"idle\" && root.actionableBlockCount === 0 && root.needsAttention;\n}\n\nexport class ProgramStatusReporter {\n\tprivate runActive = false;\n\tprivate compacting = false;\n\tprivate runResult: ProgramStatus = { state: \"done\" };\n\tprivate restingStatus: ProgramStatus = { state: \"idle\" };\n\tprivate readonly blocked = new Map<string, BlockedStatus>();\n\tprivate lastReport: string | undefined;\n\tprivate readonly roots = new Map<string, WorkflowRootActivity>();\n\t/** Roots that failed while this session watched; held until the user's next input. */\n\tprivate readonly failedRoots = new Set<string>();\n\t/** Epoch of the source whose ready snapshot is the baseline; frames before it describe history, not new outcomes. */\n\tprivate baselineEpoch: string | undefined;\n\n\tprivate readonly getTerminal: () => Terminal;\n\tprivate readonly getSessionName: () => string | undefined;\n\n\tconstructor(getTerminal: () => Terminal, getSessionName: () => string | undefined) {\n\t\tthis.getTerminal = getTerminal;\n\t\tthis.getSessionName = getSessionName;\n\t}\n\n\thandleEvent(event: AgentSessionEvent | JsonAgentSessionEvent): void {\n\t\tswitch (event.type) {\n\t\t\tcase \"agent_start\":\n\t\t\t\tthis.runActive = true;\n\t\t\t\tthis.runResult = { state: \"done\" };\n\t\t\t\tbreak;\n\t\t\tcase \"message_start\":\n\t\t\t\t// The user's next message answers a held workflow failure; lifecycle notices are custom messages.\n\t\t\t\tif (event.message.role !== \"user\" || this.failedRoots.size === 0) return;\n\t\t\t\tthis.failedRoots.clear();\n\t\t\t\tbreak;\n\t\t\tcase \"message_end\":\n\t\t\t\tif (event.message.role !== \"assistant\") return;\n\t\t\t\tthis.runResult =\n\t\t\t\t\tevent.message.stopReason === \"error\"\n\t\t\t\t\t\t? { state: \"error\", message: firstLine(event.message.errorMessage) }\n\t\t\t\t\t\t: { state: \"done\" };\n\t\t\t\tbreak;\n\t\t\tcase \"compaction_start\":\n\t\t\t\tthis.compacting = true;\n\t\t\t\tbreak;\n\t\t\tcase \"compaction_end\":\n\t\t\t\tthis.compacting = false;\n\t\t\t\tif (this.runActive) {\n\t\t\t\t\tif (event.aborted) this.runResult = { state: \"idle\" };\n\t\t\t\t\telse if (event.errorMessage) this.runResult = { state: \"error\", message: firstLine(event.errorMessage) };\n\t\t\t\t} else if (event.aborted) {\n\t\t\t\t\tthis.restingStatus = { state: \"idle\" };\n\t\t\t\t} else if (event.reason === \"manual\") {\n\t\t\t\t\tthis.restingStatus = event.errorMessage\n\t\t\t\t\t\t? { state: \"error\", message: firstLine(event.errorMessage) }\n\t\t\t\t\t\t: { state: \"done\" };\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"agent_settled\":\n\t\t\t\tthis.runActive = false;\n\t\t\t\tthis.restingStatus = event.aborted ? { state: \"idle\" } : this.runResult;\n\t\t\t\tbreak;\n\t\t\tcase \"session_info_changed\":\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treturn;\n\t\t}\n\t\tthis.report();\n\t}\n\n\thandleWorkflowActivity(frame: WorkflowActivityFrame): void {\n\t\tif (frame.kind === \"snapshot\") {\n\t\t\tconst sameSource = this.baselineEpoch === frame.cursor.epoch;\n\t\t\tif (frame.availability === \"recovering\" && sameSource) {\n\t\t\t\tthis.report();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst watched = sameSource ? new Map(this.roots) : new Map<string, WorkflowRootActivity>();\n\t\t\tthis.roots.clear();\n\t\t\tthis.baselineEpoch = frame.availability === \"ready\" ? frame.cursor.epoch : undefined;\n\t\t\tif (frame.availability === \"ready\") {\n\t\t\t\tfor (const root of frame.roots) {\n\t\t\t\t\tthis.roots.set(root.rootRunId, root);\n\t\t\t\t\tconst previous = watched.get(root.rootRunId);\n\t\t\t\t\tif (previous) this.recordOutcome(previous, root);\n\t\t\t\t}\n\t\t\t\tfor (const id of this.failedRoots) {\n\t\t\t\t\tconst root = this.roots.get(id);\n\t\t\t\t\tif (!root || !isSettledFailure(root)) this.failedRoots.delete(id);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (frame.kind === \"changed\") {\n\t\t\tconst previous = this.roots.get(frame.root.rootRunId);\n\t\t\tthis.roots.set(frame.root.rootRunId, frame.root);\n\t\t\tif (this.baselineEpoch === frame.cursor.epoch) this.recordOutcome(previous, frame.root);\n\t\t} else {\n\t\t\tthis.roots.delete(frame.rootRunId);\n\t\t\tthis.failedRoots.delete(frame.rootRunId);\n\t\t}\n\t\tthis.report();\n\t}\n\n\tprivate recordOutcome(previous: WorkflowRootActivity | undefined, root: WorkflowRootActivity): void {\n\t\tif (isSettledFailure(root)) {\n\t\t\tif (!previous || !isSettledFailure(previous)) this.failedRoots.add(root.rootRunId);\n\t\t\treturn;\n\t\t}\n\t\tthis.failedRoots.delete(root.rootRunId);\n\t\tconst finished =\n\t\t\tprevious !== undefined &&\n\t\t\tprevious.state !== \"idle\" &&\n\t\t\tprevious.reason !== \"stopping\" &&\n\t\t\troot.state === \"idle\" &&\n\t\t\troot.reason !== \"paused\" &&\n\t\t\t!root.needsAttention;\n\t\tif (finished && this.restingStatus.state === \"idle\") this.restingStatus = { state: \"done\" };\n\t}\n\n\tsetBlocked(source: string, status: BlockedStatus | undefined): void {\n\t\tthis.blocked.delete(source);\n\t\tif (status) this.blocked.set(source, status);\n\t\tthis.report();\n\t}\n\n\treset(): void {\n\t\tthis.runActive = false;\n\t\tthis.compacting = false;\n\t\tthis.runResult = { state: \"done\" };\n\t\tthis.restingStatus = { state: \"idle\" };\n\t\tthis.report();\n\t}\n\n\treport(): void {\n\t\tconst status: ProgramStatus = { ...this.currentStatus(), app: APP_NAME };\n\t\tconst key = JSON.stringify(status);\n\t\tif (key === this.lastReport) return;\n\t\tthis.lastReport = key;\n\t\tthis.getTerminal().setProgramStatus(status);\n\t}\n\n\tprivate currentStatus(): ProgramStatus {\n\t\tconst blocked = [...this.blocked.values()].at(-1);\n\t\tif (blocked) return { state: \"blocked\", ...blocked };\n\t\tconst workflowBlocked = this.workflowBlockedStatus();\n\t\tif (workflowBlocked) return workflowBlocked;\n\t\tif (this.compacting) return { state: \"working\", message: \"Compacting context\" };\n\t\tconst workflowWorking = [...this.roots.values()].some((root) => root.state === \"working\");\n\t\tif (!this.runActive && !workflowWorking && this.failedRoots.size > 0) {\n\t\t\treturn { state: \"error\", message: \"Workflow failed\" };\n\t\t}\n\t\tconst status = this.runActive || workflowWorking ? { state: \"working\" as const } : this.restingStatus;\n\t\tif (status.state === \"working\" || status.state === \"done\") return { ...status, message: this.getSessionName() };\n\t\treturn status;\n\t}\n\n\t/**\n\t * A root waits for the user when it is blocked, or when a wait is open beside executing work: the\n\t * projection reports such a root as `working`. Fixed text only: prompts raised by workflows never\n\t * reach the terminal.\n\t */\n\tprivate workflowBlockedStatus(): ProgramStatus | undefined {\n\t\tconst waiting = [...this.roots.values()].filter(\n\t\t\t(root) => root.state === \"blocked\" || root.actionableBlockCount > 0,\n\t\t);\n\t\tif (waiting.length === 0) return undefined;\n\t\t// A root that is still working cannot say whether its wait is a prompt or a manual decision.\n\t\tconst needsDecision = waiting.every((root) => root.reason === \"manual_intervention\");\n\t\treturn {\n\t\t\tstate: \"blocked\",\n\t\t\tkind: \"question\",\n\t\t\tmessage: needsDecision ? \"Workflow needs attention\" : \"Workflow waiting for input\",\n\t\t};\n\t}\n}\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { AgentSession } from "../../core/agent-session.js";
|
|
2
|
+
import type { WorkflowActivityFrame } from "../../core/extensions/workflow-events.js";
|
|
3
|
+
/**
|
|
4
|
+
* Forward the engine's workflow activity to the host that owns the terminal. The host reports it as
|
|
5
|
+
* program status, which needs each root's state and outcome but never its graph, so frames that
|
|
6
|
+
* change only the graph are not sent.
|
|
7
|
+
*/
|
|
8
|
+
export declare function forwardWorkflowActivity(session: AgentSession, write: (line: string) => void): () => void;
|
|
9
|
+
/**
|
|
10
|
+
* The host's view of the engine's workflow activity. The engine publishes its snapshot as soon as it
|
|
11
|
+
* binds, which can be before the host attaches an observer, so the host keeps the frames folded into
|
|
12
|
+
* one current snapshot and replays that to every observer that attaches later.
|
|
13
|
+
*/
|
|
14
|
+
export declare class WorkflowActivityMirror {
|
|
15
|
+
private cursor;
|
|
16
|
+
private availability;
|
|
17
|
+
private readonly roots;
|
|
18
|
+
apply(frame: WorkflowActivityFrame): void;
|
|
19
|
+
/** The snapshot a late observer starts from; absent until the engine published something. */
|
|
20
|
+
current(): WorkflowActivityFrame | undefined;
|
|
21
|
+
reset(): void;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=engine-workflow-activity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine-workflow-activity.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive-engine/engine-workflow-activity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,qBAAqB,EAAwB,MAAM,0CAA0C,CAAC;AAO5G;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI,CA0BxG;AAED;;;;GAIG;AACH,qBAAa,sBAAsB;IAClC,OAAO,CAAC,MAAM,CAA8C;IAC5D,OAAO,CAAC,YAAY,CAAyD;IAC7E,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA2C;IAEjE,KAAK,CAAC,KAAK,EAAE,qBAAqB,GAAG,IAAI,CAQxC;IAED,6FAA6F;IAC7F,OAAO,IAAI,qBAAqB,GAAG,SAAS,CAM3C;IAED,KAAK,IAAI,IAAI,CAIZ;CACD"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { serializeInteractiveEngineMessage } from "./protocol.js";
|
|
2
|
+
function withoutGraph({ graph: _graph, ...summary }) {
|
|
3
|
+
return summary;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Forward the engine's workflow activity to the host that owns the terminal. The host reports it as
|
|
7
|
+
* program status, which needs each root's state and outcome but never its graph, so frames that
|
|
8
|
+
* change only the graph are not sent.
|
|
9
|
+
*/
|
|
10
|
+
export function forwardWorkflowActivity(session, write) {
|
|
11
|
+
const sent = new Map();
|
|
12
|
+
const subscription = session.workflows.observe((frame) => {
|
|
13
|
+
let forward;
|
|
14
|
+
if (frame.kind === "snapshot") {
|
|
15
|
+
sent.clear();
|
|
16
|
+
if (frame.availability !== "ready") {
|
|
17
|
+
forward = frame;
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
const roots = frame.roots.map(withoutGraph);
|
|
21
|
+
for (const root of roots)
|
|
22
|
+
sent.set(root.rootRunId, JSON.stringify(root));
|
|
23
|
+
forward = { ...frame, roots };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
else if (frame.kind === "changed") {
|
|
27
|
+
const root = withoutGraph(frame.root);
|
|
28
|
+
const key = JSON.stringify(root);
|
|
29
|
+
if (sent.get(root.rootRunId) === key)
|
|
30
|
+
return;
|
|
31
|
+
sent.set(root.rootRunId, key);
|
|
32
|
+
forward = { ...frame, root };
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
sent.delete(frame.rootRunId);
|
|
36
|
+
forward = frame;
|
|
37
|
+
}
|
|
38
|
+
write(serializeInteractiveEngineMessage({ type: "engine_workflow_activity", frame: forward }));
|
|
39
|
+
});
|
|
40
|
+
return () => subscription.dispose();
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The host's view of the engine's workflow activity. The engine publishes its snapshot as soon as it
|
|
44
|
+
* binds, which can be before the host attaches an observer, so the host keeps the frames folded into
|
|
45
|
+
* one current snapshot and replays that to every observer that attaches later.
|
|
46
|
+
*/
|
|
47
|
+
export class WorkflowActivityMirror {
|
|
48
|
+
cursor;
|
|
49
|
+
availability = "unavailable";
|
|
50
|
+
roots = new Map();
|
|
51
|
+
apply(frame) {
|
|
52
|
+
this.cursor = frame.cursor;
|
|
53
|
+
if (frame.kind === "snapshot") {
|
|
54
|
+
this.availability = frame.availability;
|
|
55
|
+
this.roots.clear();
|
|
56
|
+
if (frame.availability === "ready")
|
|
57
|
+
for (const root of frame.roots)
|
|
58
|
+
this.roots.set(root.rootRunId, root);
|
|
59
|
+
}
|
|
60
|
+
else if (frame.kind === "changed")
|
|
61
|
+
this.roots.set(frame.root.rootRunId, frame.root);
|
|
62
|
+
else
|
|
63
|
+
this.roots.delete(frame.rootRunId);
|
|
64
|
+
}
|
|
65
|
+
/** The snapshot a late observer starts from; absent until the engine published something. */
|
|
66
|
+
current() {
|
|
67
|
+
if (!this.cursor)
|
|
68
|
+
return undefined;
|
|
69
|
+
const cursor = { ...this.cursor };
|
|
70
|
+
return this.availability === "ready"
|
|
71
|
+
? { kind: "snapshot", cursor, availability: "ready", roots: [...this.roots.values()] }
|
|
72
|
+
: { kind: "snapshot", cursor, availability: this.availability };
|
|
73
|
+
}
|
|
74
|
+
reset() {
|
|
75
|
+
this.cursor = undefined;
|
|
76
|
+
this.availability = "unavailable";
|
|
77
|
+
this.roots.clear();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=engine-workflow-activity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine-workflow-activity.js","sourceRoot":"","sources":["../../../src/modes/interactive-engine/engine-workflow-activity.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentSession } from \"../../core/agent-session.js\";\nimport type { WorkflowActivityFrame, WorkflowRootActivity } from \"../../core/extensions/workflow-events.js\";\nimport { serializeInteractiveEngineMessage } from \"./protocol.ts\";\n\nfunction withoutGraph({ graph: _graph, ...summary }: WorkflowRootActivity): WorkflowRootActivity {\n\treturn summary;\n}\n\n/**\n * Forward the engine's workflow activity to the host that owns the terminal. The host reports it as\n * program status, which needs each root's state and outcome but never its graph, so frames that\n * change only the graph are not sent.\n */\nexport function forwardWorkflowActivity(session: AgentSession, write: (line: string) => void): () => void {\n\tconst sent = new Map<string, string>();\n\tconst subscription = session.workflows.observe((frame) => {\n\t\tlet forward: WorkflowActivityFrame;\n\t\tif (frame.kind === \"snapshot\") {\n\t\t\tsent.clear();\n\t\t\tif (frame.availability !== \"ready\") {\n\t\t\t\tforward = frame;\n\t\t\t} else {\n\t\t\t\tconst roots = frame.roots.map(withoutGraph);\n\t\t\t\tfor (const root of roots) sent.set(root.rootRunId, JSON.stringify(root));\n\t\t\t\tforward = { ...frame, roots };\n\t\t\t}\n\t\t} else if (frame.kind === \"changed\") {\n\t\t\tconst root = withoutGraph(frame.root);\n\t\t\tconst key = JSON.stringify(root);\n\t\t\tif (sent.get(root.rootRunId) === key) return;\n\t\t\tsent.set(root.rootRunId, key);\n\t\t\tforward = { ...frame, root };\n\t\t} else {\n\t\t\tsent.delete(frame.rootRunId);\n\t\t\tforward = frame;\n\t\t}\n\t\twrite(serializeInteractiveEngineMessage({ type: \"engine_workflow_activity\", frame: forward }));\n\t});\n\treturn () => subscription.dispose();\n}\n\n/**\n * The host's view of the engine's workflow activity. The engine publishes its snapshot as soon as it\n * binds, which can be before the host attaches an observer, so the host keeps the frames folded into\n * one current snapshot and replays that to every observer that attaches later.\n */\nexport class WorkflowActivityMirror {\n\tprivate cursor: WorkflowActivityFrame[\"cursor\"] | undefined;\n\tprivate availability: \"ready\" | \"recovering\" | \"unavailable\" = \"unavailable\";\n\tprivate readonly roots = new Map<string, WorkflowRootActivity>();\n\n\tapply(frame: WorkflowActivityFrame): void {\n\t\tthis.cursor = frame.cursor;\n\t\tif (frame.kind === \"snapshot\") {\n\t\t\tthis.availability = frame.availability;\n\t\t\tthis.roots.clear();\n\t\t\tif (frame.availability === \"ready\") for (const root of frame.roots) this.roots.set(root.rootRunId, root);\n\t\t} else if (frame.kind === \"changed\") this.roots.set(frame.root.rootRunId, frame.root);\n\t\telse this.roots.delete(frame.rootRunId);\n\t}\n\n\t/** The snapshot a late observer starts from; absent until the engine published something. */\n\tcurrent(): WorkflowActivityFrame | undefined {\n\t\tif (!this.cursor) return undefined;\n\t\tconst cursor = { ...this.cursor };\n\t\treturn this.availability === \"ready\"\n\t\t\t? { kind: \"snapshot\", cursor, availability: \"ready\", roots: [...this.roots.values()] }\n\t\t\t: { kind: \"snapshot\", cursor, availability: this.availability };\n\t}\n\n\treset(): void {\n\t\tthis.cursor = undefined;\n\t\tthis.availability = \"unavailable\";\n\t\tthis.roots.clear();\n\t}\n}\n"]}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import type { AgentSession } from "../../core/agent-session.js";
|
|
1
2
|
import type { AgentSessionRuntime } from "../../core/agent-session-runtime.ts";
|
|
2
3
|
import type { ResourceOverlap } from "../../core/diagnostics.ts";
|
|
3
4
|
import type { ExtensionUIContext } from "../../core/extensions/index.js";
|
|
5
|
+
import type { WorkflowActivityFrame } from "../../core/extensions/workflow-events.js";
|
|
4
6
|
import type { KeybindingsManager } from "../../core/keybindings.ts";
|
|
5
7
|
import type { RpcAutocompleteItem, RpcResourceExtension, RpcSlashCommand } from "../rpc/rpc-types.ts";
|
|
6
8
|
import type { ActivityWatchdogDiagnostic } from "./activity-watchdog.ts";
|
|
@@ -11,7 +13,12 @@ interface EngineMessageSource {
|
|
|
11
13
|
onKeybindingState?(listener: (state: EngineKeybindingState) => void): () => void;
|
|
12
14
|
}
|
|
13
15
|
export declare function attachInteractiveEngineKeybindingSync(runtime: EngineMessageSource, keybindings: KeybindingsManager, onState?: (state: EngineKeybindingState) => void): () => void;
|
|
14
|
-
export declare function attachInteractiveEngineHost(runtime: AgentSessionRuntime, ui: ExtensionUIContext, onDiagnostic: (diagnostic: ActivityWatchdogDiagnostic) => void, tuiRendererLifecycle: TuiRendererLifecycle, setShortcutHandler?: (handler: (data: string) => boolean) => undefined | (() => void), keybindings?: KeybindingsManager): () => void;
|
|
16
|
+
export declare function attachInteractiveEngineHost(runtime: AgentSessionRuntime, ui: ExtensionUIContext, onDiagnostic: (diagnostic: ActivityWatchdogDiagnostic) => void, tuiRendererLifecycle: TuiRendererLifecycle, setShortcutHandler?: (handler: (data: string) => boolean) => undefined | (() => void), keybindings?: KeybindingsManager, onWorkflowActivity?: (frame: WorkflowActivityFrame) => void): () => void;
|
|
17
|
+
/**
|
|
18
|
+
* Observe workflow activity of a session whose extensions run in this process. An isolated host
|
|
19
|
+
* receives it from its engine child instead (see `attachInteractiveEngineHost`).
|
|
20
|
+
*/
|
|
21
|
+
export declare function observeLocalWorkflowActivity(runtime: AgentSessionRuntime, session: AgentSession, observer: (frame: WorkflowActivityFrame) => void): () => void;
|
|
15
22
|
/** Route host-owned trust waits to the runner that actually owns the subscribers. */
|
|
16
23
|
export declare function withHostProjectTrustPrompt<T>(runtime: AgentSessionRuntime, kind: "select" | "confirm" | "input", title: string, run: () => Promise<T>): Promise<T>;
|
|
17
24
|
export declare function waitForInteractiveEngineBound(runtime: AgentSessionRuntime): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension-ui-bridge.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive-engine/extension-ui-bridge.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC/E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtG,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAIzE,OAAO,KAAK,EAA2B,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAC9G,OAAO,EAA6B,KAAK,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAI7F,UAAU,mBAAmB;IAC5B,eAAe,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,wBAAwB,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IACnF,iBAAiB,CAAC,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CACjF;AAED,wBAAgB,qCAAqC,CACpD,OAAO,EAAE,mBAAmB,EAC5B,WAAW,EAAE,kBAAkB,EAC/B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,GAC9C,MAAM,IAAI,CASZ;AAED,wBAAgB,2BAA2B,CAC1C,OAAO,EAAE,mBAAmB,EAC5B,EAAE,EAAE,kBAAkB,EACtB,YAAY,EAAE,CAAC,UAAU,EAAE,0BAA0B,KAAK,IAAI,EAC9D,oBAAoB,EAAE,oBAAoB,EAC1C,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,KAAK,SAAS,GAAG,CAAC,MAAM,IAAI,CAAC,EACrF,WAAW,CAAC,EAAE,kBAAkB,
|
|
1
|
+
{"version":3,"file":"extension-ui-bridge.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive-engine/extension-ui-bridge.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,10 +17,13 @@ export function attachInteractiveEngineKeybindingSync(runtime, keybindings, onSt
|
|
|
17
17
|
applyState(message.state);
|
|
18
18
|
});
|
|
19
19
|
}
|
|
20
|
-
export function attachInteractiveEngineHost(runtime, ui, onDiagnostic, tuiRendererLifecycle, setShortcutHandler, keybindings) {
|
|
20
|
+
export function attachInteractiveEngineHost(runtime, ui, onDiagnostic, tuiRendererLifecycle, setShortcutHandler, keybindings, onWorkflowActivity) {
|
|
21
21
|
if (!(runtime instanceof IsolatedInteractiveRuntime))
|
|
22
22
|
return () => { };
|
|
23
23
|
const disposeDiagnostic = runtime.onDiagnostic(onDiagnostic);
|
|
24
|
+
const disposeWorkflowActivity = onWorkflowActivity
|
|
25
|
+
? observeEngineWorkflowActivity(runtime, onWorkflowActivity)
|
|
26
|
+
: () => { };
|
|
24
27
|
// Generation-owned: RPC dialogs mount real host components and must not
|
|
25
28
|
// outlive, or answer through, a replacement engine child.
|
|
26
29
|
const dialogs = new EngineDialogHostController(runtime, ui);
|
|
@@ -64,6 +67,7 @@ export function attachInteractiveEngineHost(runtime, ui, onDiagnostic, tuiRender
|
|
|
64
67
|
disposed = true;
|
|
65
68
|
disposeShortcutHandler?.();
|
|
66
69
|
disposeKeybindings();
|
|
70
|
+
disposeWorkflowActivity();
|
|
67
71
|
disposeOwnership();
|
|
68
72
|
remoteComponents.dispose();
|
|
69
73
|
sessionPicker.dispose();
|
|
@@ -72,6 +76,32 @@ export function attachInteractiveEngineHost(runtime, ui, onDiagnostic, tuiRender
|
|
|
72
76
|
disposeDiagnostic();
|
|
73
77
|
};
|
|
74
78
|
}
|
|
79
|
+
const unavailableWorkflowActivity = {
|
|
80
|
+
kind: "snapshot",
|
|
81
|
+
cursor: { epoch: "", revision: 0 },
|
|
82
|
+
availability: "unavailable",
|
|
83
|
+
};
|
|
84
|
+
/** The engine child owns the workflow runs; a dead generation's runs are gone with it. */
|
|
85
|
+
function observeEngineWorkflowActivity(runtime, observer) {
|
|
86
|
+
// The runtime replays the engine's current snapshot: the engine published it at bind time, which can
|
|
87
|
+
// be long before this observer attaches.
|
|
88
|
+
const disposeMessages = runtime.onWorkflowActivity(observer);
|
|
89
|
+
const disposeEnded = runtime.onGenerationEnded(() => observer(unavailableWorkflowActivity));
|
|
90
|
+
return () => {
|
|
91
|
+
disposeMessages();
|
|
92
|
+
disposeEnded();
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Observe workflow activity of a session whose extensions run in this process. An isolated host
|
|
97
|
+
* receives it from its engine child instead (see `attachInteractiveEngineHost`).
|
|
98
|
+
*/
|
|
99
|
+
export function observeLocalWorkflowActivity(runtime, session, observer) {
|
|
100
|
+
if (runtime instanceof IsolatedInteractiveRuntime)
|
|
101
|
+
return () => { };
|
|
102
|
+
const subscription = session.workflows.observe(observer);
|
|
103
|
+
return () => subscription.dispose();
|
|
104
|
+
}
|
|
75
105
|
/** Route host-owned trust waits to the runner that actually owns the subscribers. */
|
|
76
106
|
export function withHostProjectTrustPrompt(runtime, kind, title, run) {
|
|
77
107
|
return runtime instanceof IsolatedInteractiveRuntime
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension-ui-bridge.js","sourceRoot":"","sources":["../../../src/modes/interactive-engine/extension-ui-bridge.ts"],"names":[],"mappings":"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","sourcesContent":["import { type KeyId, matchesKey } from \"@earendil-works/pi-tui\";\nimport type { AgentSessionRuntime } from \"../../core/agent-session-runtime.ts\";\nimport type { ResourceOverlap } from \"../../core/diagnostics.ts\";\nimport type { ExtensionUIContext } from \"../../core/extensions/index.js\";\nimport type { KeybindingsManager } from \"../../core/keybindings.ts\";\nimport type { RpcAutocompleteItem, RpcResourceExtension, RpcSlashCommand } from \"../rpc/rpc-types.ts\";\nimport type { ActivityWatchdogDiagnostic } from \"./activity-watchdog.ts\";\nimport { EngineDialogHostController } from \"./engine-dialog-host.ts\";\nimport { InputFormHostController } from \"./input-form-host.ts\";\nimport { IsolatedInteractiveRuntime } from \"./isolated-runtime.js\";\nimport type { EngineExtensionShortcut, EngineKeybindingState, InteractiveEngineMessage } from \"./protocol.ts\";\nimport { RemoteComponentController, type TuiRendererLifecycle } from \"./remote-component.ts\";\nimport { registerRemoteProxyOwnership } from \"./remote-input-ownership.ts\";\nimport { SessionPickerHostController } from \"./session-picker-host.ts\";\n\ninterface EngineMessageSource {\n\tonEngineMessage(listener: (message: InteractiveEngineMessage) => void): () => void;\n\tonKeybindingState?(listener: (state: EngineKeybindingState) => void): () => void;\n}\n\nexport function attachInteractiveEngineKeybindingSync(\n\truntime: EngineMessageSource,\n\tkeybindings: KeybindingsManager,\n\tonState?: (state: EngineKeybindingState) => void,\n): () => void {\n\tconst applyState = (state: EngineKeybindingState): void => {\n\t\tkeybindings.setUserBindings(state.userBindings);\n\t\tonState?.(state);\n\t};\n\tif (runtime.onKeybindingState) return runtime.onKeybindingState(applyState);\n\treturn runtime.onEngineMessage((message) => {\n\t\tif (message.type === \"engine_keybindings_reloaded\") applyState(message.state);\n\t});\n}\n\nexport function attachInteractiveEngineHost(\n\truntime: AgentSessionRuntime,\n\tui: ExtensionUIContext,\n\tonDiagnostic: (diagnostic: ActivityWatchdogDiagnostic) => void,\n\ttuiRendererLifecycle: TuiRendererLifecycle,\n\tsetShortcutHandler?: (handler: (data: string) => boolean) => undefined | (() => void),\n\tkeybindings?: KeybindingsManager,\n): () => void {\n\tif (!(runtime instanceof IsolatedInteractiveRuntime)) return () => {};\n\tconst disposeDiagnostic = runtime.onDiagnostic(onDiagnostic);\n\t// Generation-owned: RPC dialogs mount real host components and must not\n\t// outlive, or answer through, a replacement engine child.\n\tconst dialogs = new EngineDialogHostController(runtime, ui);\n\tlet shortcuts: EngineExtensionShortcut[] = [];\n\tconst dispatchShortcut = (data: string): boolean => {\n\t\tconst shortcut = shortcuts.find(\n\t\t\t({ key, editorKeys }) =>\n\t\t\t\tmatchesKey(data, key as KeyId) && !editorKeys?.some((editorKey) => matchesKey(data, editorKey)),\n\t\t);\n\t\tif (!shortcut) return false;\n\t\tvoid runtime\n\t\t\t.invokeRemoteShortcut(shortcut.key)\n\t\t\t.catch((error: Error) =>\n\t\t\t\tonDiagnostic({ activity: undefined, elapsedMs: 0, level: \"unresponsive\", message: error.message }),\n\t\t\t);\n\t\treturn true;\n\t};\n\tlet disposeShortcutHandler: (() => void) | undefined;\n\tconst installShortcutHandler = (): void => {\n\t\tdisposeShortcutHandler?.();\n\t\tconst dispose = setShortcutHandler?.(dispatchShortcut);\n\t\tdisposeShortcutHandler = typeof dispose === \"function\" ? dispose : undefined;\n\t};\n\tconst applyState = (state: EngineKeybindingState): void => {\n\t\tshortcuts = [...state.shortcuts];\n\t\tinstallShortcutHandler();\n\t};\n\tinstallShortcutHandler();\n\tconst disposeKeybindings = keybindings\n\t\t? attachInteractiveEngineKeybindingSync(runtime, keybindings, applyState)\n\t\t: runtime.onEngineMessage((message) => {\n\t\t\t\tif (message.type === \"engine_keybindings_reloaded\") applyState(message.state);\n\t\t\t});\n\tconst remoteComponents = new RemoteComponentController(runtime, ui, tuiRendererLifecycle);\n\t// Ctrl+C must reach the host while a remote proxy owns input, so publish the\n\t// only component that can answer that question exactly.\n\tconst disposeOwnership = registerRemoteProxyOwnership(runtime, remoteComponents);\n\tconst sessionPicker = new SessionPickerHostController(runtime, ui);\n\tconst inputForm = new InputFormHostController(runtime, ui);\n\tlet disposed = false;\n\treturn () => {\n\t\tif (disposed) return;\n\t\tdisposed = true;\n\t\tdisposeShortcutHandler?.();\n\t\tdisposeKeybindings();\n\t\tdisposeOwnership();\n\t\tremoteComponents.dispose();\n\t\tsessionPicker.dispose();\n\t\tinputForm.dispose();\n\t\tdialogs.dispose();\n\t\tdisposeDiagnostic();\n\t};\n}\n\n/** Route host-owned trust waits to the runner that actually owns the subscribers. */\nexport function withHostProjectTrustPrompt<T>(\n\truntime: AgentSessionRuntime,\n\tkind: \"select\" | \"confirm\" | \"input\",\n\ttitle: string,\n\trun: () => Promise<T>,\n): Promise<T> {\n\treturn runtime instanceof IsolatedInteractiveRuntime\n\t\t? runtime.withProjectTrustPrompt(kind, title, run)\n\t\t: runtime.session.extensionRunner.withProjectTrustPrompt(kind, title, run);\n}\n\nexport async function waitForInteractiveEngineBound(runtime: AgentSessionRuntime): Promise<void> {\n\tif (!(runtime instanceof IsolatedInteractiveRuntime)) return;\n\tawait runtime.waitUntilBound();\n\tawait runtime.initializeFromEngine();\n}\n\nexport async function waitForInteractiveEngineProjectTrust(runtime: AgentSessionRuntime): Promise<void> {\n\tif (!(runtime instanceof IsolatedInteractiveRuntime)) return;\n\tawait runtime.waitUntilProjectTrustSettled();\n}\n\nexport function interruptBlockedInteractiveEngine(runtime: AgentSessionRuntime): boolean {\n\treturn runtime instanceof IsolatedInteractiveRuntime && runtime.interruptBlockedCallback();\n}\n\n/**\n * True when the interactive engine still owes a cooperative abort or the\n * heartbeat watchdog has declared it unresponsive, i.e. when the explicit\n * Ctrl+C escape hatch promised by the watchdog copy applies.\n */\nexport function interactiveEngineNeedsExplicitTermination(runtime: AgentSessionRuntime): boolean {\n\treturn runtime instanceof IsolatedInteractiveRuntime && runtime.needsExplicitTermination();\n}\n\n/**\n * Explicitly terminate an unresponsive interactive engine and start recovery.\n * Only ever reached from a deliberate user action (Ctrl+C) — never from Escape.\n */\nexport function terminateInteractiveEngine(runtime: AgentSessionRuntime): boolean {\n\tif (!interactiveEngineNeedsExplicitTermination(runtime)) return false;\n\tvoid (runtime as IsolatedInteractiveRuntime).terminateAndRecover();\n\treturn true;\n}\n\n/**\n * Command catalog the engine child exposes to the isolated host. Returns an\n * empty list for non-isolated runtimes so callers can merge unconditionally.\n */\nexport function getInteractiveEngineRemoteCommands(runtime: AgentSessionRuntime): readonly RpcSlashCommand[] {\n\treturn runtime instanceof IsolatedInteractiveRuntime ? runtime.getRemoteCommands() : [];\n}\n\nexport function getInteractiveEngineResourceOverlaps(runtime: AgentSessionRuntime): readonly ResourceOverlap[] {\n\treturn runtime instanceof IsolatedInteractiveRuntime ? runtime.getResourceOverlaps() : [];\n}\n\nexport function getInteractiveEngineResourceExtensions(runtime: AgentSessionRuntime): readonly RpcResourceExtension[] {\n\treturn runtime instanceof IsolatedInteractiveRuntime ? runtime.getResourceExtensions() : [];\n}\n\nexport function onInteractiveEngineResourceExtensionsChanged(\n\truntime: AgentSessionRuntime,\n\tlistener: (extensions: readonly RpcResourceExtension[]) => void,\n): () => void {\n\treturn runtime instanceof IsolatedInteractiveRuntime ? runtime.onResourceExtensionsChanged(listener) : () => {};\n}\n\n/** Evaluate an engine-child command's live argument completions. */\nexport function getInteractiveEngineRemoteCommandCompletions(\n\truntime: AgentSessionRuntime,\n\tcommandName: string,\n\targumentPrefix: string,\n): Promise<RpcAutocompleteItem[] | null> {\n\treturn runtime instanceof IsolatedInteractiveRuntime\n\t\t? runtime.getRemoteCommandCompletions(commandName, argumentPrefix)\n\t\t: Promise.resolve(null);\n}\n\n/** Subscribe to engine-child command catalog changes. No-op when not isolated. */\nexport function onInteractiveEngineRemoteCommandsChanged(\n\truntime: AgentSessionRuntime,\n\tlistener: (commands: readonly RpcSlashCommand[]) => void,\n): () => void {\n\treturn runtime instanceof IsolatedInteractiveRuntime ? runtime.onRemoteCommandsChanged(listener) : () => {};\n}\n\n/** Subscribe to fresh engine session stats, so the footer can repaint. No-op when not isolated. */\nexport function onInteractiveEngineSessionStatsChanged(runtime: AgentSessionRuntime, listener: () => void): () => void {\n\treturn runtime instanceof IsolatedInteractiveRuntime ? runtime.onSessionStatsChanged(listener) : () => {};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"extension-ui-bridge.js","sourceRoot":"","sources":["../../../src/modes/interactive-engine/extension-ui-bridge.ts"],"names":[],"mappings":"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","sourcesContent":["import { type KeyId, matchesKey } from \"@earendil-works/pi-tui\";\nimport type { AgentSession } from \"../../core/agent-session.js\";\nimport type { AgentSessionRuntime } from \"../../core/agent-session-runtime.ts\";\nimport type { ResourceOverlap } from \"../../core/diagnostics.ts\";\nimport type { ExtensionUIContext } from \"../../core/extensions/index.js\";\nimport type { WorkflowActivityFrame } from \"../../core/extensions/workflow-events.js\";\nimport type { KeybindingsManager } from \"../../core/keybindings.ts\";\nimport type { RpcAutocompleteItem, RpcResourceExtension, RpcSlashCommand } from \"../rpc/rpc-types.ts\";\nimport type { ActivityWatchdogDiagnostic } from \"./activity-watchdog.ts\";\nimport { EngineDialogHostController } from \"./engine-dialog-host.ts\";\nimport { InputFormHostController } from \"./input-form-host.ts\";\nimport { IsolatedInteractiveRuntime } from \"./isolated-runtime.js\";\nimport type { EngineExtensionShortcut, EngineKeybindingState, InteractiveEngineMessage } from \"./protocol.ts\";\nimport { RemoteComponentController, type TuiRendererLifecycle } from \"./remote-component.ts\";\nimport { registerRemoteProxyOwnership } from \"./remote-input-ownership.ts\";\nimport { SessionPickerHostController } from \"./session-picker-host.ts\";\n\ninterface EngineMessageSource {\n\tonEngineMessage(listener: (message: InteractiveEngineMessage) => void): () => void;\n\tonKeybindingState?(listener: (state: EngineKeybindingState) => void): () => void;\n}\n\nexport function attachInteractiveEngineKeybindingSync(\n\truntime: EngineMessageSource,\n\tkeybindings: KeybindingsManager,\n\tonState?: (state: EngineKeybindingState) => void,\n): () => void {\n\tconst applyState = (state: EngineKeybindingState): void => {\n\t\tkeybindings.setUserBindings(state.userBindings);\n\t\tonState?.(state);\n\t};\n\tif (runtime.onKeybindingState) return runtime.onKeybindingState(applyState);\n\treturn runtime.onEngineMessage((message) => {\n\t\tif (message.type === \"engine_keybindings_reloaded\") applyState(message.state);\n\t});\n}\n\nexport function attachInteractiveEngineHost(\n\truntime: AgentSessionRuntime,\n\tui: ExtensionUIContext,\n\tonDiagnostic: (diagnostic: ActivityWatchdogDiagnostic) => void,\n\ttuiRendererLifecycle: TuiRendererLifecycle,\n\tsetShortcutHandler?: (handler: (data: string) => boolean) => undefined | (() => void),\n\tkeybindings?: KeybindingsManager,\n\tonWorkflowActivity?: (frame: WorkflowActivityFrame) => void,\n): () => void {\n\tif (!(runtime instanceof IsolatedInteractiveRuntime)) return () => {};\n\tconst disposeDiagnostic = runtime.onDiagnostic(onDiagnostic);\n\tconst disposeWorkflowActivity = onWorkflowActivity\n\t\t? observeEngineWorkflowActivity(runtime, onWorkflowActivity)\n\t\t: () => {};\n\t// Generation-owned: RPC dialogs mount real host components and must not\n\t// outlive, or answer through, a replacement engine child.\n\tconst dialogs = new EngineDialogHostController(runtime, ui);\n\tlet shortcuts: EngineExtensionShortcut[] = [];\n\tconst dispatchShortcut = (data: string): boolean => {\n\t\tconst shortcut = shortcuts.find(\n\t\t\t({ key, editorKeys }) =>\n\t\t\t\tmatchesKey(data, key as KeyId) && !editorKeys?.some((editorKey) => matchesKey(data, editorKey)),\n\t\t);\n\t\tif (!shortcut) return false;\n\t\tvoid runtime\n\t\t\t.invokeRemoteShortcut(shortcut.key)\n\t\t\t.catch((error: Error) =>\n\t\t\t\tonDiagnostic({ activity: undefined, elapsedMs: 0, level: \"unresponsive\", message: error.message }),\n\t\t\t);\n\t\treturn true;\n\t};\n\tlet disposeShortcutHandler: (() => void) | undefined;\n\tconst installShortcutHandler = (): void => {\n\t\tdisposeShortcutHandler?.();\n\t\tconst dispose = setShortcutHandler?.(dispatchShortcut);\n\t\tdisposeShortcutHandler = typeof dispose === \"function\" ? dispose : undefined;\n\t};\n\tconst applyState = (state: EngineKeybindingState): void => {\n\t\tshortcuts = [...state.shortcuts];\n\t\tinstallShortcutHandler();\n\t};\n\tinstallShortcutHandler();\n\tconst disposeKeybindings = keybindings\n\t\t? attachInteractiveEngineKeybindingSync(runtime, keybindings, applyState)\n\t\t: runtime.onEngineMessage((message) => {\n\t\t\t\tif (message.type === \"engine_keybindings_reloaded\") applyState(message.state);\n\t\t\t});\n\tconst remoteComponents = new RemoteComponentController(runtime, ui, tuiRendererLifecycle);\n\t// Ctrl+C must reach the host while a remote proxy owns input, so publish the\n\t// only component that can answer that question exactly.\n\tconst disposeOwnership = registerRemoteProxyOwnership(runtime, remoteComponents);\n\tconst sessionPicker = new SessionPickerHostController(runtime, ui);\n\tconst inputForm = new InputFormHostController(runtime, ui);\n\tlet disposed = false;\n\treturn () => {\n\t\tif (disposed) return;\n\t\tdisposed = true;\n\t\tdisposeShortcutHandler?.();\n\t\tdisposeKeybindings();\n\t\tdisposeWorkflowActivity();\n\t\tdisposeOwnership();\n\t\tremoteComponents.dispose();\n\t\tsessionPicker.dispose();\n\t\tinputForm.dispose();\n\t\tdialogs.dispose();\n\t\tdisposeDiagnostic();\n\t};\n}\n\nconst unavailableWorkflowActivity: WorkflowActivityFrame = {\n\tkind: \"snapshot\",\n\tcursor: { epoch: \"\", revision: 0 },\n\tavailability: \"unavailable\",\n};\n\n/** The engine child owns the workflow runs; a dead generation's runs are gone with it. */\nfunction observeEngineWorkflowActivity(\n\truntime: IsolatedInteractiveRuntime,\n\tobserver: (frame: WorkflowActivityFrame) => void,\n): () => void {\n\t// The runtime replays the engine's current snapshot: the engine published it at bind time, which can\n\t// be long before this observer attaches.\n\tconst disposeMessages = runtime.onWorkflowActivity(observer);\n\tconst disposeEnded = runtime.onGenerationEnded(() => observer(unavailableWorkflowActivity));\n\treturn () => {\n\t\tdisposeMessages();\n\t\tdisposeEnded();\n\t};\n}\n\n/**\n * Observe workflow activity of a session whose extensions run in this process. An isolated host\n * receives it from its engine child instead (see `attachInteractiveEngineHost`).\n */\nexport function observeLocalWorkflowActivity(\n\truntime: AgentSessionRuntime,\n\tsession: AgentSession,\n\tobserver: (frame: WorkflowActivityFrame) => void,\n): () => void {\n\tif (runtime instanceof IsolatedInteractiveRuntime) return () => {};\n\tconst subscription = session.workflows.observe(observer);\n\treturn () => subscription.dispose();\n}\n\n/** Route host-owned trust waits to the runner that actually owns the subscribers. */\nexport function withHostProjectTrustPrompt<T>(\n\truntime: AgentSessionRuntime,\n\tkind: \"select\" | \"confirm\" | \"input\",\n\ttitle: string,\n\trun: () => Promise<T>,\n): Promise<T> {\n\treturn runtime instanceof IsolatedInteractiveRuntime\n\t\t? runtime.withProjectTrustPrompt(kind, title, run)\n\t\t: runtime.session.extensionRunner.withProjectTrustPrompt(kind, title, run);\n}\n\nexport async function waitForInteractiveEngineBound(runtime: AgentSessionRuntime): Promise<void> {\n\tif (!(runtime instanceof IsolatedInteractiveRuntime)) return;\n\tawait runtime.waitUntilBound();\n\tawait runtime.initializeFromEngine();\n}\n\nexport async function waitForInteractiveEngineProjectTrust(runtime: AgentSessionRuntime): Promise<void> {\n\tif (!(runtime instanceof IsolatedInteractiveRuntime)) return;\n\tawait runtime.waitUntilProjectTrustSettled();\n}\n\nexport function interruptBlockedInteractiveEngine(runtime: AgentSessionRuntime): boolean {\n\treturn runtime instanceof IsolatedInteractiveRuntime && runtime.interruptBlockedCallback();\n}\n\n/**\n * True when the interactive engine still owes a cooperative abort or the\n * heartbeat watchdog has declared it unresponsive, i.e. when the explicit\n * Ctrl+C escape hatch promised by the watchdog copy applies.\n */\nexport function interactiveEngineNeedsExplicitTermination(runtime: AgentSessionRuntime): boolean {\n\treturn runtime instanceof IsolatedInteractiveRuntime && runtime.needsExplicitTermination();\n}\n\n/**\n * Explicitly terminate an unresponsive interactive engine and start recovery.\n * Only ever reached from a deliberate user action (Ctrl+C) — never from Escape.\n */\nexport function terminateInteractiveEngine(runtime: AgentSessionRuntime): boolean {\n\tif (!interactiveEngineNeedsExplicitTermination(runtime)) return false;\n\tvoid (runtime as IsolatedInteractiveRuntime).terminateAndRecover();\n\treturn true;\n}\n\n/**\n * Command catalog the engine child exposes to the isolated host. Returns an\n * empty list for non-isolated runtimes so callers can merge unconditionally.\n */\nexport function getInteractiveEngineRemoteCommands(runtime: AgentSessionRuntime): readonly RpcSlashCommand[] {\n\treturn runtime instanceof IsolatedInteractiveRuntime ? runtime.getRemoteCommands() : [];\n}\n\nexport function getInteractiveEngineResourceOverlaps(runtime: AgentSessionRuntime): readonly ResourceOverlap[] {\n\treturn runtime instanceof IsolatedInteractiveRuntime ? runtime.getResourceOverlaps() : [];\n}\n\nexport function getInteractiveEngineResourceExtensions(runtime: AgentSessionRuntime): readonly RpcResourceExtension[] {\n\treturn runtime instanceof IsolatedInteractiveRuntime ? runtime.getResourceExtensions() : [];\n}\n\nexport function onInteractiveEngineResourceExtensionsChanged(\n\truntime: AgentSessionRuntime,\n\tlistener: (extensions: readonly RpcResourceExtension[]) => void,\n): () => void {\n\treturn runtime instanceof IsolatedInteractiveRuntime ? runtime.onResourceExtensionsChanged(listener) : () => {};\n}\n\n/** Evaluate an engine-child command's live argument completions. */\nexport function getInteractiveEngineRemoteCommandCompletions(\n\truntime: AgentSessionRuntime,\n\tcommandName: string,\n\targumentPrefix: string,\n): Promise<RpcAutocompleteItem[] | null> {\n\treturn runtime instanceof IsolatedInteractiveRuntime\n\t\t? runtime.getRemoteCommandCompletions(commandName, argumentPrefix)\n\t\t: Promise.resolve(null);\n}\n\n/** Subscribe to engine-child command catalog changes. No-op when not isolated. */\nexport function onInteractiveEngineRemoteCommandsChanged(\n\truntime: AgentSessionRuntime,\n\tlistener: (commands: readonly RpcSlashCommand[]) => void,\n): () => void {\n\treturn runtime instanceof IsolatedInteractiveRuntime ? runtime.onRemoteCommandsChanged(listener) : () => {};\n}\n\n/** Subscribe to fresh engine session stats, so the footer can repaint. No-op when not isolated. */\nexport function onInteractiveEngineSessionStatsChanged(runtime: AgentSessionRuntime, listener: () => void): () => void {\n\treturn runtime instanceof IsolatedInteractiveRuntime ? runtime.onSessionStatsChanged(listener) : () => {};\n}\n"]}
|
|
@@ -2,6 +2,7 @@ import type { AuthInteraction } from "@bastani/pi-ai";
|
|
|
2
2
|
import type { AgentSession } from "../../core/agent-session.js";
|
|
3
3
|
import { AgentSessionRuntime, type CreateAgentSessionRuntimeFactory } from "../../core/agent-session-runtime.ts";
|
|
4
4
|
import type { ResourceOverlap } from "../../core/diagnostics.ts";
|
|
5
|
+
import type { WorkflowActivityFrame } from "../../core/extensions/workflow-events.js";
|
|
5
6
|
import type { ToolStatusReport } from "../../core/tool-status.js";
|
|
6
7
|
import type { RpcClient } from "../rpc/rpc-client.ts";
|
|
7
8
|
import type { RpcAutocompleteItem, RpcExtensionUIRequest, RpcExtensionUIResponse, RpcResourceExtension, RpcSlashCommand } from "../rpc/rpc-types.ts";
|
|
@@ -75,6 +76,8 @@ export declare class IsolatedInteractiveRuntime extends AgentSessionRuntime {
|
|
|
75
76
|
/** Fires when fresh engine session stats arrive, so the host can repaint its footer. */
|
|
76
77
|
onSessionStatsChanged(listener: () => void): () => void;
|
|
77
78
|
onEngineMessage(listener: (message: InteractiveEngineMessage) => void): () => void;
|
|
79
|
+
/** Workflow activity of the engine child, starting from its current snapshot. */
|
|
80
|
+
onWorkflowActivity(listener: (frame: WorkflowActivityFrame) => void): () => void;
|
|
78
81
|
onKeybindingState(listener: (state: EngineKeybindingState) => void): () => void;
|
|
79
82
|
sendEngineCommand(command: InteractiveEngineCommand): void;
|
|
80
83
|
/** Report a native host trust dialog to the extension runner in this engine generation. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isolated-runtime.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive-engine/isolated-runtime.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtD,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,6BAA6B,CAAC;AAClF,OAAO,EAAE,mBAAmB,EAAE,KAAK,gCAAgC,EAAE,MAAM,qCAAqC,CAAC;AAEjH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"isolated-runtime.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive-engine/isolated-runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -242,6 +242,10 @@ export class IsolatedInteractiveRuntime extends AgentSessionRuntime {
|
|
|
242
242
|
onEngineMessage(listener) {
|
|
243
243
|
return this.client.onInteractiveEngineMessage(listener);
|
|
244
244
|
}
|
|
245
|
+
/** Workflow activity of the engine child, starting from its current snapshot. */
|
|
246
|
+
onWorkflowActivity(listener) {
|
|
247
|
+
return this.client.onInteractiveEngineWorkflowActivity(listener);
|
|
248
|
+
}
|
|
245
249
|
onKeybindingState(listener) {
|
|
246
250
|
return this.client.onInteractiveEngineKeybindingState(listener);
|
|
247
251
|
}
|