@caupulican/pi-adaptative 0.93.17 → 0.93.19
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 +23 -0
- package/dist/core/agent-session.d.ts +1 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +22 -12
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction-controller.d.ts +22 -0
- package/dist/core/compaction-controller.d.ts.map +1 -1
- package/dist/core/compaction-controller.js +191 -30
- package/dist/core/compaction-controller.js.map +1 -1
- package/dist/core/compaction-support.d.ts.map +1 -1
- package/dist/core/compaction-support.js +21 -1
- package/dist/core/compaction-support.js.map +1 -1
- package/dist/core/delegation/worker-agent-control-coordinator.d.ts.map +1 -1
- package/dist/core/delegation/worker-agent-control-coordinator.js +1 -0
- package/dist/core/delegation/worker-agent-control-coordinator.js.map +1 -1
- package/dist/core/delegation/worker-agent-control.d.ts +2 -0
- package/dist/core/delegation/worker-agent-control.d.ts.map +1 -1
- package/dist/core/delegation/worker-agent-control.js.map +1 -1
- package/dist/core/foreground-lifecycle-adapter.d.ts +27 -0
- package/dist/core/foreground-lifecycle-adapter.d.ts.map +1 -0
- package/dist/core/foreground-lifecycle-adapter.js +61 -0
- package/dist/core/foreground-lifecycle-adapter.js.map +1 -0
- package/dist/core/foreground-lifecycle-controller.d.ts +48 -0
- package/dist/core/foreground-lifecycle-controller.d.ts.map +1 -0
- package/dist/core/foreground-lifecycle-controller.js +404 -0
- package/dist/core/foreground-lifecycle-controller.js.map +1 -0
- package/dist/core/foreground-recovery-controller.d.ts +3 -0
- package/dist/core/foreground-recovery-controller.d.ts.map +1 -1
- package/dist/core/foreground-recovery-controller.js +15 -1
- package/dist/core/foreground-recovery-controller.js.map +1 -1
- package/dist/core/goals/goal-state.d.ts.map +1 -1
- package/dist/core/goals/goal-state.js +9 -2
- package/dist/core/goals/goal-state.js.map +1 -1
- package/dist/core/keybindings.d.ts +2 -2
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +2 -2
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/memory/memory-manager.d.ts +22 -0
- package/dist/core/memory/memory-manager.d.ts.map +1 -1
- package/dist/core/memory/memory-manager.js +108 -49
- package/dist/core/memory/memory-manager.js.map +1 -1
- package/dist/core/model-router/session-buffer.d.ts +10 -2
- package/dist/core/model-router/session-buffer.d.ts.map +1 -1
- package/dist/core/model-router/session-buffer.js +35 -9
- package/dist/core/model-router/session-buffer.js.map +1 -1
- package/dist/core/model-router-controller.d.ts +20 -2
- package/dist/core/model-router-controller.d.ts.map +1 -1
- package/dist/core/model-router-controller.js +70 -17
- package/dist/core/model-router-controller.js.map +1 -1
- package/dist/core/provider-request-runtime-controller.d.ts +12 -1
- package/dist/core/provider-request-runtime-controller.d.ts.map +1 -1
- package/dist/core/provider-request-runtime-controller.js +45 -2
- package/dist/core/provider-request-runtime-controller.js.map +1 -1
- package/dist/core/settings-manager.d.ts +1 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +3 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/tools/delegate.d.ts.map +1 -1
- package/dist/core/tools/delegate.js +4 -2
- package/dist/core/tools/delegate.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts +1 -3
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +10 -20
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/tool-group.d.ts +3 -0
- package/dist/modes/interactive/components/tool-group.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-group.js +25 -0
- package/dist/modes/interactive/components/tool-group.js.map +1 -1
- package/dist/modes/interactive/components/transcript-overlay.d.ts +13 -0
- package/dist/modes/interactive/components/transcript-overlay.d.ts.map +1 -0
- package/dist/modes/interactive/components/transcript-overlay.js +35 -0
- package/dist/modes/interactive/components/transcript-overlay.js.map +1 -0
- package/dist/modes/interactive/components/tree-selector.d.ts +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +7 -4
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-event-controller.d.ts +1 -1
- package/dist/modes/interactive/interactive-event-controller.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-event-controller.js +2 -1
- package/dist/modes/interactive/interactive-event-controller.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +9 -7
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +70 -99
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/runtime-status-controller.d.ts +40 -0
- package/dist/modes/interactive/runtime-status-controller.d.ts.map +1 -0
- package/dist/modes/interactive/runtime-status-controller.js +147 -0
- package/dist/modes/interactive/runtime-status-controller.js.map +1 -0
- package/dist/modes/interactive/runtime-status.d.ts +15 -0
- package/dist/modes/interactive/runtime-status.d.ts.map +1 -0
- package/dist/modes/interactive/runtime-status.js +18 -0
- package/dist/modes/interactive/runtime-status.js.map +1 -0
- package/docs/json.md +1 -1
- package/docs/keybindings.md +2 -1
- package/docs/session-format.md +59 -4
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +12 -12
- package/package.json +4 -4
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { AssistantMessage } from "@caupulican/pi-ai";
|
|
2
|
+
import { type Container, Loader, type LoaderIndicatorOptions, type TUI } from "@caupulican/pi-tui";
|
|
3
|
+
import type { ActivityLaneComponent } from "./components/activity-lane.ts";
|
|
4
|
+
export interface RuntimeStatusControllerHost {
|
|
5
|
+
readonly ui: TUI;
|
|
6
|
+
readonly statusContainer: Container;
|
|
7
|
+
readonly activityLane: ActivityLaneComponent | undefined;
|
|
8
|
+
readonly hasHumanAudience: boolean;
|
|
9
|
+
isStreaming(): boolean;
|
|
10
|
+
isThinkingHidden(): boolean;
|
|
11
|
+
}
|
|
12
|
+
/** Owns the human-facing turn indicator and its loader/activity-lane lifecycle. */
|
|
13
|
+
export declare class RuntimeStatusController {
|
|
14
|
+
private readonly host;
|
|
15
|
+
private activeLoader;
|
|
16
|
+
private workingMessage;
|
|
17
|
+
private workingVisible;
|
|
18
|
+
private workingIndicatorOptions;
|
|
19
|
+
private readonly defaultWorkingMessage;
|
|
20
|
+
private readonly defaultHiddenThinkingLabel;
|
|
21
|
+
private hiddenThinkingLabel;
|
|
22
|
+
private runtimeStatusLabel;
|
|
23
|
+
constructor(host: RuntimeStatusControllerHost);
|
|
24
|
+
get loadingAnimation(): Loader | undefined;
|
|
25
|
+
set loadingAnimation(value: Loader | undefined);
|
|
26
|
+
get isWorkingVisible(): boolean;
|
|
27
|
+
set isWorkingVisible(value: boolean);
|
|
28
|
+
get indicatorOptions(): LoaderIndicatorOptions | undefined;
|
|
29
|
+
set indicatorOptions(value: LoaderIndicatorOptions | undefined);
|
|
30
|
+
getWorkingLoaderMessage(): string;
|
|
31
|
+
createWorkingLoader(): Loader;
|
|
32
|
+
stopWorkingLoader(): void;
|
|
33
|
+
setWorkingVisible(visible: boolean): void;
|
|
34
|
+
setWorkingIndicator(options?: LoaderIndicatorOptions): void;
|
|
35
|
+
setHiddenThinkingLabel(label?: string): void;
|
|
36
|
+
updateRuntimeStatus(message?: AssistantMessage): void;
|
|
37
|
+
setWorkingMessage(message: string | undefined, messageInFlight: AssistantMessage | undefined): void;
|
|
38
|
+
resetWorkingIndicators(): void;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=runtime-status-controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-status-controller.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/runtime-status-controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,EAAE,KAAK,sBAAsB,EAAE,KAAK,GAAG,EAAE,MAAM,oBAAoB,CAAC;AACnG,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAK3E,MAAM,WAAW,2BAA2B;IAC3C,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC;IACjB,QAAQ,CAAC,eAAe,EAAE,SAAS,CAAC;IACpC,QAAQ,CAAC,YAAY,EAAE,qBAAqB,GAAG,SAAS,CAAC;IACzD,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACnC,WAAW,IAAI,OAAO,CAAC;IACvB,gBAAgB,IAAI,OAAO,CAAC;CAC5B;AAED,mFAAmF;AACnF,qBAAa,uBAAuB;IACnC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA8B;IACnD,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,cAAc,CAAqB;IAC3C,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,uBAAuB,CAAqC;IACpE,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAgB;IACtD,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAAiB;IAC5D,OAAO,CAAC,mBAAmB,CAAmC;IAC9D,OAAO,CAAC,kBAAkB,CAAqB;IAE/C,YAAY,IAAI,EAAE,2BAA2B,EAG5C;IAED,IAAI,gBAAgB,IAAI,MAAM,GAAG,SAAS,CAEzC;IAED,IAAI,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAE7C;IAED,IAAI,gBAAgB,IAAI,OAAO,CAE9B;IAED,IAAI,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAElC;IAED,IAAI,gBAAgB,IAAI,sBAAsB,GAAG,SAAS,CAEzD;IAED,IAAI,gBAAgB,CAAC,KAAK,EAAE,sBAAsB,GAAG,SAAS,EAE7D;IAED,uBAAuB,IAAI,MAAM,CAEhC;IAED,mBAAmB,IAAI,MAAM,CAQ5B;IAED,iBAAiB,IAAI,IAAI,CASxB;IAED,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA4BxC;IAED,mBAAmB,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,IAAI,CA4B1D;IAED,sBAAsB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAE3C;IAED,mBAAmB,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAoBpD;IAED,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,eAAe,EAAE,gBAAgB,GAAG,SAAS,GAAG,IAAI,CAUlG;IAED,sBAAsB,IAAI,IAAI,CAQ7B;CACD"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { Loader } from "@caupulican/pi-tui";
|
|
2
|
+
import { keyText } from "./components/keybinding-hints.js";
|
|
3
|
+
import { applyRuntimeStatusLabel, resolveHiddenThinkingStatus } from "./runtime-status.js";
|
|
4
|
+
import { theme } from "./theme/theme.js";
|
|
5
|
+
/** Owns the human-facing turn indicator and its loader/activity-lane lifecycle. */
|
|
6
|
+
export class RuntimeStatusController {
|
|
7
|
+
constructor(host) {
|
|
8
|
+
this.defaultWorkingMessage = "Working...";
|
|
9
|
+
this.defaultHiddenThinkingLabel = "Thinking...";
|
|
10
|
+
this.hiddenThinkingLabel = this.defaultHiddenThinkingLabel;
|
|
11
|
+
this.host = host;
|
|
12
|
+
this.workingVisible = host.hasHumanAudience;
|
|
13
|
+
}
|
|
14
|
+
get loadingAnimation() {
|
|
15
|
+
return this.activeLoader;
|
|
16
|
+
}
|
|
17
|
+
set loadingAnimation(value) {
|
|
18
|
+
this.activeLoader = value;
|
|
19
|
+
}
|
|
20
|
+
get isWorkingVisible() {
|
|
21
|
+
return this.workingVisible;
|
|
22
|
+
}
|
|
23
|
+
set isWorkingVisible(value) {
|
|
24
|
+
this.workingVisible = value;
|
|
25
|
+
}
|
|
26
|
+
get indicatorOptions() {
|
|
27
|
+
return this.workingIndicatorOptions;
|
|
28
|
+
}
|
|
29
|
+
set indicatorOptions(value) {
|
|
30
|
+
this.workingIndicatorOptions = value;
|
|
31
|
+
}
|
|
32
|
+
getWorkingLoaderMessage() {
|
|
33
|
+
return this.workingMessage ?? this.defaultWorkingMessage;
|
|
34
|
+
}
|
|
35
|
+
createWorkingLoader() {
|
|
36
|
+
return new Loader(this.host.ui, (spinner) => theme.fg("accent", spinner), (text) => theme.fg("muted", text), this.runtimeStatusLabel ?? this.getWorkingLoaderMessage(), this.workingIndicatorOptions);
|
|
37
|
+
}
|
|
38
|
+
stopWorkingLoader() {
|
|
39
|
+
if (this.activeLoader) {
|
|
40
|
+
this.activeLoader.stop();
|
|
41
|
+
this.activeLoader = undefined;
|
|
42
|
+
}
|
|
43
|
+
this.host.statusContainer.clear();
|
|
44
|
+
this.runtimeStatusLabel = undefined;
|
|
45
|
+
this.host.activityLane?.remove("runtime:routing");
|
|
46
|
+
this.host.activityLane?.remove("runtime:turn");
|
|
47
|
+
}
|
|
48
|
+
setWorkingVisible(visible) {
|
|
49
|
+
if (!this.host.hasHumanAudience) {
|
|
50
|
+
this.workingVisible = false;
|
|
51
|
+
this.stopWorkingLoader();
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
this.workingVisible = visible;
|
|
55
|
+
if (!visible) {
|
|
56
|
+
const currentRuntimeStatus = this.runtimeStatusLabel;
|
|
57
|
+
this.stopWorkingLoader();
|
|
58
|
+
if (this.host.isStreaming())
|
|
59
|
+
this.runtimeStatusLabel = currentRuntimeStatus;
|
|
60
|
+
this.host.ui.requestRender();
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (this.host.isStreaming() && !this.activeLoader) {
|
|
64
|
+
if (this.workingIndicatorOptions) {
|
|
65
|
+
this.host.statusContainer.clear();
|
|
66
|
+
this.activeLoader = this.createWorkingLoader();
|
|
67
|
+
this.host.statusContainer.addChild(this.activeLoader);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
this.host.activityLane?.start({
|
|
71
|
+
id: "runtime:turn",
|
|
72
|
+
kind: "runtime",
|
|
73
|
+
label: this.runtimeStatusLabel ?? this.getWorkingLoaderMessage(),
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
this.host.ui.requestRender();
|
|
78
|
+
}
|
|
79
|
+
setWorkingIndicator(options) {
|
|
80
|
+
this.workingIndicatorOptions = options;
|
|
81
|
+
if (!this.host.hasHumanAudience) {
|
|
82
|
+
this.stopWorkingLoader();
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (options) {
|
|
86
|
+
this.host.activityLane?.remove("runtime:turn");
|
|
87
|
+
if (this.host.isStreaming() && this.workingVisible) {
|
|
88
|
+
const currentRuntimeStatus = this.runtimeStatusLabel;
|
|
89
|
+
this.stopWorkingLoader();
|
|
90
|
+
this.runtimeStatusLabel = currentRuntimeStatus;
|
|
91
|
+
this.activeLoader = this.createWorkingLoader();
|
|
92
|
+
this.host.statusContainer.addChild(this.activeLoader);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
this.activeLoader?.stop();
|
|
97
|
+
this.activeLoader = undefined;
|
|
98
|
+
this.host.statusContainer.clear();
|
|
99
|
+
if (this.host.isStreaming() && this.workingVisible) {
|
|
100
|
+
this.host.activityLane?.start({
|
|
101
|
+
id: "runtime:turn",
|
|
102
|
+
kind: "runtime",
|
|
103
|
+
label: this.runtimeStatusLabel ?? this.getWorkingLoaderMessage(),
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
this.host.ui.requestRender();
|
|
108
|
+
}
|
|
109
|
+
setHiddenThinkingLabel(label) {
|
|
110
|
+
this.hiddenThinkingLabel = label ?? this.defaultHiddenThinkingLabel;
|
|
111
|
+
}
|
|
112
|
+
updateRuntimeStatus(message) {
|
|
113
|
+
if (!this.host.hasHumanAudience)
|
|
114
|
+
return;
|
|
115
|
+
const label = message
|
|
116
|
+
? resolveHiddenThinkingStatus(message, this.host.isThinkingHidden(), this.hiddenThinkingLabel, this.getWorkingLoaderMessage())
|
|
117
|
+
: this.getWorkingLoaderMessage();
|
|
118
|
+
this.runtimeStatusLabel = applyRuntimeStatusLabel({
|
|
119
|
+
hasHumanAudience: this.host.hasHumanAudience,
|
|
120
|
+
currentLabel: this.runtimeStatusLabel,
|
|
121
|
+
loadingAnimation: this.activeLoader,
|
|
122
|
+
activityLane: this.host.activityLane,
|
|
123
|
+
requestRender: () => this.host.ui.requestRender(),
|
|
124
|
+
}, label);
|
|
125
|
+
}
|
|
126
|
+
setWorkingMessage(message, messageInFlight) {
|
|
127
|
+
this.workingMessage = message;
|
|
128
|
+
if (messageInFlight) {
|
|
129
|
+
this.updateRuntimeStatus(messageInFlight);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
if (this.activeLoader) {
|
|
133
|
+
this.activeLoader.setMessage(message ?? this.defaultWorkingMessage);
|
|
134
|
+
}
|
|
135
|
+
this.host.activityLane?.update("runtime:turn", message ?? this.defaultWorkingMessage);
|
|
136
|
+
}
|
|
137
|
+
resetWorkingIndicators() {
|
|
138
|
+
this.workingMessage = undefined;
|
|
139
|
+
this.workingVisible = this.host.hasHumanAudience;
|
|
140
|
+
this.setWorkingIndicator();
|
|
141
|
+
if (this.activeLoader) {
|
|
142
|
+
this.activeLoader.setMessage(`${this.defaultWorkingMessage} (${keyText("app.interrupt")} to interrupt)`);
|
|
143
|
+
}
|
|
144
|
+
this.setHiddenThinkingLabel();
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=runtime-status-controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-status-controller.js","sourceRoot":"","sources":["../../../src/modes/interactive/runtime-status-controller.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,MAAM,EAAyC,MAAM,oBAAoB,CAAC;AAEnG,OAAO,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAC3F,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAWzC,mFAAmF;AACnF,MAAM,OAAO,uBAAuB;IAWnC,YAAY,IAAiC;QAL5B,0BAAqB,GAAG,YAAY,CAAC;QACrC,+BAA0B,GAAG,aAAa,CAAC;QACpD,wBAAmB,GAAG,IAAI,CAAC,0BAA0B,CAAC;QAI7D,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,gBAAgB,CAAC;IAC7C,CAAC;IAED,IAAI,gBAAgB;QACnB,OAAO,IAAI,CAAC,YAAY,CAAC;IAC1B,CAAC;IAED,IAAI,gBAAgB,CAAC,KAAyB;QAC7C,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;IAC3B,CAAC;IAED,IAAI,gBAAgB;QACnB,OAAO,IAAI,CAAC,cAAc,CAAC;IAC5B,CAAC;IAED,IAAI,gBAAgB,CAAC,KAAc;QAClC,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;IAC7B,CAAC;IAED,IAAI,gBAAgB;QACnB,OAAO,IAAI,CAAC,uBAAuB,CAAC;IACrC,CAAC;IAED,IAAI,gBAAgB,CAAC,KAAyC;QAC7D,IAAI,CAAC,uBAAuB,GAAG,KAAK,CAAC;IACtC,CAAC;IAED,uBAAuB;QACtB,OAAO,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,qBAAqB,CAAC;IAC1D,CAAC;IAED,mBAAmB;QAClB,OAAO,IAAI,MAAM,CAChB,IAAI,CAAC,IAAI,CAAC,EAAE,EACZ,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,EACxC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,EACjC,IAAI,CAAC,kBAAkB,IAAI,IAAI,CAAC,uBAAuB,EAAE,EACzD,IAAI,CAAC,uBAAuB,CAC5B,CAAC;IACH,CAAC;IAED,iBAAiB;QAChB,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACvB,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;YACzB,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;QAC/B,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;QAClC,IAAI,CAAC,kBAAkB,GAAG,SAAS,CAAC;QACpC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,iBAAiB,CAAC,CAAC;QAClD,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC;IAChD,CAAC;IAED,iBAAiB,CAAC,OAAgB;QACjC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACjC,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;YAC5B,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACzB,OAAO;QACR,CAAC;QACD,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC;QAC9B,IAAI,CAAC,OAAO,EAAE,CAAC;YACd,MAAM,oBAAoB,GAAG,IAAI,CAAC,kBAAkB,CAAC;YACrD,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACzB,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;gBAAE,IAAI,CAAC,kBAAkB,GAAG,oBAAoB,CAAC;YAC5E,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC;YAC7B,OAAO;QACR,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACnD,IAAI,IAAI,CAAC,uBAAuB,EAAE,CAAC;gBAClC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;gBAClC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC/C,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACvD,CAAC;iBAAM,CAAC;gBACP,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC;oBAC7B,EAAE,EAAE,cAAc;oBAClB,IAAI,EAAE,SAAS;oBACf,KAAK,EAAE,IAAI,CAAC,kBAAkB,IAAI,IAAI,CAAC,uBAAuB,EAAE;iBAChE,CAAC,CAAC;YACJ,CAAC;QACF,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC;IAC9B,CAAC;IAED,mBAAmB,CAAC,OAAgC;QACnD,IAAI,CAAC,uBAAuB,GAAG,OAAO,CAAC;QACvC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACjC,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACzB,OAAO;QACR,CAAC;QACD,IAAI,OAAO,EAAE,CAAC;YACb,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC;YAC/C,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpD,MAAM,oBAAoB,GAAG,IAAI,CAAC,kBAAkB,CAAC;gBACrD,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBACzB,IAAI,CAAC,kBAAkB,GAAG,oBAAoB,CAAC;gBAC/C,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC/C,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACvD,CAAC;QACF,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC;YAC1B,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;YAC9B,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;YAClC,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpD,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC;oBAC7B,EAAE,EAAE,cAAc;oBAClB,IAAI,EAAE,SAAS;oBACf,KAAK,EAAE,IAAI,CAAC,kBAAkB,IAAI,IAAI,CAAC,uBAAuB,EAAE;iBAChE,CAAC,CAAC;YACJ,CAAC;QACF,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC;IAC9B,CAAC;IAED,sBAAsB,CAAC,KAAc;QACpC,IAAI,CAAC,mBAAmB,GAAG,KAAK,IAAI,IAAI,CAAC,0BAA0B,CAAC;IACrE,CAAC;IAED,mBAAmB,CAAC,OAA0B;QAC7C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB;YAAE,OAAO;QACxC,MAAM,KAAK,GAAG,OAAO;YACpB,CAAC,CAAC,2BAA2B,CAC3B,OAAO,EACP,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAC5B,IAAI,CAAC,mBAAmB,EACxB,IAAI,CAAC,uBAAuB,EAAE,CAC9B;YACF,CAAC,CAAC,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAClC,IAAI,CAAC,kBAAkB,GAAG,uBAAuB,CAChD;YACC,gBAAgB,EAAE,IAAI,CAAC,IAAI,CAAC,gBAAgB;YAC5C,YAAY,EAAE,IAAI,CAAC,kBAAkB;YACrC,gBAAgB,EAAE,IAAI,CAAC,YAAY;YACnC,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,YAAY;YACpC,aAAa,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE;SACjD,EACD,KAAK,CACL,CAAC;IACH,CAAC;IAED,iBAAiB,CAAC,OAA2B,EAAE,eAA6C;QAC3F,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC;QAC9B,IAAI,eAAe,EAAE,CAAC;YACrB,IAAI,CAAC,mBAAmB,CAAC,eAAe,CAAC,CAAC;YAC1C,OAAO;QACR,CAAC;QACD,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACvB,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,OAAO,IAAI,IAAI,CAAC,qBAAqB,CAAC,CAAC;QACrE,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,cAAc,EAAE,OAAO,IAAI,IAAI,CAAC,qBAAqB,CAAC,CAAC;IACvF,CAAC;IAED,sBAAsB;QACrB,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;QAChC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC;QACjD,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACvB,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,qBAAqB,KAAK,OAAO,CAAC,eAAe,CAAC,gBAAgB,CAAC,CAAC;QAC1G,CAAC;QACD,IAAI,CAAC,sBAAsB,EAAE,CAAC;IAC/B,CAAC;CACD","sourcesContent":["import type { AssistantMessage } from \"@caupulican/pi-ai\";\nimport { type Container, Loader, type LoaderIndicatorOptions, type TUI } from \"@caupulican/pi-tui\";\nimport type { ActivityLaneComponent } from \"./components/activity-lane.ts\";\nimport { keyText } from \"./components/keybinding-hints.ts\";\nimport { applyRuntimeStatusLabel, resolveHiddenThinkingStatus } from \"./runtime-status.ts\";\nimport { theme } from \"./theme/theme.ts\";\n\nexport interface RuntimeStatusControllerHost {\n\treadonly ui: TUI;\n\treadonly statusContainer: Container;\n\treadonly activityLane: ActivityLaneComponent | undefined;\n\treadonly hasHumanAudience: boolean;\n\tisStreaming(): boolean;\n\tisThinkingHidden(): boolean;\n}\n\n/** Owns the human-facing turn indicator and its loader/activity-lane lifecycle. */\nexport class RuntimeStatusController {\n\tprivate readonly host: RuntimeStatusControllerHost;\n\tprivate activeLoader: Loader | undefined;\n\tprivate workingMessage: string | undefined;\n\tprivate workingVisible: boolean;\n\tprivate workingIndicatorOptions: LoaderIndicatorOptions | undefined;\n\tprivate readonly defaultWorkingMessage = \"Working...\";\n\tprivate readonly defaultHiddenThinkingLabel = \"Thinking...\";\n\tprivate hiddenThinkingLabel = this.defaultHiddenThinkingLabel;\n\tprivate runtimeStatusLabel: string | undefined;\n\n\tconstructor(host: RuntimeStatusControllerHost) {\n\t\tthis.host = host;\n\t\tthis.workingVisible = host.hasHumanAudience;\n\t}\n\n\tget loadingAnimation(): Loader | undefined {\n\t\treturn this.activeLoader;\n\t}\n\n\tset loadingAnimation(value: Loader | undefined) {\n\t\tthis.activeLoader = value;\n\t}\n\n\tget isWorkingVisible(): boolean {\n\t\treturn this.workingVisible;\n\t}\n\n\tset isWorkingVisible(value: boolean) {\n\t\tthis.workingVisible = value;\n\t}\n\n\tget indicatorOptions(): LoaderIndicatorOptions | undefined {\n\t\treturn this.workingIndicatorOptions;\n\t}\n\n\tset indicatorOptions(value: LoaderIndicatorOptions | undefined) {\n\t\tthis.workingIndicatorOptions = value;\n\t}\n\n\tgetWorkingLoaderMessage(): string {\n\t\treturn this.workingMessage ?? this.defaultWorkingMessage;\n\t}\n\n\tcreateWorkingLoader(): Loader {\n\t\treturn new Loader(\n\t\t\tthis.host.ui,\n\t\t\t(spinner) => theme.fg(\"accent\", spinner),\n\t\t\t(text) => theme.fg(\"muted\", text),\n\t\t\tthis.runtimeStatusLabel ?? this.getWorkingLoaderMessage(),\n\t\t\tthis.workingIndicatorOptions,\n\t\t);\n\t}\n\n\tstopWorkingLoader(): void {\n\t\tif (this.activeLoader) {\n\t\t\tthis.activeLoader.stop();\n\t\t\tthis.activeLoader = undefined;\n\t\t}\n\t\tthis.host.statusContainer.clear();\n\t\tthis.runtimeStatusLabel = undefined;\n\t\tthis.host.activityLane?.remove(\"runtime:routing\");\n\t\tthis.host.activityLane?.remove(\"runtime:turn\");\n\t}\n\n\tsetWorkingVisible(visible: boolean): void {\n\t\tif (!this.host.hasHumanAudience) {\n\t\t\tthis.workingVisible = false;\n\t\t\tthis.stopWorkingLoader();\n\t\t\treturn;\n\t\t}\n\t\tthis.workingVisible = visible;\n\t\tif (!visible) {\n\t\t\tconst currentRuntimeStatus = this.runtimeStatusLabel;\n\t\t\tthis.stopWorkingLoader();\n\t\t\tif (this.host.isStreaming()) this.runtimeStatusLabel = currentRuntimeStatus;\n\t\t\tthis.host.ui.requestRender();\n\t\t\treturn;\n\t\t}\n\t\tif (this.host.isStreaming() && !this.activeLoader) {\n\t\t\tif (this.workingIndicatorOptions) {\n\t\t\t\tthis.host.statusContainer.clear();\n\t\t\t\tthis.activeLoader = this.createWorkingLoader();\n\t\t\t\tthis.host.statusContainer.addChild(this.activeLoader);\n\t\t\t} else {\n\t\t\t\tthis.host.activityLane?.start({\n\t\t\t\t\tid: \"runtime:turn\",\n\t\t\t\t\tkind: \"runtime\",\n\t\t\t\t\tlabel: this.runtimeStatusLabel ?? this.getWorkingLoaderMessage(),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tthis.host.ui.requestRender();\n\t}\n\n\tsetWorkingIndicator(options?: LoaderIndicatorOptions): void {\n\t\tthis.workingIndicatorOptions = options;\n\t\tif (!this.host.hasHumanAudience) {\n\t\t\tthis.stopWorkingLoader();\n\t\t\treturn;\n\t\t}\n\t\tif (options) {\n\t\t\tthis.host.activityLane?.remove(\"runtime:turn\");\n\t\t\tif (this.host.isStreaming() && this.workingVisible) {\n\t\t\t\tconst currentRuntimeStatus = this.runtimeStatusLabel;\n\t\t\t\tthis.stopWorkingLoader();\n\t\t\t\tthis.runtimeStatusLabel = currentRuntimeStatus;\n\t\t\t\tthis.activeLoader = this.createWorkingLoader();\n\t\t\t\tthis.host.statusContainer.addChild(this.activeLoader);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.activeLoader?.stop();\n\t\t\tthis.activeLoader = undefined;\n\t\t\tthis.host.statusContainer.clear();\n\t\t\tif (this.host.isStreaming() && this.workingVisible) {\n\t\t\t\tthis.host.activityLane?.start({\n\t\t\t\t\tid: \"runtime:turn\",\n\t\t\t\t\tkind: \"runtime\",\n\t\t\t\t\tlabel: this.runtimeStatusLabel ?? this.getWorkingLoaderMessage(),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tthis.host.ui.requestRender();\n\t}\n\n\tsetHiddenThinkingLabel(label?: string): void {\n\t\tthis.hiddenThinkingLabel = label ?? this.defaultHiddenThinkingLabel;\n\t}\n\n\tupdateRuntimeStatus(message?: AssistantMessage): void {\n\t\tif (!this.host.hasHumanAudience) return;\n\t\tconst label = message\n\t\t\t? resolveHiddenThinkingStatus(\n\t\t\t\t\tmessage,\n\t\t\t\t\tthis.host.isThinkingHidden(),\n\t\t\t\t\tthis.hiddenThinkingLabel,\n\t\t\t\t\tthis.getWorkingLoaderMessage(),\n\t\t\t\t)\n\t\t\t: this.getWorkingLoaderMessage();\n\t\tthis.runtimeStatusLabel = applyRuntimeStatusLabel(\n\t\t\t{\n\t\t\t\thasHumanAudience: this.host.hasHumanAudience,\n\t\t\t\tcurrentLabel: this.runtimeStatusLabel,\n\t\t\t\tloadingAnimation: this.activeLoader,\n\t\t\t\tactivityLane: this.host.activityLane,\n\t\t\t\trequestRender: () => this.host.ui.requestRender(),\n\t\t\t},\n\t\t\tlabel,\n\t\t);\n\t}\n\n\tsetWorkingMessage(message: string | undefined, messageInFlight: AssistantMessage | undefined): void {\n\t\tthis.workingMessage = message;\n\t\tif (messageInFlight) {\n\t\t\tthis.updateRuntimeStatus(messageInFlight);\n\t\t\treturn;\n\t\t}\n\t\tif (this.activeLoader) {\n\t\t\tthis.activeLoader.setMessage(message ?? this.defaultWorkingMessage);\n\t\t}\n\t\tthis.host.activityLane?.update(\"runtime:turn\", message ?? this.defaultWorkingMessage);\n\t}\n\n\tresetWorkingIndicators(): void {\n\t\tthis.workingMessage = undefined;\n\t\tthis.workingVisible = this.host.hasHumanAudience;\n\t\tthis.setWorkingIndicator();\n\t\tif (this.activeLoader) {\n\t\t\tthis.activeLoader.setMessage(`${this.defaultWorkingMessage} (${keyText(\"app.interrupt\")} to interrupt)`);\n\t\t}\n\t\tthis.setHiddenThinkingLabel();\n\t}\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { AssistantMessage } from "@caupulican/pi-ai";
|
|
2
|
+
export interface RuntimeStatusPresentation {
|
|
3
|
+
hasHumanAudience: boolean;
|
|
4
|
+
currentLabel: string | undefined;
|
|
5
|
+
loadingAnimation: {
|
|
6
|
+
setMessage(message: string): void;
|
|
7
|
+
} | undefined;
|
|
8
|
+
activityLane: {
|
|
9
|
+
update(id: string, label: string): void;
|
|
10
|
+
} | undefined;
|
|
11
|
+
requestRender(): void;
|
|
12
|
+
}
|
|
13
|
+
export declare function applyRuntimeStatusLabel(presentation: RuntimeStatusPresentation, label: string): string | undefined;
|
|
14
|
+
export declare function resolveHiddenThinkingStatus(message: AssistantMessage, hideThinkingBlock: boolean, hiddenThinkingLabel: string, workingLabel: string): string;
|
|
15
|
+
//# sourceMappingURL=runtime-status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-status.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/runtime-status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,MAAM,WAAW,yBAAyB;IACzC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,gBAAgB,EAAE;QAAE,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,SAAS,CAAC;IACpE,YAAY,EAAE;QAAE,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,SAAS,CAAC;IACtE,aAAa,IAAI,IAAI,CAAC;CACtB;AAED,wBAAgB,uBAAuB,CAAC,YAAY,EAAE,yBAAyB,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAMlH;AAED,wBAAgB,2BAA2B,CAC1C,OAAO,EAAE,gBAAgB,EACzB,iBAAiB,EAAE,OAAO,EAC1B,mBAAmB,EAAE,MAAM,EAC3B,YAAY,EAAE,MAAM,GAClB,MAAM,CASR"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export function applyRuntimeStatusLabel(presentation, label) {
|
|
2
|
+
if (!presentation.hasHumanAudience || presentation.currentLabel === label)
|
|
3
|
+
return presentation.currentLabel;
|
|
4
|
+
if (presentation.loadingAnimation)
|
|
5
|
+
presentation.loadingAnimation.setMessage(label);
|
|
6
|
+
else
|
|
7
|
+
presentation.activityLane?.update("runtime:turn", label);
|
|
8
|
+
presentation.requestRender();
|
|
9
|
+
return label;
|
|
10
|
+
}
|
|
11
|
+
export function resolveHiddenThinkingStatus(message, hideThinkingBlock, hiddenThinkingLabel, workingLabel) {
|
|
12
|
+
if (!hideThinkingBlock)
|
|
13
|
+
return workingLabel;
|
|
14
|
+
const hasThinking = message.content.some((content) => content.type === "thinking" && content.thinking.trim().length > 0);
|
|
15
|
+
const hasVisibleWork = message.content.some((content) => (content.type === "text" && content.text.trim().length > 0) || content.type === "toolCall");
|
|
16
|
+
return hasThinking && !hasVisibleWork ? hiddenThinkingLabel : workingLabel;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=runtime-status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-status.js","sourceRoot":"","sources":["../../../src/modes/interactive/runtime-status.ts"],"names":[],"mappings":"AAUA,MAAM,UAAU,uBAAuB,CAAC,YAAuC,EAAE,KAAa;IAC7F,IAAI,CAAC,YAAY,CAAC,gBAAgB,IAAI,YAAY,CAAC,YAAY,KAAK,KAAK;QAAE,OAAO,YAAY,CAAC,YAAY,CAAC;IAC5G,IAAI,YAAY,CAAC,gBAAgB;QAAE,YAAY,CAAC,gBAAgB,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;;QAC9E,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IAC9D,YAAY,CAAC,aAAa,EAAE,CAAC;IAC7B,OAAO,KAAK,CAAC;AACd,CAAC;AAED,MAAM,UAAU,2BAA2B,CAC1C,OAAyB,EACzB,iBAA0B,EAC1B,mBAA2B,EAC3B,YAAoB;IAEpB,IAAI,CAAC,iBAAiB;QAAE,OAAO,YAAY,CAAC;IAC5C,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CACvC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,UAAU,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAC9E,CAAC;IACF,MAAM,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAC1C,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,OAAO,CAAC,IAAI,KAAK,UAAU,CACvG,CAAC;IACF,OAAO,WAAW,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,YAAY,CAAC;AAC5E,CAAC","sourcesContent":["import type { AssistantMessage } from \"@caupulican/pi-ai\";\n\nexport interface RuntimeStatusPresentation {\n\thasHumanAudience: boolean;\n\tcurrentLabel: string | undefined;\n\tloadingAnimation: { setMessage(message: string): void } | undefined;\n\tactivityLane: { update(id: string, label: string): void } | undefined;\n\trequestRender(): void;\n}\n\nexport function applyRuntimeStatusLabel(presentation: RuntimeStatusPresentation, label: string): string | undefined {\n\tif (!presentation.hasHumanAudience || presentation.currentLabel === label) return presentation.currentLabel;\n\tif (presentation.loadingAnimation) presentation.loadingAnimation.setMessage(label);\n\telse presentation.activityLane?.update(\"runtime:turn\", label);\n\tpresentation.requestRender();\n\treturn label;\n}\n\nexport function resolveHiddenThinkingStatus(\n\tmessage: AssistantMessage,\n\thideThinkingBlock: boolean,\n\thiddenThinkingLabel: string,\n\tworkingLabel: string,\n): string {\n\tif (!hideThinkingBlock) return workingLabel;\n\tconst hasThinking = message.content.some(\n\t\t(content) => content.type === \"thinking\" && content.thinking.trim().length > 0,\n\t);\n\tconst hasVisibleWork = message.content.some(\n\t\t(content) => (content.type === \"text\" && content.text.trim().length > 0) || content.type === \"toolCall\",\n\t);\n\treturn hasThinking && !hasVisibleWork ? hiddenThinkingLabel : workingLabel;\n}\n"]}
|
package/docs/json.md
CHANGED
|
@@ -62,7 +62,7 @@ Extended messages from [`packages/coding-agent/src/core/messages.ts`](https://gi
|
|
|
62
62
|
Each line is a JSON object. The first line is the session header:
|
|
63
63
|
|
|
64
64
|
```json
|
|
65
|
-
{"type":"session","version":
|
|
65
|
+
{"type":"session","version":4,"id":"uuid","timestamp":"...","cwd":"/path"}
|
|
66
66
|
```
|
|
67
67
|
|
|
68
68
|
Followed by events as they occur:
|
package/docs/keybindings.md
CHANGED
|
@@ -122,13 +122,14 @@ These actions apply while the built-in `ask_question` interaction has focus. The
|
|
|
122
122
|
| `app.model.cycleForward` | `ctrl+p` | Cycle to next model |
|
|
123
123
|
| `app.model.cycleBackward` | `shift+ctrl+p` | Cycle to previous model |
|
|
124
124
|
| `app.thinking.cycle` | `shift+tab` | Cycle thinking level |
|
|
125
|
-
| `app.thinking.toggle` | `
|
|
125
|
+
| `app.thinking.toggle` | `shift+pageUp` | Show or hide thinking blocks (hidden by default) |
|
|
126
126
|
|
|
127
127
|
### Display and Message Queue
|
|
128
128
|
|
|
129
129
|
| Keybinding id | Default | Description |
|
|
130
130
|
|--------|---------|-------------|
|
|
131
131
|
| `app.tools.expand` | `ctrl+o` | Expand or collapse tool output (file groups stay as a count + short list until then) |
|
|
132
|
+
| `app.transcript.open` | `ctrl+t` | Open expanded transcript scrollback |
|
|
132
133
|
| `app.history.load` | `ctrl+shift+h` | Load deferred session history into the chat |
|
|
133
134
|
| `app.message.followUp` | `alt+enter` | Queue follow-up message |
|
|
134
135
|
| `app.message.dequeue` | `alt+up` | Restore queued messages to editor |
|
package/docs/session-format.md
CHANGED
|
@@ -23,13 +23,14 @@ Sessions have a version field in the header:
|
|
|
23
23
|
- **Version 1**: Linear entry sequence (legacy, auto-migrated on load)
|
|
24
24
|
- **Version 2**: Tree structure with `id`/`parentId` linking
|
|
25
25
|
- **Version 3**: Renamed `hookMessage` role to `custom` (extensions unification)
|
|
26
|
+
- **Version 4**: Added bounded provider-request, foreground-tool, and compaction lifecycle records for crash recovery
|
|
26
27
|
|
|
27
|
-
Existing sessions are automatically migrated to the current version (
|
|
28
|
+
Existing sessions are automatically migrated to the current version (v4) when loaded.
|
|
28
29
|
|
|
29
30
|
## Source Files
|
|
30
31
|
|
|
31
32
|
Source on GitHub ([pi-mono](https://github.com/earendil-works/pi-mono)):
|
|
32
|
-
- [`packages/
|
|
33
|
+
- [`packages/agent/src/session/session-manager.ts`](https://github.com/earendil-works/pi-mono/blob/main/packages/agent/src/session/session-manager.ts) - Session entry types and SessionManager
|
|
33
34
|
- [`packages/coding-agent/src/core/messages.ts`](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/messages.ts) - Extended message types (BashExecutionMessage, CustomMessage, etc.)
|
|
34
35
|
- [`packages/ai/src/types.ts`](https://github.com/earendil-works/pi-mono/blob/main/packages/ai/src/types.ts) - Base message types (UserMessage, AssistantMessage, ToolResultMessage)
|
|
35
36
|
- [`packages/agent/src/types.ts`](https://github.com/earendil-works/pi-mono/blob/main/packages/agent/src/types.ts) - AgentMessage union type
|
|
@@ -188,13 +189,13 @@ interface SessionEntryBase {
|
|
|
188
189
|
First line of the file. Metadata only, not part of the tree (no `id`/`parentId`).
|
|
189
190
|
|
|
190
191
|
```json
|
|
191
|
-
{"type":"session","version":
|
|
192
|
+
{"type":"session","version":4,"id":"uuid","timestamp":"2024-12-03T14:00:00.000Z","cwd":"/path/to/project"}
|
|
192
193
|
```
|
|
193
194
|
|
|
194
195
|
For sessions with a parent (created via `/fork`, `/clone`, or `newSession({ parentSession })`):
|
|
195
196
|
|
|
196
197
|
```json
|
|
197
|
-
{"type":"session","version":
|
|
198
|
+
{"type":"session","version":4,"id":"uuid","timestamp":"2024-12-03T14:00:00.000Z","cwd":"/path/to/project","parentSession":"/path/to/original/session.jsonl"}
|
|
198
199
|
```
|
|
199
200
|
|
|
200
201
|
### SessionMessageEntry
|
|
@@ -290,6 +291,37 @@ Session metadata (e.g., user-defined display name). Set via `/name`, `--name` /
|
|
|
290
291
|
|
|
291
292
|
The session name is displayed in the session selector (`/resume`) instead of the first message when set.
|
|
292
293
|
|
|
294
|
+
### Lifecycle Entries (v4)
|
|
295
|
+
|
|
296
|
+
Lifecycle entries make interrupted foreground work recoverable without duplicating provider-visible data. They participate in tree ancestry but are excluded from model context and hidden from ordinary `/tree` views.
|
|
297
|
+
|
|
298
|
+
`RequestSnapshotEntry` is force-flushed before provider transport. It contains only the accepted model identity, bounded SHA-256 fingerprints, and bounded message-entry IDs; it never stores prompt text, tool arguments, results, credentials, or headers.
|
|
299
|
+
|
|
300
|
+
```json
|
|
301
|
+
{"type":"request_snapshot","id":"r1","parentId":"u1","timestamp":"2026-08-21T12:00:00.000Z","requestId":"0198...","reason":"initial","api":"anthropic-messages","provider":"amazon-bedrock","modelId":"global.anthropic.claude-haiku-4-5-20251001-v1:0","effectiveConfigFingerprint":"...","systemFingerprint":"...","toolsFingerprint":"...","historyFingerprint":"...","messageEntryIds":["u1"]}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
`ForegroundToolStartEntry` is written after validation/policy checks and before a prepared tool body starts. Parallel waves are appended in one bounded batch.
|
|
305
|
+
|
|
306
|
+
```json
|
|
307
|
+
{"type":"foreground_tool_start","id":"t1","parentId":"a1","timestamp":"2026-08-21T12:00:01.000Z","requestId":"0198...","assistantMessageEntryId":"a1","callId":"toolu_123","toolName":"bash"}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
`ForegroundToolTerminalEntry` is written only after the canonical `toolResult` message. Its composite identity is `(requestId, assistantMessageEntryId, callId)`.
|
|
311
|
+
|
|
312
|
+
```json
|
|
313
|
+
{"type":"foreground_tool_terminal","id":"t2","parentId":"result1","timestamp":"2026-08-21T12:00:02.000Z","requestId":"0198...","assistantMessageEntryId":"a1","callId":"toolu_123","toolName":"bash","outcome":"success","resultMessageEntryId":"result1"}
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
`CompactionStartEntry` and `CompactionEndEntry` bracket one complete compaction retry ladder. A successful end references the canonical `compaction` entry; interrupted runs are closed as `interrupted` during reopen repair.
|
|
317
|
+
|
|
318
|
+
```json
|
|
319
|
+
{"type":"compaction_start","id":"c1","parentId":"m1","timestamp":"2026-08-21T12:01:00.000Z","compactionId":"...","firstKeptEntryId":"m1","tokensBefore":50000}
|
|
320
|
+
{"type":"compaction_end","id":"c3","parentId":"c2","timestamp":"2026-08-21T12:01:03.000Z","compactionId":"...","outcome":"success","compactionEntryId":"c2"}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
On reopen, deterministic repair distinguishes calls that were never started from started calls whose outcome is unknown. Duplicate, contradictory, ambiguous, or out-of-order records are refused and surfaced for manual review rather than guessed.
|
|
324
|
+
|
|
293
325
|
## Tree Structure
|
|
294
326
|
|
|
295
327
|
Entries form a tree:
|
|
@@ -315,6 +347,7 @@ Entries form a tree:
|
|
|
315
347
|
- Then messages from `firstKeptEntryId` to compaction
|
|
316
348
|
- Then messages after compaction
|
|
317
349
|
4. Converts `BranchSummaryEntry` and `CustomMessageEntry` to appropriate message formats
|
|
350
|
+
5. Ignores lifecycle-only entries while preserving their ancestry for recovery
|
|
318
351
|
|
|
319
352
|
## Parsing Example
|
|
320
353
|
|
|
@@ -354,6 +387,21 @@ for (const line of lines) {
|
|
|
354
387
|
case "thinking_level_change":
|
|
355
388
|
console.log(`[${entry.id}] Thinking: ${entry.thinkingLevel}`);
|
|
356
389
|
break;
|
|
390
|
+
case "request_snapshot":
|
|
391
|
+
console.log(`[${entry.id}] Request ${entry.requestId}: ${entry.provider}/${entry.modelId}`);
|
|
392
|
+
break;
|
|
393
|
+
case "foreground_tool_start":
|
|
394
|
+
console.log(`[${entry.id}] Tool started: ${entry.toolName}/${entry.callId}`);
|
|
395
|
+
break;
|
|
396
|
+
case "foreground_tool_terminal":
|
|
397
|
+
console.log(`[${entry.id}] Tool ${entry.outcome}: ${entry.toolName}/${entry.callId}`);
|
|
398
|
+
break;
|
|
399
|
+
case "compaction_start":
|
|
400
|
+
console.log(`[${entry.id}] Compaction started: ${entry.compactionId}`);
|
|
401
|
+
break;
|
|
402
|
+
case "compaction_end":
|
|
403
|
+
console.log(`[${entry.id}] Compaction ${entry.outcome}: ${entry.compactionId}`);
|
|
404
|
+
break;
|
|
357
405
|
}
|
|
358
406
|
}
|
|
359
407
|
```
|
|
@@ -380,6 +428,7 @@ Key methods for working with sessions programmatically.
|
|
|
380
428
|
|
|
381
429
|
### Instance Methods - Appending (all return entry ID)
|
|
382
430
|
- `appendMessage(message)` - Add message
|
|
431
|
+
- `appendMessageBatch(entries)` - Atomically append a bounded source-order message/custom-message batch
|
|
383
432
|
- `appendThinkingLevelChange(level)` - Record thinking change
|
|
384
433
|
- `appendModelChange(provider, modelId)` - Record model change
|
|
385
434
|
- `appendCompaction(summary, firstKeptEntryId, tokensBefore, details?, fromHook?)` - Add compaction
|
|
@@ -387,6 +436,10 @@ Key methods for working with sessions programmatically.
|
|
|
387
436
|
- `appendSessionInfo(name)` - Set session display name
|
|
388
437
|
- `appendCustomMessageEntry(customType, content, display, details?)` - Extension message (in context)
|
|
389
438
|
- `appendLabelChange(targetId, label)` - Set/clear label
|
|
439
|
+
- `appendRequestSnapshot(snapshot)` - Force-flush a bounded accepted-request record
|
|
440
|
+
- `appendForegroundToolStarts(starts)` - Atomically reserve one prepared tool wave
|
|
441
|
+
- `appendForegroundToolTerminal(...)` - Link a started call to its canonical result
|
|
442
|
+
- `appendCompactionStart(...)` / `appendCompactionEnd(...)` - Bracket a compaction retry ladder
|
|
390
443
|
|
|
391
444
|
### Instance Methods - Tree Navigation
|
|
392
445
|
- `getLeafId()` - Current position
|
|
@@ -402,6 +455,8 @@ Key methods for working with sessions programmatically.
|
|
|
402
455
|
|
|
403
456
|
### Instance Methods - Context & Info
|
|
404
457
|
- `buildSessionContext()` - Get messages, thinkingLevel, and model for LLM
|
|
458
|
+
- `inspectSessionLifecycle()` - Validate the active branch lifecycle and classify incomplete work
|
|
459
|
+
- `planSessionLifecycleRepair()` - Produce a deterministic repair plan or a refusal with reasons
|
|
405
460
|
- `getEntries()` - All entries (excluding header)
|
|
406
461
|
- `getHeader()` - Session header metadata
|
|
407
462
|
- `getSessionName()` - Get display name from latest session_info entry
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-extension-custom-provider",
|
|
3
|
-
"version": "0.93.
|
|
3
|
+
"version": "0.93.19",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "pi-extension-custom-provider",
|
|
9
|
-
"version": "0.93.
|
|
9
|
+
"version": "0.93.19",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@anthropic-ai/sdk": "^0.52.0"
|
|
12
12
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-extension-sandbox",
|
|
3
|
-
"version": "0.93.
|
|
3
|
+
"version": "0.93.19",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "pi-extension-sandbox",
|
|
9
|
-
"version": "0.93.
|
|
9
|
+
"version": "0.93.19",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@anthropic-ai/sandbox-runtime": "^0.0.26"
|
|
12
12
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-extension-with-deps",
|
|
3
|
-
"version": "0.93.
|
|
3
|
+
"version": "0.93.19",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "pi-extension-with-deps",
|
|
9
|
-
"version": "0.93.
|
|
9
|
+
"version": "0.93.19",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"ms": "^2.1.3"
|
|
12
12
|
},
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@caupulican/pi-adaptative",
|
|
3
|
-
"version": "0.93.
|
|
3
|
+
"version": "0.93.19",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@caupulican/pi-adaptative",
|
|
9
|
-
"version": "0.93.
|
|
9
|
+
"version": "0.93.19",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@caupulican/pi-agent-core": "^0.93.
|
|
13
|
-
"@caupulican/pi-ai": "^0.93.
|
|
14
|
-
"@caupulican/pi-tui": "^0.93.
|
|
12
|
+
"@caupulican/pi-agent-core": "^0.93.19",
|
|
13
|
+
"@caupulican/pi-ai": "^0.93.19",
|
|
14
|
+
"@caupulican/pi-tui": "^0.93.19",
|
|
15
15
|
"@silvia-odwyer/photon-node": "0.3.4",
|
|
16
16
|
"chalk": "5.6.2",
|
|
17
17
|
"cross-spawn": "7.0.6",
|
|
@@ -506,11 +506,11 @@
|
|
|
506
506
|
}
|
|
507
507
|
},
|
|
508
508
|
"node_modules/@caupulican/pi-agent-core": {
|
|
509
|
-
"version": "0.93.
|
|
510
|
-
"resolved": "https://registry.npmjs.org/@caupulican/pi-agent-core/-/pi-agent-core-0.93.
|
|
509
|
+
"version": "0.93.19",
|
|
510
|
+
"resolved": "https://registry.npmjs.org/@caupulican/pi-agent-core/-/pi-agent-core-0.93.19.tgz",
|
|
511
511
|
"license": "MIT",
|
|
512
512
|
"dependencies": {
|
|
513
|
-
"@caupulican/pi-ai": "^0.93.
|
|
513
|
+
"@caupulican/pi-ai": "^0.93.19",
|
|
514
514
|
"ignore": "7.0.5",
|
|
515
515
|
"typebox": "1.1.38",
|
|
516
516
|
"yaml": "2.9.0"
|
|
@@ -520,8 +520,8 @@
|
|
|
520
520
|
}
|
|
521
521
|
},
|
|
522
522
|
"node_modules/@caupulican/pi-ai": {
|
|
523
|
-
"version": "0.93.
|
|
524
|
-
"resolved": "https://registry.npmjs.org/@caupulican/pi-ai/-/pi-ai-0.93.
|
|
523
|
+
"version": "0.93.19",
|
|
524
|
+
"resolved": "https://registry.npmjs.org/@caupulican/pi-ai/-/pi-ai-0.93.19.tgz",
|
|
525
525
|
"license": "MIT",
|
|
526
526
|
"dependencies": {
|
|
527
527
|
"@anthropic-ai/sdk": "0.117.1",
|
|
@@ -546,8 +546,8 @@
|
|
|
546
546
|
}
|
|
547
547
|
},
|
|
548
548
|
"node_modules/@caupulican/pi-tui": {
|
|
549
|
-
"version": "0.93.
|
|
550
|
-
"resolved": "https://registry.npmjs.org/@caupulican/pi-tui/-/pi-tui-0.93.
|
|
549
|
+
"version": "0.93.19",
|
|
550
|
+
"resolved": "https://registry.npmjs.org/@caupulican/pi-tui/-/pi-tui-0.93.19.tgz",
|
|
551
551
|
"license": "MIT",
|
|
552
552
|
"dependencies": {
|
|
553
553
|
"get-east-asian-width": "1.6.0",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@caupulican/pi-adaptative",
|
|
3
|
-
"version": "0.93.
|
|
3
|
+
"version": "0.93.19",
|
|
4
4
|
"description": "Adaptive fork of Pi coding agent for self-evolving agent harness experiments",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"piConfig": {
|
|
@@ -89,9 +89,9 @@
|
|
|
89
89
|
"postinstall": "node scripts/postinstall-python-runtime.mjs"
|
|
90
90
|
},
|
|
91
91
|
"dependencies": {
|
|
92
|
-
"@caupulican/pi-agent-core": "^0.93.
|
|
93
|
-
"@caupulican/pi-ai": "^0.93.
|
|
94
|
-
"@caupulican/pi-tui": "^0.93.
|
|
92
|
+
"@caupulican/pi-agent-core": "^0.93.19",
|
|
93
|
+
"@caupulican/pi-ai": "^0.93.19",
|
|
94
|
+
"@caupulican/pi-tui": "^0.93.19",
|
|
95
95
|
"@silvia-odwyer/photon-node": "0.3.4",
|
|
96
96
|
"chalk": "5.6.2",
|
|
97
97
|
"cross-spawn": "7.0.6",
|