@astralyn/pi 0.84.10 → 0.84.12
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 +27 -0
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +2 -1
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/core/agent-session.d.ts +62 -8
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +395 -78
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +4 -3
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +5 -0
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +19 -5
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +5 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +44 -1
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +18 -10
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +4 -2
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +8 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +17 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/tools/bash.d.ts +5 -0
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +5 -1
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/extensions/background/actions.d.ts +21 -0
- package/dist/extensions/background/actions.d.ts.map +1 -0
- package/dist/extensions/background/actions.js +264 -0
- package/dist/extensions/background/actions.js.map +1 -0
- package/dist/extensions/background/constants.d.ts +24 -0
- package/dist/extensions/background/constants.d.ts.map +1 -0
- package/dist/extensions/background/constants.js +24 -0
- package/dist/extensions/background/constants.js.map +1 -0
- package/dist/extensions/background/index.d.ts +6 -115
- package/dist/extensions/background/index.d.ts.map +1 -1
- package/dist/extensions/background/index.js +38 -509
- package/dist/extensions/background/index.js.map +1 -1
- package/dist/extensions/background/manager.d.ts +2 -1
- package/dist/extensions/background/manager.d.ts.map +1 -1
- package/dist/extensions/background/manager.js +8 -10
- package/dist/extensions/background/manager.js.map +1 -1
- package/dist/extensions/background/notify.d.ts +16 -0
- package/dist/extensions/background/notify.d.ts.map +1 -0
- package/dist/extensions/background/notify.js +114 -0
- package/dist/extensions/background/notify.js.map +1 -0
- package/dist/extensions/background/output-file.d.ts +58 -0
- package/dist/extensions/background/output-file.d.ts.map +1 -0
- package/dist/extensions/background/output-file.js +122 -0
- package/dist/extensions/background/output-file.js.map +1 -0
- package/dist/extensions/background/registry.d.ts +40 -72
- package/dist/extensions/background/registry.d.ts.map +1 -1
- package/dist/extensions/background/registry.js +71 -184
- package/dist/extensions/background/registry.js.map +1 -1
- package/dist/extensions/background/render.d.ts +3 -10
- package/dist/extensions/background/render.d.ts.map +1 -1
- package/dist/extensions/background/render.js +20 -60
- package/dist/extensions/background/render.js.map +1 -1
- package/dist/extensions/background/schema.d.ts +34 -0
- package/dist/extensions/background/schema.d.ts.map +1 -0
- package/dist/extensions/background/schema.js +89 -0
- package/dist/extensions/background/schema.js.map +1 -0
- package/dist/extensions/background/task-view.d.ts +48 -0
- package/dist/extensions/background/task-view.d.ts.map +1 -0
- package/dist/extensions/background/task-view.js +90 -0
- package/dist/extensions/background/task-view.js.map +1 -0
- package/dist/extensions/background/text.d.ts +15 -0
- package/dist/extensions/background/text.d.ts.map +1 -0
- package/dist/extensions/background/text.js +31 -0
- package/dist/extensions/background/text.js.map +1 -0
- package/dist/extensions/background/types.d.ts +74 -0
- package/dist/extensions/background/types.d.ts.map +1 -0
- package/dist/extensions/background/types.js +17 -0
- package/dist/extensions/background/types.js.map +1 -0
- package/dist/extensions/llama/client.d.ts +6 -0
- package/dist/extensions/llama/client.d.ts.map +1 -1
- package/dist/extensions/llama/client.js +7 -0
- package/dist/extensions/llama/client.js.map +1 -1
- package/dist/extensions/llama/provider.d.ts +3 -1
- package/dist/extensions/llama/provider.d.ts.map +1 -1
- package/dist/extensions/llama/provider.js +27 -6
- package/dist/extensions/llama/provider.js.map +1 -1
- package/dist/extensions/subagent/activity.d.ts +5 -0
- package/dist/extensions/subagent/activity.d.ts.map +1 -1
- package/dist/extensions/subagent/activity.js +5 -0
- package/dist/extensions/subagent/activity.js.map +1 -1
- package/dist/extensions/subagent/agents-command.d.ts.map +1 -1
- package/dist/extensions/subagent/agents-command.js +6 -391
- package/dist/extensions/subagent/agents-command.js.map +1 -1
- package/dist/extensions/subagent/constants.d.ts +1 -1
- package/dist/extensions/subagent/constants.d.ts.map +1 -1
- package/dist/extensions/subagent/constants.js +2 -1
- package/dist/extensions/subagent/constants.js.map +1 -1
- package/dist/extensions/subagent/index.js +2 -2
- package/dist/extensions/subagent/index.js.map +1 -1
- package/dist/extensions/subagent/render.d.ts +5 -5
- package/dist/extensions/subagent/render.d.ts.map +1 -1
- package/dist/extensions/subagent/render.js +106 -36
- package/dist/extensions/subagent/render.js.map +1 -1
- package/dist/extensions/subagent/resolve.d.ts.map +1 -1
- package/dist/extensions/subagent/resolve.js +2 -4
- package/dist/extensions/subagent/resolve.js.map +1 -1
- package/dist/extensions/subagent/runner.d.ts +1 -1
- package/dist/extensions/subagent/runner.d.ts.map +1 -1
- package/dist/extensions/subagent/runner.js +8 -8
- package/dist/extensions/subagent/runner.js.map +1 -1
- package/dist/extensions/subagent/sdk-runner.d.ts +11 -0
- package/dist/extensions/subagent/sdk-runner.d.ts.map +1 -1
- package/dist/extensions/subagent/sdk-runner.js +90 -79
- package/dist/extensions/subagent/sdk-runner.js.map +1 -1
- package/dist/extensions/subagent/state.d.ts.map +1 -1
- package/dist/extensions/subagent/state.js +145 -126
- package/dist/extensions/subagent/state.js.map +1 -1
- package/dist/extensions/subagent/text.d.ts.map +1 -1
- package/dist/extensions/subagent/text.js +4 -0
- package/dist/extensions/subagent/text.js.map +1 -1
- package/dist/extensions/subagent/ui/agents-dialog.d.ts +4 -0
- package/dist/extensions/subagent/ui/agents-dialog.d.ts.map +1 -0
- package/dist/extensions/subagent/ui/agents-dialog.js +84 -0
- package/dist/extensions/subagent/ui/agents-dialog.js.map +1 -0
- package/dist/extensions/subagent/ui/choice-menu.d.ts +39 -0
- package/dist/extensions/subagent/ui/choice-menu.d.ts.map +1 -0
- package/dist/extensions/subagent/ui/choice-menu.js +93 -0
- package/dist/extensions/subagent/ui/choice-menu.js.map +1 -0
- package/dist/extensions/subagent/ui/model-picker.d.ts +47 -0
- package/dist/extensions/subagent/ui/model-picker.d.ts.map +1 -0
- package/dist/extensions/subagent/ui/model-picker.js +142 -0
- package/dist/extensions/subagent/ui/model-picker.js.map +1 -0
- package/dist/extensions/subagent/ui/profile-settings-menu.d.ts +41 -0
- package/dist/extensions/subagent/ui/profile-settings-menu.d.ts.map +1 -0
- package/dist/extensions/subagent/ui/profile-settings-menu.js +98 -0
- package/dist/extensions/subagent/ui/profile-settings-menu.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +2 -0
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +2 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +10 -0
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +4 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +71 -58
- package/dist/modes/interactive/interactive-mode.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 +7 -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 +3 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +12 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +6 -4
- package/dist/utils/shell.js.map +1 -1
- package/docs/bundled/extensions/subagent.md +1 -1
- package/docs/compaction.md +5 -12
- package/docs/environment-variables.md +3 -0
- package/docs/extensions.md +21 -5
- package/docs/keybindings.md +1 -1
- package/docs/quickstart.md +1 -1
- package/docs/rpc.md +23 -0
- package/docs/settings.md +7 -0
- package/docs/terminal-setup.md +12 -0
- package/docs/usage.md +4 -3
- package/npm-shrinkwrap.json +29 -29
- package/package.json +6 -6
- package/dist/core/compaction-controller.d.ts +0 -90
- package/dist/core/compaction-controller.d.ts.map +0 -1
- package/dist/core/compaction-controller.js +0 -471
- package/dist/core/compaction-controller.js.map +0 -1
|
@@ -1,287 +1,12 @@
|
|
|
1
|
-
import { Container, isFocusable,
|
|
1
|
+
import { Container, isFocusable, } from "@earendil-works/pi-tui";
|
|
2
2
|
import { getAgentDir } from "../../config.js";
|
|
3
|
-
import { DynamicBorder } from "../../modes/interactive/components/dynamic-border.js";
|
|
4
|
-
import { keyLabel } from "../../modes/interactive/components/keybinding-hints.js";
|
|
5
3
|
import { AGENT_PROFILE_LABELS, AGENT_PROFILES } from "./agents.js";
|
|
6
4
|
import { loadSubagentConfig, updateProfileOverride } from "./settings.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
function refreshFailureMessage(providerIds) {
|
|
13
|
-
if (providerIds.length === 1)
|
|
14
|
-
return `Could not refresh ${providerIds[0]}; showing cached models.`;
|
|
15
|
-
const visible = providerIds.slice(0, 3);
|
|
16
|
-
const omitted = providerIds.length - visible.length;
|
|
17
|
-
const suffix = omitted > 0 ? `, +${omitted} more` : "";
|
|
18
|
-
return `Could not refresh ${providerIds.length} model catalogs (${visible.join(", ")}${suffix}); showing cached models.`;
|
|
19
|
-
}
|
|
20
|
-
function hint(theme, keybindings, binding, description) {
|
|
21
|
-
const key = keyLabel(binding, { keybindings });
|
|
22
|
-
return key ? `${theme.fg("dim", key)}${theme.fg("muted", ` ${description}`)}` : "";
|
|
23
|
-
}
|
|
24
|
-
function navigationHint(theme, keybindings) {
|
|
25
|
-
const keys = [keyLabel("tui.select.up", { keybindings }), keyLabel("tui.select.down", { keybindings })]
|
|
26
|
-
.filter(Boolean)
|
|
27
|
-
.join("/");
|
|
28
|
-
return keys ? `${theme.fg("dim", keys)}${theme.fg("muted", " navigate")}` : "";
|
|
29
|
-
}
|
|
30
|
-
/** Small Pi-native list page used inside the single /agents custom UI lifecycle. */
|
|
31
|
-
class ChoiceMenuComponent extends Container {
|
|
32
|
-
get focused() {
|
|
33
|
-
return this._focused;
|
|
34
|
-
}
|
|
35
|
-
set focused(value) {
|
|
36
|
-
this._focused = value;
|
|
37
|
-
}
|
|
38
|
-
constructor(options) {
|
|
39
|
-
super();
|
|
40
|
-
this._focused = false;
|
|
41
|
-
this.theme = options.theme;
|
|
42
|
-
this.keybindings = options.keybindings;
|
|
43
|
-
this.choices = options.choices;
|
|
44
|
-
this.onDone = options.onDone;
|
|
45
|
-
this.title = options.title;
|
|
46
|
-
this.cancelDescription = options.cancelDescription;
|
|
47
|
-
this.selectedIndex = Math.min(Math.max(options.initialIndex ?? 0, 0), Math.max(0, options.choices.length - 1));
|
|
48
|
-
this.addChild(new DynamicBorder());
|
|
49
|
-
this.addChild(new Spacer(1));
|
|
50
|
-
this.titleText = new Text("", 1, 0);
|
|
51
|
-
this.addChild(this.titleText);
|
|
52
|
-
this.addChild(new Spacer(1));
|
|
53
|
-
this.listContainer = new Container();
|
|
54
|
-
this.addChild(this.listContainer);
|
|
55
|
-
this.addChild(new Spacer(1));
|
|
56
|
-
this.hintText = new Text("", 1, 0);
|
|
57
|
-
this.addChild(this.hintText);
|
|
58
|
-
this.addChild(new Spacer(1));
|
|
59
|
-
this.addChild(new DynamicBorder());
|
|
60
|
-
this.updateStaticText();
|
|
61
|
-
this.updateList();
|
|
62
|
-
}
|
|
63
|
-
updateStaticText() {
|
|
64
|
-
this.titleText.setText(this.theme.fg("accent", this.theme.bold(this.title)));
|
|
65
|
-
const hints = [
|
|
66
|
-
navigationHint(this.theme, this.keybindings),
|
|
67
|
-
hint(this.theme, this.keybindings, "tui.select.confirm", "select"),
|
|
68
|
-
hint(this.theme, this.keybindings, "tui.select.cancel", this.cancelDescription),
|
|
69
|
-
].filter(Boolean);
|
|
70
|
-
this.hintText.setText(hints.join(this.theme.fg("muted", " • ")));
|
|
71
|
-
}
|
|
72
|
-
updateList() {
|
|
73
|
-
this.listContainer.clear();
|
|
74
|
-
for (const [index, choice] of this.choices.entries()) {
|
|
75
|
-
const selected = index === this.selectedIndex;
|
|
76
|
-
const prefix = selected ? this.theme.fg("accent", "→ ") : " ";
|
|
77
|
-
const label = this.theme.fg(selected ? "accent" : "text", choice.label);
|
|
78
|
-
this.listContainer.addChild(new TruncatedText(`${prefix}${label}`, 1, 0));
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
moveSelection(offset) {
|
|
82
|
-
if (this.choices.length === 0)
|
|
83
|
-
return;
|
|
84
|
-
this.selectedIndex = (this.selectedIndex + offset + this.choices.length) % this.choices.length;
|
|
85
|
-
this.updateList();
|
|
86
|
-
}
|
|
87
|
-
invalidate() {
|
|
88
|
-
this.updateStaticText();
|
|
89
|
-
this.updateList();
|
|
90
|
-
super.invalidate();
|
|
91
|
-
}
|
|
92
|
-
handleInput(data) {
|
|
93
|
-
if (this.keybindings.matches(data, "tui.select.up")) {
|
|
94
|
-
this.moveSelection(-1);
|
|
95
|
-
}
|
|
96
|
-
else if (this.keybindings.matches(data, "tui.select.down")) {
|
|
97
|
-
this.moveSelection(1);
|
|
98
|
-
}
|
|
99
|
-
else if (this.keybindings.matches(data, "tui.select.confirm")) {
|
|
100
|
-
const choice = this.choices[this.selectedIndex];
|
|
101
|
-
if (choice)
|
|
102
|
-
this.onDone(choice);
|
|
103
|
-
}
|
|
104
|
-
else if (this.keybindings.matches(data, "tui.select.cancel")) {
|
|
105
|
-
this.onDone(undefined);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
/** Compact Model/Thinking settings menu for one profile; every confirm persists immediately. */
|
|
110
|
-
class ProfileSettingsMenuComponent extends Container {
|
|
111
|
-
get focused() {
|
|
112
|
-
return this._focused;
|
|
113
|
-
}
|
|
114
|
-
set focused(value) {
|
|
115
|
-
this._focused = value;
|
|
116
|
-
}
|
|
117
|
-
constructor(options) {
|
|
118
|
-
super();
|
|
119
|
-
this.selectedIndex = 0;
|
|
120
|
-
this._focused = false;
|
|
121
|
-
this.theme = options.theme;
|
|
122
|
-
this.keybindings = options.keybindings;
|
|
123
|
-
this.onDone = options.onDone;
|
|
124
|
-
this.title = AGENT_PROFILE_LABELS[options.profile.name];
|
|
125
|
-
this.status = options.status;
|
|
126
|
-
this.rows = buildSettingsRows({
|
|
127
|
-
override: options.override,
|
|
128
|
-
models: options.models,
|
|
129
|
-
currentSessionModel: options.currentSessionModel,
|
|
130
|
-
currentThinking: options.currentThinking,
|
|
131
|
-
});
|
|
132
|
-
this.selectedIndex = Math.max(0, this.rows.findIndex((row) => row.action === options.selectedAction));
|
|
133
|
-
this.addChild(new DynamicBorder());
|
|
134
|
-
this.addChild(new Spacer(1));
|
|
135
|
-
this.titleText = new Text("", 1, 0);
|
|
136
|
-
this.addChild(this.titleText);
|
|
137
|
-
this.addChild(new Spacer(1));
|
|
138
|
-
this.listContainer = new Container();
|
|
139
|
-
this.addChild(this.listContainer);
|
|
140
|
-
this.addChild(new Spacer(1));
|
|
141
|
-
if (this.status) {
|
|
142
|
-
this.statusText = new Text("", 1, 0);
|
|
143
|
-
this.addChild(this.statusText);
|
|
144
|
-
this.addChild(new Spacer(1));
|
|
145
|
-
}
|
|
146
|
-
else {
|
|
147
|
-
this.statusText = undefined;
|
|
148
|
-
}
|
|
149
|
-
this.hintText = new Text("", 1, 0);
|
|
150
|
-
this.addChild(this.hintText);
|
|
151
|
-
this.addChild(new Spacer(1));
|
|
152
|
-
this.addChild(new DynamicBorder());
|
|
153
|
-
this.updateStaticText();
|
|
154
|
-
this.updateList();
|
|
155
|
-
}
|
|
156
|
-
updateStaticText() {
|
|
157
|
-
this.titleText.setText(this.theme.fg("accent", this.theme.bold(this.title)));
|
|
158
|
-
this.statusText?.setText(this.theme.fg("muted", this.status ?? ""));
|
|
159
|
-
const hints = [
|
|
160
|
-
navigationHint(this.theme, this.keybindings),
|
|
161
|
-
hint(this.theme, this.keybindings, "tui.select.confirm", "select"),
|
|
162
|
-
hint(this.theme, this.keybindings, "tui.select.cancel", "back"),
|
|
163
|
-
].filter(Boolean);
|
|
164
|
-
this.hintText.setText(hints.join(this.theme.fg("muted", " • ")));
|
|
165
|
-
}
|
|
166
|
-
updateList() {
|
|
167
|
-
this.listContainer.clear();
|
|
168
|
-
for (const [index, row] of this.rows.entries()) {
|
|
169
|
-
const selected = index === this.selectedIndex;
|
|
170
|
-
const prefix = selected ? this.theme.fg("accent", "→ ") : " ";
|
|
171
|
-
const label = selected ? this.theme.fg("accent", row.label) : this.theme.fg("text", row.label);
|
|
172
|
-
const value = this.theme.fg("muted", `— ${row.value}`);
|
|
173
|
-
const checkmark = row.override ? this.theme.fg("success", " ✓") : "";
|
|
174
|
-
this.listContainer.addChild(new TruncatedText(`${prefix}${label} ${value}${checkmark}`, 1, 0));
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
moveSelection(offset) {
|
|
178
|
-
this.selectedIndex = (this.selectedIndex + offset + this.rows.length) % this.rows.length;
|
|
179
|
-
this.updateList();
|
|
180
|
-
}
|
|
181
|
-
invalidate() {
|
|
182
|
-
this.updateStaticText();
|
|
183
|
-
this.updateList();
|
|
184
|
-
super.invalidate();
|
|
185
|
-
}
|
|
186
|
-
handleInput(data) {
|
|
187
|
-
if (this.keybindings.matches(data, "tui.select.up")) {
|
|
188
|
-
this.moveSelection(-1);
|
|
189
|
-
}
|
|
190
|
-
else if (this.keybindings.matches(data, "tui.select.down")) {
|
|
191
|
-
this.moveSelection(1);
|
|
192
|
-
}
|
|
193
|
-
else if (this.keybindings.matches(data, "tui.select.confirm")) {
|
|
194
|
-
this.onDone(this.rows[this.selectedIndex]?.action);
|
|
195
|
-
}
|
|
196
|
-
else if (this.keybindings.matches(data, "tui.select.cancel")) {
|
|
197
|
-
this.onDone(undefined);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
/** Searchable model page for one profile; confirm saves immediately. */
|
|
202
|
-
class ModelPickerComponent extends Container {
|
|
203
|
-
get focused() {
|
|
204
|
-
return this._focused;
|
|
205
|
-
}
|
|
206
|
-
set focused(value) {
|
|
207
|
-
this._focused = value;
|
|
208
|
-
this.modelList.focused = value;
|
|
209
|
-
}
|
|
210
|
-
constructor(options) {
|
|
211
|
-
super();
|
|
212
|
-
this.refreshAbortController = new AbortController();
|
|
213
|
-
this.closed = false;
|
|
214
|
-
this._focused = false;
|
|
215
|
-
this.tui = options.tui;
|
|
216
|
-
this.theme = options.theme;
|
|
217
|
-
this.keybindings = options.keybindings;
|
|
218
|
-
this.title = `Model — ${AGENT_PROFILE_LABELS[options.profile.name]}`;
|
|
219
|
-
this.hasScopedModels = options.scopedModels.length > 0;
|
|
220
|
-
this.addChild(new DynamicBorder());
|
|
221
|
-
this.addChild(new Spacer(1));
|
|
222
|
-
this.titleText = new Text("", 1, 0);
|
|
223
|
-
this.addChild(this.titleText);
|
|
224
|
-
this.addChild(new Spacer(1));
|
|
225
|
-
this.modelList = new ProfileModelListComponent({
|
|
226
|
-
theme: options.theme,
|
|
227
|
-
keybindings: options.keybindings,
|
|
228
|
-
models: options.models,
|
|
229
|
-
scopedModels: options.scopedModels,
|
|
230
|
-
currentSessionModel: options.currentSessionModel,
|
|
231
|
-
savedModelId: options.savedModelId,
|
|
232
|
-
onDone: options.onDone,
|
|
233
|
-
});
|
|
234
|
-
this.addChild(this.modelList);
|
|
235
|
-
this.addChild(new Spacer(1));
|
|
236
|
-
this.hintText = new Text("", 1, 0);
|
|
237
|
-
this.addChild(this.hintText);
|
|
238
|
-
this.addChild(new Spacer(1));
|
|
239
|
-
this.addChild(new DynamicBorder());
|
|
240
|
-
this.updateStaticText();
|
|
241
|
-
}
|
|
242
|
-
updateStaticText() {
|
|
243
|
-
this.titleText.setText(this.theme.fg("accent", this.theme.bold(this.title)));
|
|
244
|
-
const hints = [
|
|
245
|
-
navigationHint(this.theme, this.keybindings),
|
|
246
|
-
this.hasScopedModels ? hint(this.theme, this.keybindings, "tui.input.tab", "scope") : "",
|
|
247
|
-
hint(this.theme, this.keybindings, "tui.select.confirm", "select"),
|
|
248
|
-
hint(this.theme, this.keybindings, "tui.select.cancel", "back"),
|
|
249
|
-
].filter(Boolean);
|
|
250
|
-
this.hintText.setText(hints.join(this.theme.fg("muted", " • ")));
|
|
251
|
-
}
|
|
252
|
-
get refreshSignal() {
|
|
253
|
-
return this.refreshAbortController.signal;
|
|
254
|
-
}
|
|
255
|
-
cancelRefresh() {
|
|
256
|
-
this.refreshAbortController.abort();
|
|
257
|
-
}
|
|
258
|
-
get isClosed() {
|
|
259
|
-
return this.closed;
|
|
260
|
-
}
|
|
261
|
-
dispose() {
|
|
262
|
-
this.closed = true;
|
|
263
|
-
this.refreshAbortController.abort();
|
|
264
|
-
}
|
|
265
|
-
updateModels(models) {
|
|
266
|
-
if (this.closed)
|
|
267
|
-
return;
|
|
268
|
-
this.modelList.updateModels(models);
|
|
269
|
-
this.tui.requestRender();
|
|
270
|
-
}
|
|
271
|
-
setRefreshStatus(message, tone = "muted") {
|
|
272
|
-
if (this.closed)
|
|
273
|
-
return;
|
|
274
|
-
this.modelList.setStatus(message, tone);
|
|
275
|
-
this.tui.requestRender();
|
|
276
|
-
}
|
|
277
|
-
invalidate() {
|
|
278
|
-
this.updateStaticText();
|
|
279
|
-
super.invalidate();
|
|
280
|
-
}
|
|
281
|
-
handleInput(data) {
|
|
282
|
-
this.modelList.handleInput(data);
|
|
283
|
-
}
|
|
284
|
-
}
|
|
5
|
+
import { showDialogAgentsCommand } from "./ui/agents-dialog.js";
|
|
6
|
+
import { ChoiceMenuComponent } from "./ui/choice-menu.js";
|
|
7
|
+
import { buildThinkingChoices } from "./ui/choices.js";
|
|
8
|
+
import { ModelPickerComponent, refreshPickerModels } from "./ui/model-picker.js";
|
|
9
|
+
import { ProfileSettingsMenuComponent } from "./ui/profile-settings-menu.js";
|
|
285
10
|
/** Persist a single override atomically; the UI only reflects the value on success. */
|
|
286
11
|
async function persistOverride(ctx, profile, patch) {
|
|
287
12
|
try {
|
|
@@ -292,46 +17,6 @@ async function persistOverride(ctx, profile, patch) {
|
|
|
292
17
|
return undefined;
|
|
293
18
|
}
|
|
294
19
|
}
|
|
295
|
-
async function refreshPickerModels(ctx, picker) {
|
|
296
|
-
let timedOut = false;
|
|
297
|
-
const timeout = setTimeout(() => {
|
|
298
|
-
timedOut = true;
|
|
299
|
-
picker.cancelRefresh();
|
|
300
|
-
}, MODEL_REFRESH_TIMEOUT_MS);
|
|
301
|
-
timeout.unref?.();
|
|
302
|
-
try {
|
|
303
|
-
const result = await ctx.modelRegistry.refresh({ signal: picker.refreshSignal });
|
|
304
|
-
if (picker.isClosed || (picker.refreshSignal.aborted && !timedOut))
|
|
305
|
-
return;
|
|
306
|
-
picker.updateModels(ctx.modelRegistry.getAvailable());
|
|
307
|
-
if (result.aborted && timedOut) {
|
|
308
|
-
picker.setRefreshStatus("Model refresh timed out; showing cached models.", "error");
|
|
309
|
-
return;
|
|
310
|
-
}
|
|
311
|
-
const providerIds = [...result.errors.keys()];
|
|
312
|
-
if (providerIds.length > 0) {
|
|
313
|
-
picker.setRefreshStatus(refreshFailureMessage(providerIds), "error");
|
|
314
|
-
return;
|
|
315
|
-
}
|
|
316
|
-
const registryError = ctx.modelRegistry.getError();
|
|
317
|
-
if (registryError) {
|
|
318
|
-
picker.setRefreshStatus(truncate(registryError, MAX_REFRESH_ERROR_LENGTH), "error");
|
|
319
|
-
return;
|
|
320
|
-
}
|
|
321
|
-
picker.setRefreshStatus(undefined);
|
|
322
|
-
}
|
|
323
|
-
catch (error) {
|
|
324
|
-
if (picker.isClosed || (picker.refreshSignal.aborted && !timedOut))
|
|
325
|
-
return;
|
|
326
|
-
const message = timedOut
|
|
327
|
-
? "Model refresh timed out; showing cached models."
|
|
328
|
-
: `Could not refresh model catalogs: ${error instanceof Error ? error.message : String(error)}`;
|
|
329
|
-
picker.setRefreshStatus(truncate(message, MAX_REFRESH_ERROR_LENGTH), "error");
|
|
330
|
-
}
|
|
331
|
-
finally {
|
|
332
|
-
clearTimeout(timeout);
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
20
|
/** One mounted /agents TUI whose child pages switch without restoring the editor between them. */
|
|
336
21
|
class AgentsMenuComponent extends Container {
|
|
337
22
|
get focused() {
|
|
@@ -520,68 +205,6 @@ class AgentsMenuComponent extends Container {
|
|
|
520
205
|
this.clear();
|
|
521
206
|
}
|
|
522
207
|
}
|
|
523
|
-
async function selectProfile(ctx) {
|
|
524
|
-
const labels = AGENT_PROFILES.map((profile) => AGENT_PROFILE_LABELS[profile.name]);
|
|
525
|
-
const label = await ctx.ui.select("Agents", labels);
|
|
526
|
-
return label === undefined
|
|
527
|
-
? undefined
|
|
528
|
-
: AGENT_PROFILES.find((profile) => AGENT_PROFILE_LABELS[profile.name] === label);
|
|
529
|
-
}
|
|
530
|
-
async function showDialogSettingsMenu(ctx, profile, override, currentThinking) {
|
|
531
|
-
const options = new Map();
|
|
532
|
-
for (const row of buildSettingsRows({
|
|
533
|
-
override,
|
|
534
|
-
models: ctx.modelRegistry.getAvailable(),
|
|
535
|
-
currentSessionModel: ctx.model,
|
|
536
|
-
currentThinking,
|
|
537
|
-
})) {
|
|
538
|
-
options.set(`${row.label} — ${row.value}`, row.action);
|
|
539
|
-
}
|
|
540
|
-
const label = await ctx.ui.select(AGENT_PROFILE_LABELS[profile.name], [...options.keys()]);
|
|
541
|
-
return label === undefined ? undefined : options.get(label);
|
|
542
|
-
}
|
|
543
|
-
async function showDialogModelPicker(ctx, profile, override) {
|
|
544
|
-
const models = [...ctx.modelRegistry.getAvailable()].sort(compareModels);
|
|
545
|
-
const choices = buildModelChoices({
|
|
546
|
-
models,
|
|
547
|
-
currentSessionModel: ctx.model,
|
|
548
|
-
savedModelId: override?.model,
|
|
549
|
-
});
|
|
550
|
-
const label = await ctx.ui.select(`Model — ${AGENT_PROFILE_LABELS[profile.name]}`, [...choices.keys()]);
|
|
551
|
-
return label === undefined ? undefined : { modelId: choices.get(label) };
|
|
552
|
-
}
|
|
553
|
-
async function showDialogThinkingPicker(ctx, profile, override, currentThinking) {
|
|
554
|
-
const choices = buildThinkingChoices({
|
|
555
|
-
currentSessionModel: ctx.model,
|
|
556
|
-
models: ctx.modelRegistry.getAvailable(),
|
|
557
|
-
override,
|
|
558
|
-
currentThinking,
|
|
559
|
-
});
|
|
560
|
-
const label = await ctx.ui.select(`Thinking — ${AGENT_PROFILE_LABELS[profile.name]}`, [...choices.keys()]);
|
|
561
|
-
return label === undefined ? undefined : { level: choices.get(label) };
|
|
562
|
-
}
|
|
563
|
-
async function runDialogProfileSettings(ctx, profile, currentThinking) {
|
|
564
|
-
const agentDir = getAgentDir();
|
|
565
|
-
while (true) {
|
|
566
|
-
const config = await loadSubagentConfig(agentDir);
|
|
567
|
-
const override = config.profiles[profile.name];
|
|
568
|
-
const action = await showDialogSettingsMenu(ctx, profile, override, currentThinking);
|
|
569
|
-
if (!action)
|
|
570
|
-
return;
|
|
571
|
-
if (action === "model") {
|
|
572
|
-
const chosen = await showDialogModelPicker(ctx, profile, override);
|
|
573
|
-
if (!chosen)
|
|
574
|
-
continue;
|
|
575
|
-
await persistOverride(ctx, profile, { model: chosen.modelId });
|
|
576
|
-
}
|
|
577
|
-
else {
|
|
578
|
-
const chosen = await showDialogThinkingPicker(ctx, profile, override, currentThinking);
|
|
579
|
-
if (!chosen)
|
|
580
|
-
continue;
|
|
581
|
-
await persistOverride(ctx, profile, { thinking: chosen.level });
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
}
|
|
585
208
|
async function showTuiAgentsCommand(ctx, currentThinking) {
|
|
586
209
|
const config = await loadSubagentConfig(getAgentDir());
|
|
587
210
|
await ctx.ui.custom((tui, theme, keybindings, done) => new AgentsMenuComponent({
|
|
@@ -594,14 +217,6 @@ async function showTuiAgentsCommand(ctx, currentThinking) {
|
|
|
594
217
|
onDone: () => done(),
|
|
595
218
|
}));
|
|
596
219
|
}
|
|
597
|
-
async function showDialogAgentsCommand(ctx, currentThinking) {
|
|
598
|
-
while (true) {
|
|
599
|
-
const profile = await selectProfile(ctx);
|
|
600
|
-
if (!profile)
|
|
601
|
-
return;
|
|
602
|
-
await runDialogProfileSettings(ctx, profile, currentThinking);
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
220
|
export async function showAgentsCommand(ctx, currentThinking) {
|
|
606
221
|
if (!ctx.hasUI) {
|
|
607
222
|
ctx.ui.notify("/agents requires an interactive UI.", "warning");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents-command.js","sourceRoot":"","sources":["../../../src/extensions/subagent/agents-command.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport type { Api, Model } from \"@earendil-works/pi-ai\";\nimport {\n\ttype Component,\n\tContainer,\n\ttype Focusable,\n\tisFocusable,\n\ttype KeybindingsManager,\n\tSpacer,\n\tText,\n\tTruncatedText,\n\ttype TUI,\n} from \"@earendil-works/pi-tui\";\nimport { getAgentDir } from \"../../config.ts\";\nimport type { ExtensionCommandContext } from \"../../core/extensions/types.ts\";\nimport { DynamicBorder } from \"../../modes/interactive/components/dynamic-border.ts\";\nimport { keyLabel } from \"../../modes/interactive/components/keybinding-hints.ts\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { AGENT_PROFILE_LABELS, AGENT_PROFILES } from \"./agents.ts\";\nimport { loadSubagentConfig, updateProfileOverride } from \"./settings.ts\";\nimport { truncate } from \"./text.ts\";\nimport type { AgentProfile, SubagentConfigFile, SubagentProfileOverride } from \"./types.ts\";\nimport {\n\tbuildModelChoices,\n\tbuildSettingsRows,\n\tbuildThinkingChoices,\n\tcompareModels,\n\ttype SettingsAction,\n\ttype SettingsRow,\n} from \"./ui/choices.ts\";\nimport { type ProfileModelChoice, ProfileModelListComponent } from \"./ui/model-list.ts\";\n\nconst MODEL_REFRESH_TIMEOUT_MS = 15_000;\nconst MAX_REFRESH_ERROR_LENGTH = 240;\n\nfunction refreshFailureMessage(providerIds: readonly string[]): string {\n\tif (providerIds.length === 1) return `Could not refresh ${providerIds[0]}; showing cached models.`;\n\tconst visible = providerIds.slice(0, 3);\n\tconst omitted = providerIds.length - visible.length;\n\tconst suffix = omitted > 0 ? `, +${omitted} more` : \"\";\n\treturn `Could not refresh ${providerIds.length} model catalogs (${visible.join(\", \")}${suffix}); showing cached models.`;\n}\n\nfunction hint(\n\ttheme: Theme,\n\tkeybindings: KeybindingsManager,\n\tbinding: Parameters<KeybindingsManager[\"getKeys\"]>[0],\n\tdescription: string,\n): string {\n\tconst key = keyLabel(binding, { keybindings });\n\treturn key ? `${theme.fg(\"dim\", key)}${theme.fg(\"muted\", ` ${description}`)}` : \"\";\n}\n\nfunction navigationHint(theme: Theme, keybindings: KeybindingsManager): string {\n\tconst keys = [keyLabel(\"tui.select.up\", { keybindings }), keyLabel(\"tui.select.down\", { keybindings })]\n\t\t.filter(Boolean)\n\t\t.join(\"/\");\n\treturn keys ? `${theme.fg(\"dim\", keys)}${theme.fg(\"muted\", \" navigate\")}` : \"\";\n}\n\ninterface MenuChoice<T> {\n\tlabel: string;\n\tvalue: T;\n}\n\n/** Small Pi-native list page used inside the single /agents custom UI lifecycle. */\nclass ChoiceMenuComponent<T> extends Container implements Focusable {\n\tprivate readonly theme: Theme;\n\tprivate readonly keybindings: KeybindingsManager;\n\tprivate readonly choices: readonly MenuChoice<T>[];\n\tprivate readonly onDone: (choice: MenuChoice<T> | undefined) => void;\n\tprivate readonly title: string;\n\tprivate readonly cancelDescription: \"back\" | \"close\";\n\tprivate readonly titleText: Text;\n\tprivate readonly hintText: Text;\n\tprivate readonly listContainer: Container;\n\tprivate selectedIndex: number;\n\tprivate _focused = false;\n\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t}\n\n\tconstructor(options: {\n\t\ttheme: Theme;\n\t\tkeybindings: KeybindingsManager;\n\t\ttitle: string;\n\t\tchoices: readonly MenuChoice<T>[];\n\t\tonDone: (choice: MenuChoice<T> | undefined) => void;\n\t\tinitialIndex?: number;\n\t\tcancelDescription: \"back\" | \"close\";\n\t}) {\n\t\tsuper();\n\t\tthis.theme = options.theme;\n\t\tthis.keybindings = options.keybindings;\n\t\tthis.choices = options.choices;\n\t\tthis.onDone = options.onDone;\n\t\tthis.title = options.title;\n\t\tthis.cancelDescription = options.cancelDescription;\n\t\tthis.selectedIndex = Math.min(Math.max(options.initialIndex ?? 0, 0), Math.max(0, options.choices.length - 1));\n\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.titleText = new Text(\"\", 1, 0);\n\t\tthis.addChild(this.titleText);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.listContainer = new Container();\n\t\tthis.addChild(this.listContainer);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.hintText = new Text(\"\", 1, 0);\n\t\tthis.addChild(this.hintText);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.updateStaticText();\n\t\tthis.updateList();\n\t}\n\n\tprivate updateStaticText(): void {\n\t\tthis.titleText.setText(this.theme.fg(\"accent\", this.theme.bold(this.title)));\n\t\tconst hints = [\n\t\t\tnavigationHint(this.theme, this.keybindings),\n\t\t\thint(this.theme, this.keybindings, \"tui.select.confirm\", \"select\"),\n\t\t\thint(this.theme, this.keybindings, \"tui.select.cancel\", this.cancelDescription),\n\t\t].filter(Boolean);\n\t\tthis.hintText.setText(hints.join(this.theme.fg(\"muted\", \" • \")));\n\t}\n\n\tprivate updateList(): void {\n\t\tthis.listContainer.clear();\n\t\tfor (const [index, choice] of this.choices.entries()) {\n\t\t\tconst selected = index === this.selectedIndex;\n\t\t\tconst prefix = selected ? this.theme.fg(\"accent\", \"→ \") : \" \";\n\t\t\tconst label = this.theme.fg(selected ? \"accent\" : \"text\", choice.label);\n\t\t\tthis.listContainer.addChild(new TruncatedText(`${prefix}${label}`, 1, 0));\n\t\t}\n\t}\n\n\tprivate moveSelection(offset: -1 | 1): void {\n\t\tif (this.choices.length === 0) return;\n\t\tthis.selectedIndex = (this.selectedIndex + offset + this.choices.length) % this.choices.length;\n\t\tthis.updateList();\n\t}\n\n\toverride invalidate(): void {\n\t\tthis.updateStaticText();\n\t\tthis.updateList();\n\t\tsuper.invalidate();\n\t}\n\n\thandleInput(data: string): void {\n\t\tif (this.keybindings.matches(data, \"tui.select.up\")) {\n\t\t\tthis.moveSelection(-1);\n\t\t} else if (this.keybindings.matches(data, \"tui.select.down\")) {\n\t\t\tthis.moveSelection(1);\n\t\t} else if (this.keybindings.matches(data, \"tui.select.confirm\")) {\n\t\t\tconst choice = this.choices[this.selectedIndex];\n\t\t\tif (choice) this.onDone(choice);\n\t\t} else if (this.keybindings.matches(data, \"tui.select.cancel\")) {\n\t\t\tthis.onDone(undefined);\n\t\t}\n\t}\n}\n\n/** Compact Model/Thinking settings menu for one profile; every confirm persists immediately. */\nclass ProfileSettingsMenuComponent extends Container implements Focusable {\n\tprivate readonly theme: Theme;\n\tprivate readonly keybindings: KeybindingsManager;\n\tprivate readonly rows: readonly SettingsRow[];\n\tprivate readonly onDone: (action: SettingsAction | undefined) => void;\n\tprivate readonly title: string;\n\tprivate readonly status: string | undefined;\n\tprivate readonly titleText: Text;\n\tprivate readonly statusText: Text | undefined;\n\tprivate readonly hintText: Text;\n\tprivate readonly listContainer: Container;\n\tprivate selectedIndex = 0;\n\tprivate _focused = false;\n\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t}\n\n\tconstructor(options: {\n\t\ttheme: Theme;\n\t\tkeybindings: KeybindingsManager;\n\t\tprofile: AgentProfile;\n\t\toverride: SubagentProfileOverride | undefined;\n\t\tmodels: readonly Model<Api>[];\n\t\tcurrentSessionModel: Model<Api> | undefined;\n\t\tcurrentThinking: ThinkingLevel;\n\t\tselectedAction?: SettingsAction;\n\t\tstatus?: string;\n\t\tonDone: (action: SettingsAction | undefined) => void;\n\t}) {\n\t\tsuper();\n\t\tthis.theme = options.theme;\n\t\tthis.keybindings = options.keybindings;\n\t\tthis.onDone = options.onDone;\n\t\tthis.title = AGENT_PROFILE_LABELS[options.profile.name];\n\t\tthis.status = options.status;\n\t\tthis.rows = buildSettingsRows({\n\t\t\toverride: options.override,\n\t\t\tmodels: options.models,\n\t\t\tcurrentSessionModel: options.currentSessionModel,\n\t\t\tcurrentThinking: options.currentThinking,\n\t\t}) satisfies SettingsRow[];\n\t\tthis.selectedIndex = Math.max(\n\t\t\t0,\n\t\t\tthis.rows.findIndex((row) => row.action === options.selectedAction),\n\t\t);\n\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.titleText = new Text(\"\", 1, 0);\n\t\tthis.addChild(this.titleText);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.listContainer = new Container();\n\t\tthis.addChild(this.listContainer);\n\t\tthis.addChild(new Spacer(1));\n\t\tif (this.status) {\n\t\t\tthis.statusText = new Text(\"\", 1, 0);\n\t\t\tthis.addChild(this.statusText);\n\t\t\tthis.addChild(new Spacer(1));\n\t\t} else {\n\t\t\tthis.statusText = undefined;\n\t\t}\n\t\tthis.hintText = new Text(\"\", 1, 0);\n\t\tthis.addChild(this.hintText);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.updateStaticText();\n\t\tthis.updateList();\n\t}\n\n\tprivate updateStaticText(): void {\n\t\tthis.titleText.setText(this.theme.fg(\"accent\", this.theme.bold(this.title)));\n\t\tthis.statusText?.setText(this.theme.fg(\"muted\", this.status ?? \"\"));\n\t\tconst hints = [\n\t\t\tnavigationHint(this.theme, this.keybindings),\n\t\t\thint(this.theme, this.keybindings, \"tui.select.confirm\", \"select\"),\n\t\t\thint(this.theme, this.keybindings, \"tui.select.cancel\", \"back\"),\n\t\t].filter(Boolean);\n\t\tthis.hintText.setText(hints.join(this.theme.fg(\"muted\", \" • \")));\n\t}\n\n\tprivate updateList(): void {\n\t\tthis.listContainer.clear();\n\t\tfor (const [index, row] of this.rows.entries()) {\n\t\t\tconst selected = index === this.selectedIndex;\n\t\t\tconst prefix = selected ? this.theme.fg(\"accent\", \"→ \") : \" \";\n\t\t\tconst label = selected ? this.theme.fg(\"accent\", row.label) : this.theme.fg(\"text\", row.label);\n\t\t\tconst value = this.theme.fg(\"muted\", `— ${row.value}`);\n\t\t\tconst checkmark = row.override ? this.theme.fg(\"success\", \" ✓\") : \"\";\n\t\t\tthis.listContainer.addChild(new TruncatedText(`${prefix}${label} ${value}${checkmark}`, 1, 0));\n\t\t}\n\t}\n\n\tprivate moveSelection(offset: -1 | 1): void {\n\t\tthis.selectedIndex = (this.selectedIndex + offset + this.rows.length) % this.rows.length;\n\t\tthis.updateList();\n\t}\n\n\toverride invalidate(): void {\n\t\tthis.updateStaticText();\n\t\tthis.updateList();\n\t\tsuper.invalidate();\n\t}\n\n\thandleInput(data: string): void {\n\t\tif (this.keybindings.matches(data, \"tui.select.up\")) {\n\t\t\tthis.moveSelection(-1);\n\t\t} else if (this.keybindings.matches(data, \"tui.select.down\")) {\n\t\t\tthis.moveSelection(1);\n\t\t} else if (this.keybindings.matches(data, \"tui.select.confirm\")) {\n\t\t\tthis.onDone(this.rows[this.selectedIndex]?.action);\n\t\t} else if (this.keybindings.matches(data, \"tui.select.cancel\")) {\n\t\t\tthis.onDone(undefined);\n\t\t}\n\t}\n}\n\n/** Searchable model page for one profile; confirm saves immediately. */\nclass ModelPickerComponent extends Container implements Focusable {\n\tprivate readonly tui: TUI;\n\tprivate readonly theme: Theme;\n\tprivate readonly keybindings: KeybindingsManager;\n\tprivate readonly title: string;\n\tprivate readonly hasScopedModels: boolean;\n\tprivate readonly titleText: Text;\n\tprivate readonly hintText: Text;\n\tprivate readonly modelList: ProfileModelListComponent;\n\tprivate readonly refreshAbortController = new AbortController();\n\tprivate closed = false;\n\tprivate _focused = false;\n\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.modelList.focused = value;\n\t}\n\n\tconstructor(options: {\n\t\ttui: TUI;\n\t\ttheme: Theme;\n\t\tkeybindings: KeybindingsManager;\n\t\tprofile: AgentProfile;\n\t\tsavedModelId: string | undefined;\n\t\tmodels: readonly Model<Api>[];\n\t\tscopedModels: readonly { model: Model<Api> }[];\n\t\tcurrentSessionModel: Model<Api> | undefined;\n\t\tonDone: (choice: ProfileModelChoice | undefined) => void;\n\t}) {\n\t\tsuper();\n\t\tthis.tui = options.tui;\n\t\tthis.theme = options.theme;\n\t\tthis.keybindings = options.keybindings;\n\t\tthis.title = `Model — ${AGENT_PROFILE_LABELS[options.profile.name]}`;\n\t\tthis.hasScopedModels = options.scopedModels.length > 0;\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.titleText = new Text(\"\", 1, 0);\n\t\tthis.addChild(this.titleText);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.modelList = new ProfileModelListComponent({\n\t\t\ttheme: options.theme,\n\t\t\tkeybindings: options.keybindings,\n\t\t\tmodels: options.models,\n\t\t\tscopedModels: options.scopedModels,\n\t\t\tcurrentSessionModel: options.currentSessionModel,\n\t\t\tsavedModelId: options.savedModelId,\n\t\t\tonDone: options.onDone,\n\t\t});\n\t\tthis.addChild(this.modelList);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.hintText = new Text(\"\", 1, 0);\n\t\tthis.addChild(this.hintText);\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.updateStaticText();\n\t}\n\n\tprivate updateStaticText(): void {\n\t\tthis.titleText.setText(this.theme.fg(\"accent\", this.theme.bold(this.title)));\n\t\tconst hints = [\n\t\t\tnavigationHint(this.theme, this.keybindings),\n\t\t\tthis.hasScopedModels ? hint(this.theme, this.keybindings, \"tui.input.tab\", \"scope\") : \"\",\n\t\t\thint(this.theme, this.keybindings, \"tui.select.confirm\", \"select\"),\n\t\t\thint(this.theme, this.keybindings, \"tui.select.cancel\", \"back\"),\n\t\t].filter(Boolean);\n\t\tthis.hintText.setText(hints.join(this.theme.fg(\"muted\", \" • \")));\n\t}\n\n\tget refreshSignal(): AbortSignal {\n\t\treturn this.refreshAbortController.signal;\n\t}\n\n\tcancelRefresh(): void {\n\t\tthis.refreshAbortController.abort();\n\t}\n\n\tget isClosed(): boolean {\n\t\treturn this.closed;\n\t}\n\n\tdispose(): void {\n\t\tthis.closed = true;\n\t\tthis.refreshAbortController.abort();\n\t}\n\n\tupdateModels(models: readonly Model<Api>[]): void {\n\t\tif (this.closed) return;\n\t\tthis.modelList.updateModels(models);\n\t\tthis.tui.requestRender();\n\t}\n\n\tsetRefreshStatus(message: string | undefined, tone: \"muted\" | \"success\" | \"error\" = \"muted\"): void {\n\t\tif (this.closed) return;\n\t\tthis.modelList.setStatus(message, tone);\n\t\tthis.tui.requestRender();\n\t}\n\n\toverride invalidate(): void {\n\t\tthis.updateStaticText();\n\t\tsuper.invalidate();\n\t}\n\n\thandleInput(data: string): void {\n\t\tthis.modelList.handleInput(data);\n\t}\n}\n\n/** Persist a single override atomically; the UI only reflects the value on success. */\nasync function persistOverride(\n\tctx: ExtensionCommandContext,\n\tprofile: AgentProfile,\n\tpatch: Partial<SubagentProfileOverride>,\n): Promise<SubagentConfigFile | undefined> {\n\ttry {\n\t\treturn await updateProfileOverride(profile.name, patch, getAgentDir());\n\t} catch (error) {\n\t\tctx.ui.notify(\n\t\t\t`Could not save ${AGENT_PROFILE_LABELS[profile.name]} settings: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\"error\",\n\t\t);\n\t\treturn undefined;\n\t}\n}\n\nasync function refreshPickerModels(ctx: ExtensionCommandContext, picker: ModelPickerComponent): Promise<void> {\n\tlet timedOut = false;\n\tconst timeout = setTimeout(() => {\n\t\ttimedOut = true;\n\t\tpicker.cancelRefresh();\n\t}, MODEL_REFRESH_TIMEOUT_MS);\n\ttimeout.unref?.();\n\ttry {\n\t\tconst result = await ctx.modelRegistry.refresh({ signal: picker.refreshSignal });\n\t\tif (picker.isClosed || (picker.refreshSignal.aborted && !timedOut)) return;\n\t\tpicker.updateModels(ctx.modelRegistry.getAvailable());\n\t\tif (result.aborted && timedOut) {\n\t\t\tpicker.setRefreshStatus(\"Model refresh timed out; showing cached models.\", \"error\");\n\t\t\treturn;\n\t\t}\n\t\tconst providerIds = [...result.errors.keys()];\n\t\tif (providerIds.length > 0) {\n\t\t\tpicker.setRefreshStatus(refreshFailureMessage(providerIds), \"error\");\n\t\t\treturn;\n\t\t}\n\t\tconst registryError = ctx.modelRegistry.getError();\n\t\tif (registryError) {\n\t\t\tpicker.setRefreshStatus(truncate(registryError, MAX_REFRESH_ERROR_LENGTH), \"error\");\n\t\t\treturn;\n\t\t}\n\t\tpicker.setRefreshStatus(undefined);\n\t} catch (error) {\n\t\tif (picker.isClosed || (picker.refreshSignal.aborted && !timedOut)) return;\n\t\tconst message = timedOut\n\t\t\t? \"Model refresh timed out; showing cached models.\"\n\t\t\t: `Could not refresh model catalogs: ${error instanceof Error ? error.message : String(error)}`;\n\t\tpicker.setRefreshStatus(truncate(message, MAX_REFRESH_ERROR_LENGTH), \"error\");\n\t} finally {\n\t\tclearTimeout(timeout);\n\t}\n}\n\ntype AgentsMenuRoute =\n\t| { kind: \"profiles\" }\n\t| { kind: \"settings\"; profile: AgentProfile; selectedAction: SettingsAction }\n\t| { kind: \"model\"; profile: AgentProfile }\n\t| { kind: \"thinking\"; profile: AgentProfile };\n\n/** One mounted /agents TUI whose child pages switch without restoring the editor between them. */\nclass AgentsMenuComponent extends Container implements Focusable {\n\tprivate readonly tui: TUI;\n\tprivate readonly theme: Theme;\n\tprivate readonly keybindings: KeybindingsManager;\n\tprivate readonly ctx: ExtensionCommandContext;\n\tprivate readonly currentThinking: ThinkingLevel;\n\tprivate readonly onDone: () => void;\n\tprivate config: SubagentConfigFile;\n\tprivate activeScreen: (Component & { dispose?(): void }) | undefined;\n\tprivate route: AgentsMenuRoute = { kind: \"profiles\" };\n\tprivate selectedProfile: AgentProfile | undefined;\n\tprivate selectedSettingsAction: SettingsAction = \"model\";\n\tprivate saving = false;\n\tprivate closed = false;\n\tprivate _focused = false;\n\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tif (this.activeScreen && isFocusable(this.activeScreen)) this.activeScreen.focused = value;\n\t}\n\n\tconstructor(options: {\n\t\ttui: TUI;\n\t\ttheme: Theme;\n\t\tkeybindings: KeybindingsManager;\n\t\tctx: ExtensionCommandContext;\n\t\tcurrentThinking: ThinkingLevel;\n\t\tconfig: SubagentConfigFile;\n\t\tonDone: () => void;\n\t}) {\n\t\tsuper();\n\t\tthis.tui = options.tui;\n\t\tthis.theme = options.theme;\n\t\tthis.keybindings = options.keybindings;\n\t\tthis.ctx = options.ctx;\n\t\tthis.currentThinking = options.currentThinking;\n\t\tthis.config = options.config;\n\t\tthis.onDone = options.onDone;\n\t\tthis.showProfiles();\n\t}\n\n\tprivate disposeActiveScreen(): void {\n\t\tconst screen = this.activeScreen;\n\t\tthis.activeScreen = undefined;\n\t\tif (!screen) return;\n\t\tconst disposable = screen as Component & { dispose?(): void };\n\t\tif (isFocusable(screen)) screen.focused = false;\n\t\tdisposable.dispose?.();\n\t}\n\n\tprivate setActiveScreen(screen: Component & { dispose?(): void }): void {\n\t\tthis.disposeActiveScreen();\n\t\tthis.clear();\n\t\tthis.activeScreen = screen;\n\t\tthis.addChild(screen);\n\t\tif (isFocusable(screen)) screen.focused = this._focused;\n\t\tthis.tui.requestRender();\n\t}\n\n\tprivate showProfiles(): void {\n\t\tthis.route = { kind: \"profiles\" };\n\t\tconst choices = AGENT_PROFILES.map((profile) => ({\n\t\t\tlabel: AGENT_PROFILE_LABELS[profile.name],\n\t\t\tvalue: profile,\n\t\t}));\n\t\tconst initialIndex = choices.findIndex((choice) => choice.value.name === this.selectedProfile?.name);\n\t\tthis.setActiveScreen(\n\t\t\tnew ChoiceMenuComponent({\n\t\t\t\ttheme: this.theme,\n\t\t\t\tkeybindings: this.keybindings,\n\t\t\t\ttitle: \"Agents\",\n\t\t\t\tchoices,\n\t\t\t\tinitialIndex,\n\t\t\t\tcancelDescription: \"close\",\n\t\t\t\tonDone: (choice) => {\n\t\t\t\t\tif (!choice) {\n\t\t\t\t\t\tthis.onDone();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthis.selectedProfile = choice.value;\n\t\t\t\t\tthis.selectedSettingsAction = \"model\";\n\t\t\t\t\tthis.showSettings(choice.value);\n\t\t\t\t},\n\t\t\t}),\n\t\t);\n\t}\n\n\tprivate showSettings(profile: AgentProfile, selectedAction = this.selectedSettingsAction): void {\n\t\tthis.selectedProfile = profile;\n\t\tthis.selectedSettingsAction = selectedAction;\n\t\tthis.route = { kind: \"settings\", profile, selectedAction };\n\t\tthis.setActiveScreen(\n\t\t\tnew ProfileSettingsMenuComponent({\n\t\t\t\ttheme: this.theme,\n\t\t\t\tkeybindings: this.keybindings,\n\t\t\t\tprofile,\n\t\t\t\toverride: this.config.profiles[profile.name],\n\t\t\t\tmodels: this.ctx.modelRegistry.getAvailable(),\n\t\t\t\tcurrentSessionModel: this.ctx.model,\n\t\t\t\tcurrentThinking: this.currentThinking,\n\t\t\t\tselectedAction,\n\t\t\t\tstatus: this.saving ? \"Saving…\" : undefined,\n\t\t\t\tonDone: (action) => {\n\t\t\t\t\tif (!action) {\n\t\t\t\t\t\tthis.showProfiles();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthis.selectedSettingsAction = action;\n\t\t\t\t\tif (action === \"model\") this.showModelPicker(profile);\n\t\t\t\t\telse this.showThinkingPicker(profile);\n\t\t\t\t},\n\t\t\t}),\n\t\t);\n\t}\n\n\tprivate showModelPicker(profile: AgentProfile): void {\n\t\tthis.route = { kind: \"model\", profile };\n\t\tconst override = this.config.profiles[profile.name];\n\t\tconst picker = new ModelPickerComponent({\n\t\t\ttui: this.tui,\n\t\t\ttheme: this.theme,\n\t\t\tkeybindings: this.keybindings,\n\t\t\tprofile,\n\t\t\tsavedModelId: override?.model,\n\t\t\tmodels: this.ctx.modelRegistry.getAvailable(),\n\t\t\tscopedModels: this.ctx.scopedModels,\n\t\t\tcurrentSessionModel: this.ctx.model,\n\t\t\tonDone: (choice) => {\n\t\t\t\tif (!choice) {\n\t\t\t\t\tthis.showSettings(profile, \"model\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.saveOverride(profile, { model: choice.modelId }, \"model\");\n\t\t\t},\n\t\t});\n\t\tpicker.setRefreshStatus(\"Refreshing model catalogs…\");\n\t\tthis.setActiveScreen(picker);\n\t\tvoid refreshPickerModels(this.ctx, picker);\n\t}\n\n\tprivate showThinkingPicker(profile: AgentProfile): void {\n\t\tthis.route = { kind: \"thinking\", profile };\n\t\tconst override = this.config.profiles[profile.name];\n\t\tconst choices = [\n\t\t\t...buildThinkingChoices({\n\t\t\t\tcurrentSessionModel: this.ctx.model,\n\t\t\t\tmodels: this.ctx.modelRegistry.getAvailable(),\n\t\t\t\toverride,\n\t\t\t\tcurrentThinking: this.currentThinking,\n\t\t\t}).entries(),\n\t\t].map(([label, level]) => ({ label, value: level }));\n\t\tconst initialIndex = choices.findIndex((choice) => choice.label.endsWith(\" ✓\"));\n\t\tthis.setActiveScreen(\n\t\t\tnew ChoiceMenuComponent({\n\t\t\t\ttheme: this.theme,\n\t\t\t\tkeybindings: this.keybindings,\n\t\t\t\ttitle: `Thinking — ${AGENT_PROFILE_LABELS[profile.name]}`,\n\t\t\t\tchoices,\n\t\t\t\tinitialIndex,\n\t\t\t\tcancelDescription: \"back\",\n\t\t\t\tonDone: (choice) => {\n\t\t\t\t\tif (!choice) {\n\t\t\t\t\t\tthis.showSettings(profile, \"thinking\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthis.saveOverride(profile, { thinking: choice.value }, \"thinking\");\n\t\t\t\t},\n\t\t\t}),\n\t\t);\n\t}\n\n\tprivate saveOverride(\n\t\tprofile: AgentProfile,\n\t\tpatch: Partial<SubagentProfileOverride>,\n\t\treturnAction: SettingsAction,\n\t): void {\n\t\tif (this.saving) return;\n\t\tthis.saving = true;\n\t\tthis.showSettings(profile, returnAction);\n\t\tvoid persistOverride(this.ctx, profile, patch)\n\t\t\t.then(\n\t\t\t\t(config) => this.completeSave(profile, config),\n\t\t\t\t() => this.completeSave(profile, undefined),\n\t\t\t)\n\t\t\t.catch(() => {\n\t\t\t\t// A reload can stale the command context while the queued file write finishes.\n\t\t\t});\n\t}\n\n\tprivate completeSave(profile: AgentProfile, config: SubagentConfigFile | undefined): void {\n\t\tif (this.closed) return;\n\t\tthis.saving = false;\n\t\tif (config) this.config = config;\n\t\tif (this.route.kind === \"settings\" && this.route.profile.name === profile.name) {\n\t\t\tthis.showSettings(profile, this.route.selectedAction);\n\t\t}\n\t}\n\n\thandleInput(data: string): void {\n\t\tif (!this.saving) {\n\t\t\tthis.activeScreen?.handleInput?.(data);\n\t\t\treturn;\n\t\t}\n\t\tif (!this.keybindings.matches(data, \"tui.select.cancel\")) return;\n\t\tif (this.route.kind === \"settings\") this.showProfiles();\n\t\telse if (this.route.kind === \"profiles\") this.onDone();\n\t}\n\n\tdispose(): void {\n\t\tthis.closed = true;\n\t\tthis.disposeActiveScreen();\n\t\tthis.clear();\n\t}\n}\n\nasync function selectProfile(ctx: ExtensionCommandContext): Promise<AgentProfile | undefined> {\n\tconst labels = AGENT_PROFILES.map((profile) => AGENT_PROFILE_LABELS[profile.name]);\n\tconst label = await ctx.ui.select(\"Agents\", labels);\n\treturn label === undefined\n\t\t? undefined\n\t\t: AGENT_PROFILES.find((profile) => AGENT_PROFILE_LABELS[profile.name] === label);\n}\n\nasync function showDialogSettingsMenu(\n\tctx: ExtensionCommandContext,\n\tprofile: AgentProfile,\n\toverride: SubagentProfileOverride | undefined,\n\tcurrentThinking: ThinkingLevel,\n): Promise<SettingsAction | undefined> {\n\tconst options = new Map<string, SettingsAction>();\n\tfor (const row of buildSettingsRows({\n\t\toverride,\n\t\tmodels: ctx.modelRegistry.getAvailable(),\n\t\tcurrentSessionModel: ctx.model,\n\t\tcurrentThinking,\n\t})) {\n\t\toptions.set(`${row.label} — ${row.value}`, row.action);\n\t}\n\tconst label = await ctx.ui.select(AGENT_PROFILE_LABELS[profile.name], [...options.keys()]);\n\treturn label === undefined ? undefined : options.get(label);\n}\n\nasync function showDialogModelPicker(\n\tctx: ExtensionCommandContext,\n\tprofile: AgentProfile,\n\toverride: SubagentProfileOverride | undefined,\n): Promise<{ modelId: string | undefined } | undefined> {\n\tconst models = [...ctx.modelRegistry.getAvailable()].sort(compareModels);\n\tconst choices = buildModelChoices({\n\t\tmodels,\n\t\tcurrentSessionModel: ctx.model,\n\t\tsavedModelId: override?.model,\n\t});\n\tconst label = await ctx.ui.select(`Model — ${AGENT_PROFILE_LABELS[profile.name]}`, [...choices.keys()]);\n\treturn label === undefined ? undefined : { modelId: choices.get(label) };\n}\n\nasync function showDialogThinkingPicker(\n\tctx: ExtensionCommandContext,\n\tprofile: AgentProfile,\n\toverride: SubagentProfileOverride | undefined,\n\tcurrentThinking: ThinkingLevel,\n): Promise<{ level: ThinkingLevel | undefined } | undefined> {\n\tconst choices = buildThinkingChoices({\n\t\tcurrentSessionModel: ctx.model,\n\t\tmodels: ctx.modelRegistry.getAvailable(),\n\t\toverride,\n\t\tcurrentThinking,\n\t});\n\tconst label = await ctx.ui.select(`Thinking — ${AGENT_PROFILE_LABELS[profile.name]}`, [...choices.keys()]);\n\treturn label === undefined ? undefined : { level: choices.get(label) };\n}\n\nasync function runDialogProfileSettings(\n\tctx: ExtensionCommandContext,\n\tprofile: AgentProfile,\n\tcurrentThinking: ThinkingLevel,\n): Promise<void> {\n\tconst agentDir = getAgentDir();\n\twhile (true) {\n\t\tconst config = await loadSubagentConfig(agentDir);\n\t\tconst override = config.profiles[profile.name];\n\t\tconst action = await showDialogSettingsMenu(ctx, profile, override, currentThinking);\n\t\tif (!action) return;\n\t\tif (action === \"model\") {\n\t\t\tconst chosen = await showDialogModelPicker(ctx, profile, override);\n\t\t\tif (!chosen) continue;\n\t\t\tawait persistOverride(ctx, profile, { model: chosen.modelId });\n\t\t} else {\n\t\t\tconst chosen = await showDialogThinkingPicker(ctx, profile, override, currentThinking);\n\t\t\tif (!chosen) continue;\n\t\t\tawait persistOverride(ctx, profile, { thinking: chosen.level });\n\t\t}\n\t}\n}\n\nasync function showTuiAgentsCommand(ctx: ExtensionCommandContext, currentThinking: ThinkingLevel): Promise<void> {\n\tconst config = await loadSubagentConfig(getAgentDir());\n\tawait ctx.ui.custom<void>(\n\t\t(tui, theme, keybindings, done) =>\n\t\t\tnew AgentsMenuComponent({\n\t\t\t\ttui,\n\t\t\t\ttheme,\n\t\t\t\tkeybindings,\n\t\t\t\tctx,\n\t\t\t\tcurrentThinking,\n\t\t\t\tconfig,\n\t\t\t\tonDone: () => done(),\n\t\t\t}),\n\t);\n}\n\nasync function showDialogAgentsCommand(ctx: ExtensionCommandContext, currentThinking: ThinkingLevel): Promise<void> {\n\twhile (true) {\n\t\tconst profile = await selectProfile(ctx);\n\t\tif (!profile) return;\n\t\tawait runDialogProfileSettings(ctx, profile, currentThinking);\n\t}\n}\n\nexport async function showAgentsCommand(ctx: ExtensionCommandContext, currentThinking: ThinkingLevel): Promise<void> {\n\tif (!ctx.hasUI) {\n\t\tctx.ui.notify(\"/agents requires an interactive UI.\", \"warning\");\n\t\treturn;\n\t}\n\tif (ctx.mode === \"tui\") await showTuiAgentsCommand(ctx, currentThinking);\n\telse await showDialogAgentsCommand(ctx, currentThinking);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"agents-command.js","sourceRoot":"","sources":["../../../src/extensions/subagent/agents-command.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport {\n\ttype Component,\n\tContainer,\n\ttype Focusable,\n\tisFocusable,\n\ttype KeybindingsManager,\n\ttype TUI,\n} from \"@earendil-works/pi-tui\";\nimport { getAgentDir } from \"../../config.ts\";\nimport type { ExtensionCommandContext } from \"../../core/extensions/types.ts\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { AGENT_PROFILE_LABELS, AGENT_PROFILES } from \"./agents.ts\";\nimport { loadSubagentConfig, updateProfileOverride } from \"./settings.ts\";\nimport type { AgentProfile, SubagentConfigFile, SubagentProfileOverride } from \"./types.ts\";\nimport { showDialogAgentsCommand } from \"./ui/agents-dialog.ts\";\nimport { ChoiceMenuComponent } from \"./ui/choice-menu.ts\";\nimport { buildThinkingChoices, type SettingsAction } from \"./ui/choices.ts\";\nimport { ModelPickerComponent, refreshPickerModels } from \"./ui/model-picker.ts\";\nimport { ProfileSettingsMenuComponent } from \"./ui/profile-settings-menu.ts\";\n\n/** Persist a single override atomically; the UI only reflects the value on success. */\nasync function persistOverride(\n\tctx: ExtensionCommandContext,\n\tprofile: AgentProfile,\n\tpatch: Partial<SubagentProfileOverride>,\n): Promise<SubagentConfigFile | undefined> {\n\ttry {\n\t\treturn await updateProfileOverride(profile.name, patch, getAgentDir());\n\t} catch (error) {\n\t\tctx.ui.notify(\n\t\t\t`Could not save ${AGENT_PROFILE_LABELS[profile.name]} settings: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\"error\",\n\t\t);\n\t\treturn undefined;\n\t}\n}\n\ntype AgentsMenuRoute =\n\t| { kind: \"profiles\" }\n\t| { kind: \"settings\"; profile: AgentProfile; selectedAction: SettingsAction }\n\t| { kind: \"model\"; profile: AgentProfile }\n\t| { kind: \"thinking\"; profile: AgentProfile };\n\n/** One mounted /agents TUI whose child pages switch without restoring the editor between them. */\nclass AgentsMenuComponent extends Container implements Focusable {\n\tprivate readonly tui: TUI;\n\tprivate readonly theme: Theme;\n\tprivate readonly keybindings: KeybindingsManager;\n\tprivate readonly ctx: ExtensionCommandContext;\n\tprivate readonly currentThinking: ThinkingLevel;\n\tprivate readonly onDone: () => void;\n\tprivate config: SubagentConfigFile;\n\tprivate activeScreen: (Component & { dispose?(): void }) | undefined;\n\tprivate route: AgentsMenuRoute = { kind: \"profiles\" };\n\tprivate selectedProfile: AgentProfile | undefined;\n\tprivate selectedSettingsAction: SettingsAction = \"model\";\n\tprivate saving = false;\n\tprivate closed = false;\n\tprivate _focused = false;\n\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tif (this.activeScreen && isFocusable(this.activeScreen)) this.activeScreen.focused = value;\n\t}\n\n\tconstructor(options: {\n\t\ttui: TUI;\n\t\ttheme: Theme;\n\t\tkeybindings: KeybindingsManager;\n\t\tctx: ExtensionCommandContext;\n\t\tcurrentThinking: ThinkingLevel;\n\t\tconfig: SubagentConfigFile;\n\t\tonDone: () => void;\n\t}) {\n\t\tsuper();\n\t\tthis.tui = options.tui;\n\t\tthis.theme = options.theme;\n\t\tthis.keybindings = options.keybindings;\n\t\tthis.ctx = options.ctx;\n\t\tthis.currentThinking = options.currentThinking;\n\t\tthis.config = options.config;\n\t\tthis.onDone = options.onDone;\n\t\tthis.showProfiles();\n\t}\n\n\tprivate disposeActiveScreen(): void {\n\t\tconst screen = this.activeScreen;\n\t\tthis.activeScreen = undefined;\n\t\tif (!screen) return;\n\t\tconst disposable = screen as Component & { dispose?(): void };\n\t\tif (isFocusable(screen)) screen.focused = false;\n\t\tdisposable.dispose?.();\n\t}\n\n\tprivate setActiveScreen(screen: Component & { dispose?(): void }): void {\n\t\tthis.disposeActiveScreen();\n\t\tthis.clear();\n\t\tthis.activeScreen = screen;\n\t\tthis.addChild(screen);\n\t\tif (isFocusable(screen)) screen.focused = this._focused;\n\t\tthis.tui.requestRender();\n\t}\n\n\tprivate showProfiles(): void {\n\t\tthis.route = { kind: \"profiles\" };\n\t\tconst choices = AGENT_PROFILES.map((profile) => ({\n\t\t\tlabel: AGENT_PROFILE_LABELS[profile.name],\n\t\t\tvalue: profile,\n\t\t}));\n\t\tconst initialIndex = choices.findIndex((choice) => choice.value.name === this.selectedProfile?.name);\n\t\tthis.setActiveScreen(\n\t\t\tnew ChoiceMenuComponent({\n\t\t\t\ttheme: this.theme,\n\t\t\t\tkeybindings: this.keybindings,\n\t\t\t\ttitle: \"Agents\",\n\t\t\t\tchoices,\n\t\t\t\tinitialIndex,\n\t\t\t\tcancelDescription: \"close\",\n\t\t\t\tonDone: (choice) => {\n\t\t\t\t\tif (!choice) {\n\t\t\t\t\t\tthis.onDone();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthis.selectedProfile = choice.value;\n\t\t\t\t\tthis.selectedSettingsAction = \"model\";\n\t\t\t\t\tthis.showSettings(choice.value);\n\t\t\t\t},\n\t\t\t}),\n\t\t);\n\t}\n\n\tprivate showSettings(profile: AgentProfile, selectedAction = this.selectedSettingsAction): void {\n\t\tthis.selectedProfile = profile;\n\t\tthis.selectedSettingsAction = selectedAction;\n\t\tthis.route = { kind: \"settings\", profile, selectedAction };\n\t\tthis.setActiveScreen(\n\t\t\tnew ProfileSettingsMenuComponent({\n\t\t\t\ttheme: this.theme,\n\t\t\t\tkeybindings: this.keybindings,\n\t\t\t\tprofile,\n\t\t\t\toverride: this.config.profiles[profile.name],\n\t\t\t\tmodels: this.ctx.modelRegistry.getAvailable(),\n\t\t\t\tcurrentSessionModel: this.ctx.model,\n\t\t\t\tcurrentThinking: this.currentThinking,\n\t\t\t\tselectedAction,\n\t\t\t\tstatus: this.saving ? \"Saving…\" : undefined,\n\t\t\t\tonDone: (action) => {\n\t\t\t\t\tif (!action) {\n\t\t\t\t\t\tthis.showProfiles();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthis.selectedSettingsAction = action;\n\t\t\t\t\tif (action === \"model\") this.showModelPicker(profile);\n\t\t\t\t\telse this.showThinkingPicker(profile);\n\t\t\t\t},\n\t\t\t}),\n\t\t);\n\t}\n\n\tprivate showModelPicker(profile: AgentProfile): void {\n\t\tthis.route = { kind: \"model\", profile };\n\t\tconst override = this.config.profiles[profile.name];\n\t\tconst picker = new ModelPickerComponent({\n\t\t\ttui: this.tui,\n\t\t\ttheme: this.theme,\n\t\t\tkeybindings: this.keybindings,\n\t\t\tprofile,\n\t\t\tsavedModelId: override?.model,\n\t\t\tmodels: this.ctx.modelRegistry.getAvailable(),\n\t\t\tscopedModels: this.ctx.scopedModels,\n\t\t\tcurrentSessionModel: this.ctx.model,\n\t\t\tonDone: (choice) => {\n\t\t\t\tif (!choice) {\n\t\t\t\t\tthis.showSettings(profile, \"model\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.saveOverride(profile, { model: choice.modelId }, \"model\");\n\t\t\t},\n\t\t});\n\t\tpicker.setRefreshStatus(\"Refreshing model catalogs…\");\n\t\tthis.setActiveScreen(picker);\n\t\tvoid refreshPickerModels(this.ctx, picker);\n\t}\n\n\tprivate showThinkingPicker(profile: AgentProfile): void {\n\t\tthis.route = { kind: \"thinking\", profile };\n\t\tconst override = this.config.profiles[profile.name];\n\t\tconst choices = [\n\t\t\t...buildThinkingChoices({\n\t\t\t\tcurrentSessionModel: this.ctx.model,\n\t\t\t\tmodels: this.ctx.modelRegistry.getAvailable(),\n\t\t\t\toverride,\n\t\t\t\tcurrentThinking: this.currentThinking,\n\t\t\t}).entries(),\n\t\t].map(([label, level]) => ({ label, value: level }));\n\t\tconst initialIndex = choices.findIndex((choice) => choice.label.endsWith(\" ✓\"));\n\t\tthis.setActiveScreen(\n\t\t\tnew ChoiceMenuComponent({\n\t\t\t\ttheme: this.theme,\n\t\t\t\tkeybindings: this.keybindings,\n\t\t\t\ttitle: `Thinking — ${AGENT_PROFILE_LABELS[profile.name]}`,\n\t\t\t\tchoices,\n\t\t\t\tinitialIndex,\n\t\t\t\tcancelDescription: \"back\",\n\t\t\t\tonDone: (choice) => {\n\t\t\t\t\tif (!choice) {\n\t\t\t\t\t\tthis.showSettings(profile, \"thinking\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthis.saveOverride(profile, { thinking: choice.value }, \"thinking\");\n\t\t\t\t},\n\t\t\t}),\n\t\t);\n\t}\n\n\tprivate saveOverride(\n\t\tprofile: AgentProfile,\n\t\tpatch: Partial<SubagentProfileOverride>,\n\t\treturnAction: SettingsAction,\n\t): void {\n\t\tif (this.saving) return;\n\t\tthis.saving = true;\n\t\tthis.showSettings(profile, returnAction);\n\t\tvoid persistOverride(this.ctx, profile, patch)\n\t\t\t.then(\n\t\t\t\t(config) => this.completeSave(profile, config),\n\t\t\t\t() => this.completeSave(profile, undefined),\n\t\t\t)\n\t\t\t.catch(() => {\n\t\t\t\t// A reload can stale the command context while the queued file write finishes.\n\t\t\t});\n\t}\n\n\tprivate completeSave(profile: AgentProfile, config: SubagentConfigFile | undefined): void {\n\t\tif (this.closed) return;\n\t\tthis.saving = false;\n\t\tif (config) this.config = config;\n\t\tif (this.route.kind === \"settings\" && this.route.profile.name === profile.name) {\n\t\t\tthis.showSettings(profile, this.route.selectedAction);\n\t\t}\n\t}\n\n\thandleInput(data: string): void {\n\t\tif (!this.saving) {\n\t\t\tthis.activeScreen?.handleInput?.(data);\n\t\t\treturn;\n\t\t}\n\t\tif (!this.keybindings.matches(data, \"tui.select.cancel\")) return;\n\t\tif (this.route.kind === \"settings\") this.showProfiles();\n\t\telse if (this.route.kind === \"profiles\") this.onDone();\n\t}\n\n\tdispose(): void {\n\t\tthis.closed = true;\n\t\tthis.disposeActiveScreen();\n\t\tthis.clear();\n\t}\n}\n\nasync function showTuiAgentsCommand(ctx: ExtensionCommandContext, currentThinking: ThinkingLevel): Promise<void> {\n\tconst config = await loadSubagentConfig(getAgentDir());\n\tawait ctx.ui.custom<void>(\n\t\t(tui, theme, keybindings, done) =>\n\t\t\tnew AgentsMenuComponent({\n\t\t\t\ttui,\n\t\t\t\ttheme,\n\t\t\t\tkeybindings,\n\t\t\t\tctx,\n\t\t\t\tcurrentThinking,\n\t\t\t\tconfig,\n\t\t\t\tonDone: () => done(),\n\t\t\t}),\n\t);\n}\n\nexport async function showAgentsCommand(ctx: ExtensionCommandContext, currentThinking: ThinkingLevel): Promise<void> {\n\tif (!ctx.hasUI) {\n\t\tctx.ui.notify(\"/agents requires an interactive UI.\", \"warning\");\n\t\treturn;\n\t}\n\tif (ctx.mode === \"tui\") await showTuiAgentsCommand(ctx, currentThinking);\n\telse await showDialogAgentsCommand(ctx, currentThinking);\n}\n"]}
|
|
@@ -4,7 +4,7 @@ export declare const SUBAGENT_COMMAND_NAME = "agents";
|
|
|
4
4
|
export declare const SUBAGENT_CONFIG_VERSION = 1;
|
|
5
5
|
export declare const SUBAGENT_CONFIG_FILE = "subagent.json";
|
|
6
6
|
export declare const MAX_TASKS = 8;
|
|
7
|
-
export declare const MAX_CONCURRENCY =
|
|
7
|
+
export declare const MAX_CONCURRENCY = 6;
|
|
8
8
|
export declare const TASK_RETRY_LIMIT = 2;
|
|
9
9
|
export declare const TASK_RETRY_BASE_DELAY_MS = 1000;
|
|
10
10
|
export declare const SUBAGENT_AGENT_NAMES: readonly ["explorer", "general"];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/extensions/subagent/constants.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,kBAAkB,aAAa,CAAC;AAC7C,eAAO,MAAM,mBAAmB,aAAa,CAAC;AAC9C,eAAO,MAAM,qBAAqB,WAAW,CAAC;AAC9C,eAAO,MAAM,uBAAuB,IAAI,CAAC;AACzC,eAAO,MAAM,oBAAoB,kBAAkB,CAAC;AAEpD,eAAO,MAAM,SAAS,IAAI,CAAC;AAC3B,eAAO,MAAM,eAAe,IAAI,CAAC;AAKjC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,wBAAwB,OAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/extensions/subagent/constants.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,kBAAkB,aAAa,CAAC;AAC7C,eAAO,MAAM,mBAAmB,aAAa,CAAC;AAC9C,eAAO,MAAM,qBAAqB,WAAW,CAAC;AAC9C,eAAO,MAAM,uBAAuB,IAAI,CAAC;AACzC,eAAO,MAAM,oBAAoB,kBAAkB,CAAC;AAEpD,eAAO,MAAM,SAAS,IAAI,CAAC;AAC3B,eAAO,MAAM,eAAe,IAAI,CAAC;AAKjC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,wBAAwB,OAAQ,CAAC;AAK9C,eAAO,MAAM,oBAAoB,kCAAmC,CAAC;AACrE,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAGtE,eAAO,MAAM,mBAAmB,4CAA6C,CAAC;AAI9E,eAAO,MAAM,cAAc,iDAAkD,CAAC;AAE9E,eAAO,MAAM,eAAe,sEAQiB,CAAC;AAE9C,eAAO,MAAM,cAAc,KAAK,CAAC;AACjC,eAAO,MAAM,mBAAmB,QAAY,CAAC;AAI7C,eAAO,MAAM,sBAAsB,eAAe,CAAC;AAGnD,eAAO,MAAM,iBAAiB,QAAY,CAAC;AAE3C,eAAO,MAAM,kBAAkB,QAAY,CAAC;AAC5C,eAAO,MAAM,gBAAgB,QAAW,CAAC;AACzC,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAC1C,eAAO,MAAM,oBAAoB,QAAa,CAAC;AAG/C,eAAO,MAAM,sBAAsB,KAAK,CAAC"}
|
|
@@ -4,7 +4,7 @@ export const SUBAGENT_COMMAND_NAME = "agents";
|
|
|
4
4
|
export const SUBAGENT_CONFIG_VERSION = 1;
|
|
5
5
|
export const SUBAGENT_CONFIG_FILE = "subagent.json";
|
|
6
6
|
export const MAX_TASKS = 8;
|
|
7
|
-
export const MAX_CONCURRENCY =
|
|
7
|
+
export const MAX_CONCURRENCY = 6;
|
|
8
8
|
// Task-level retry for failures that bypass the session's own auto-retry
|
|
9
9
|
// (preflight throws such as auth checks). Only runs that produced nothing
|
|
10
10
|
// are retried, so a retry never discards partial work.
|
|
@@ -12,6 +12,7 @@ export const TASK_RETRY_LIMIT = 2;
|
|
|
12
12
|
export const TASK_RETRY_BASE_DELAY_MS = 1_000;
|
|
13
13
|
// The only selectable agents: the schema's agent field restricts task items
|
|
14
14
|
// to these names, resolve.ts defaults an omitted/null agent to explorer.
|
|
15
|
+
// SubagentAgentName is co-located with its source value; types.ts re-imports it.
|
|
15
16
|
export const SUBAGENT_AGENT_NAMES = ["explorer", "general"];
|
|
16
17
|
// Matches the parent session's default toolset; bash covers search needs.
|
|
17
18
|
export const DEFAULT_AGENT_TOOLS = ["read", "bash", "edit", "write"];
|