pi-ui-extend 1.0.41 → 1.0.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -13
- package/dist/app/app.d.ts +13 -0
- package/dist/app/app.js +158 -8
- package/dist/app/cli/install.js +2 -2
- package/dist/app/commands/command-controller.d.ts +4 -0
- package/dist/app/commands/command-controller.js +11 -0
- package/dist/app/commands/command-git-actions.d.ts +25 -0
- package/dist/app/commands/command-git-actions.js +381 -0
- package/dist/app/commands/command-host.d.ts +4 -0
- package/dist/app/commands/command-host.js +5 -2
- package/dist/app/commands/command-model-actions.d.ts +1 -0
- package/dist/app/commands/command-model-actions.js +57 -35
- package/dist/app/commands/command-navigation-actions.d.ts +1 -0
- package/dist/app/commands/command-navigation-actions.js +16 -3
- package/dist/app/commands/command-registry.d.ts +2 -0
- package/dist/app/commands/command-registry.js +15 -1
- package/dist/app/commands/command-session-actions.js +9 -3
- package/dist/app/commands/reload-context-inventory.d.ts +11 -0
- package/dist/app/commands/reload-context-inventory.js +70 -0
- package/dist/app/extensions/extension-actions-controller.d.ts +1 -0
- package/dist/app/extensions/extension-actions-controller.js +6 -0
- package/dist/app/extensions/subagent-catalog-state.d.ts +9 -0
- package/dist/app/extensions/subagent-catalog-state.js +23 -0
- package/dist/app/input/autocomplete-controller.js +61 -34
- package/dist/app/input/input-action-controller.d.ts +2 -0
- package/dist/app/input/input-action-controller.js +8 -1
- package/dist/app/input/input-controller.d.ts +2 -1
- package/dist/app/input/input-controller.js +7 -2
- package/dist/app/input/prompt-enhancer-controller.js +53 -35
- package/dist/app/input/voice-controller.d.ts +41 -45
- package/dist/app/input/voice-controller.js +351 -419
- package/dist/app/model/model-usage-controller.js +17 -7
- package/dist/app/model/model-usage-status.d.ts +4 -1
- package/dist/app/model/model-usage-status.js +270 -46
- package/dist/app/popup/menu-items-controller.d.ts +13 -3
- package/dist/app/popup/menu-items-controller.js +37 -21
- package/dist/app/popup/popup-action-controller.d.ts +12 -2
- package/dist/app/popup/popup-action-controller.js +77 -24
- package/dist/app/popup/popup-menu-controller.d.ts +36 -14
- package/dist/app/popup/popup-menu-controller.js +239 -69
- package/dist/app/rendering/dcp-stats.d.ts +9 -4
- package/dist/app/rendering/dcp-stats.js +40 -425
- package/dist/app/rendering/editor-panels.js +10 -4
- package/dist/app/rendering/popup-menu-renderer.d.ts +3 -5
- package/dist/app/rendering/popup-menu-renderer.js +42 -37
- package/dist/app/rendering/render-controller.js +23 -2
- package/dist/app/rendering/status-line-renderer.d.ts +5 -0
- package/dist/app/rendering/status-line-renderer.js +41 -5
- package/dist/app/rendering/tab-line-renderer.js +26 -20
- package/dist/app/runtime.d.ts +12 -1
- package/dist/app/runtime.js +120 -12
- package/dist/app/screen/mouse-controller.d.ts +2 -0
- package/dist/app/screen/mouse-controller.js +17 -7
- package/dist/app/screen/status-controller.d.ts +4 -0
- package/dist/app/screen/status-controller.js +5 -0
- package/dist/app/session/lazy-session-manager.js +34 -0
- package/dist/app/session/session-event-controller.d.ts +1 -0
- package/dist/app/session/session-event-controller.js +10 -1
- package/dist/app/session/session-history.d.ts +1 -0
- package/dist/app/session/session-history.js +12 -1
- package/dist/app/session/session-lifecycle-controller.d.ts +7 -1
- package/dist/app/session/session-lifecycle-controller.js +16 -1
- package/dist/app/session/tabs-controller.d.ts +26 -1
- package/dist/app/session/tabs-controller.js +454 -147
- package/dist/app/subagents/subagents-files.js +60 -1
- package/dist/app/subagents/subagents-model.d.ts +1 -0
- package/dist/app/subagents/subagents-model.js +18 -2
- package/dist/app/subagents/subagents-widget-controller.d.ts +1 -0
- package/dist/app/subagents/subagents-widget-controller.js +6 -0
- package/dist/app/types.d.ts +16 -1
- package/dist/app/workspace/workspace-actions-controller.js +10 -2
- package/dist/app/workspace/workspace-undo.d.ts +1 -0
- package/dist/app/workspace/workspace-undo.js +1 -0
- package/dist/bundled-extensions/question/index.js +9 -1
- package/dist/bundled-extensions/question/remote.d.ts +4 -0
- package/dist/bundled-extensions/question/remote.js +33 -0
- package/dist/bundled-extensions/telegram-connector/bot.d.ts +43 -0
- package/dist/bundled-extensions/telegram-connector/bot.js +166 -0
- package/dist/bundled-extensions/telegram-connector/config.d.ts +8 -0
- package/dist/bundled-extensions/telegram-connector/config.js +87 -0
- package/dist/bundled-extensions/telegram-connector/coordinator.d.ts +66 -0
- package/dist/bundled-extensions/telegram-connector/coordinator.js +413 -0
- package/dist/bundled-extensions/telegram-connector/index.d.ts +3 -0
- package/dist/bundled-extensions/telegram-connector/index.js +195 -0
- package/dist/bundled-extensions/terminal-bell/index.d.ts +0 -8
- package/dist/bundled-extensions/terminal-bell/index.js +0 -76
- package/dist/bundled-extensions/workspace-undo/index.d.ts +26 -0
- package/dist/bundled-extensions/workspace-undo/index.js +191 -0
- package/dist/config.d.ts +21 -2
- package/dist/config.js +159 -32
- package/dist/default-pix-config.js +25 -5
- package/dist/schemas/index.d.ts +1 -0
- package/dist/schemas/index.js +1 -0
- package/dist/schemas/pi-tools-suite-schema.d.ts +88 -62
- package/dist/schemas/pi-tools-suite-schema.js +54 -83
- package/dist/schemas/pix-schema.d.ts +19 -2
- package/dist/schemas/pix-schema.js +47 -5
- package/dist/schemas/tasks-schema.d.ts +18 -0
- package/dist/schemas/tasks-schema.js +41 -0
- package/docs/concurrency.md +9 -1
- package/docs/desktop-mvp.md +22 -6
- package/docs/desktop-task-manager.md +148 -84
- package/docs/release.md +30 -6
- package/external/pi-tools-suite/README.md +197 -84
- package/external/pi-tools-suite/docs/evals.md +1 -1
- package/external/pi-tools-suite/docs/session-recovery.md +47 -14
- package/external/pi-tools-suite/docs/subagent-model-pools.md +48 -30
- package/external/pi-tools-suite/docs/ui-qa-subagent.md +440 -0
- package/external/pi-tools-suite/package.json +6 -1
- package/external/pi-tools-suite/src/antigravity-auth/auth-store.ts +2 -1
- package/external/pi-tools-suite/src/antigravity-auth/constants.ts +9 -3
- package/external/pi-tools-suite/src/antigravity-auth/headers.ts +41 -3
- package/external/pi-tools-suite/src/antigravity-auth/models.ts +94 -21
- package/external/pi-tools-suite/src/antigravity-auth/oauth.ts +5 -17
- package/external/pi-tools-suite/src/antigravity-auth/payload.ts +72 -7
- package/external/pi-tools-suite/src/antigravity-auth/stream.ts +13 -1
- package/external/pi-tools-suite/src/async-subagents/agents/frontier-review.md +23 -0
- package/external/pi-tools-suite/src/async-subagents/agents/implement.md +1 -1
- package/external/pi-tools-suite/src/async-subagents/agents/presets.jsonc +16 -0
- package/external/pi-tools-suite/src/async-subagents/agents/research.md +5 -3
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/backends/browser.mjs +346 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/backends/desktop.mjs +1038 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/backends/tui.mjs +759 -0
- package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/scripts/browser-qa-runner.mjs +32 -23
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/chrome-devtools/chrome-devtools-provider.mjs +895 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/linux/linux-atspi.py +494 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/macos/macos-accessibility.swift +1085 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/native-terminal/bridge-client.mjs +50 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/native-terminal/native-terminal-host.mjs +501 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/windows/windows-uia.ps1 +454 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/browser-auth.md +114 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/browser-chrome-devtools.md +91 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/browser-playwright.md +145 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/browser.md +82 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/desktop-linux.md +26 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/desktop-macos.md +29 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/desktop-windows.md +23 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/desktop.md +54 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/tui-native-terminal.md +59 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/tui-pty.md +37 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/tui.md +60 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/scripts/ui-qa-runner.mjs +535 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa.md +75 -0
- package/external/pi-tools-suite/src/async-subagents/commands.ts +15 -71
- package/external/pi-tools-suite/src/async-subagents/core/activity.ts +33 -0
- package/external/pi-tools-suite/src/async-subagents/core/agent-catalog.ts +5 -4
- package/external/pi-tools-suite/src/async-subagents/core/agent-strategy.ts +1 -1
- package/external/pi-tools-suite/src/async-subagents/core/agents-dir.ts +8 -5
- package/external/pi-tools-suite/src/async-subagents/core/browser-qa.ts +16 -2
- package/external/pi-tools-suite/src/async-subagents/core/config.ts +160 -327
- package/external/pi-tools-suite/src/async-subagents/core/model-selection.ts +2 -1
- package/external/pi-tools-suite/src/async-subagents/core/registry.ts +158 -33
- package/external/pi-tools-suite/src/async-subagents/core/routing.ts +21 -5
- package/external/pi-tools-suite/src/async-subagents/core/spawn.ts +40 -26
- package/external/pi-tools-suite/src/async-subagents/core/state.ts +40 -0
- package/external/pi-tools-suite/src/async-subagents/core/types.ts +7 -0
- package/external/pi-tools-suite/src/async-subagents/core/ultrawork-auto.ts +51 -45
- package/external/pi-tools-suite/src/async-subagents/index.ts +69 -5
- package/external/pi-tools-suite/src/async-subagents/lib.ts +16 -9
- package/external/pi-tools-suite/src/async-subagents/tools/spawn.ts +8 -5
- package/external/pi-tools-suite/src/async-subagents/tools/subagents.ts +5 -4
- package/external/pi-tools-suite/src/async-subagents/types.ts +1 -0
- package/external/pi-tools-suite/src/coding-discipline/index.ts +90 -59
- package/external/pi-tools-suite/src/config.ts +55 -1
- package/external/pi-tools-suite/src/context-gateway/accounting-log.ts +282 -0
- package/external/pi-tools-suite/src/context-gateway/config.ts +77 -3
- package/external/pi-tools-suite/src/context-gateway/efficiency.ts +414 -0
- package/external/pi-tools-suite/src/context-gateway/enforcement.ts +222 -0
- package/external/pi-tools-suite/src/context-gateway/index.ts +206 -19
- package/external/pi-tools-suite/src/context-gateway/storeless-capabilities.ts +7 -7
- package/external/pi-tools-suite/src/context-gateway/telemetry.ts +101 -28
- package/external/pi-tools-suite/src/context-gateway/types.ts +16 -3
- package/external/pi-tools-suite/src/context-inventory.ts +99 -0
- package/external/pi-tools-suite/src/dcp/auto-compress-budget.ts +39 -4
- package/external/pi-tools-suite/src/dcp/auto-compress.ts +128 -49
- package/external/pi-tools-suite/src/dcp/commands.ts +32 -156
- package/external/pi-tools-suite/src/dcp/compress-tool.ts +177 -46
- package/external/pi-tools-suite/src/dcp/compression-blocks.ts +6 -58
- package/external/pi-tools-suite/src/dcp/compression-preview.ts +9 -0
- package/external/pi-tools-suite/src/dcp/compression-progress.ts +22 -0
- package/external/pi-tools-suite/src/dcp/config.ts +114 -17
- package/external/pi-tools-suite/src/dcp/conversation-index.ts +36 -9
- package/external/pi-tools-suite/src/dcp/diagnostics.ts +41 -0
- package/external/pi-tools-suite/src/dcp/fresh-tool-results.ts +38 -0
- package/external/pi-tools-suite/src/dcp/index.ts +338 -66
- package/external/pi-tools-suite/src/dcp/journal.ts +126 -4
- package/external/pi-tools-suite/src/dcp/progress-controller.ts +2 -1
- package/external/pi-tools-suite/src/dcp/prompts.ts +83 -192
- package/external/pi-tools-suite/src/dcp/protected-continuity.ts +175 -0
- package/external/pi-tools-suite/src/dcp/pruner-candidates.ts +93 -3
- package/external/pi-tools-suite/src/dcp/pruner-message-ids.ts +6 -10
- package/external/pi-tools-suite/src/dcp/pruner-nudge.ts +36 -33
- package/external/pi-tools-suite/src/dcp/pruner-tools.ts +6 -3
- package/external/pi-tools-suite/src/dcp/pruner.ts +1 -0
- package/external/pi-tools-suite/src/dcp/routine-pressure.ts +86 -0
- package/external/pi-tools-suite/src/dcp/state.ts +9 -0
- package/external/pi-tools-suite/src/dcp/statistics.d.ts +8 -0
- package/external/pi-tools-suite/src/dcp/statistics.js +156 -0
- package/external/pi-tools-suite/src/default-pi-tools-suite-config.ts +78 -22
- package/external/pi-tools-suite/src/index.ts +7 -1
- package/external/pi-tools-suite/src/lib/project.ts +36 -1
- package/external/pi-tools-suite/src/model-tools/index.ts +10 -7
- package/external/pi-tools-suite/src/repo-discovery/index.ts +304 -4
- package/external/pi-tools-suite/src/resource-registry/index.ts +2551 -0
- package/external/pi-tools-suite/src/session-recovery/index.ts +17 -0
- package/external/pi-tools-suite/src/shell-command-policy.ts +219 -0
- package/external/pi-tools-suite/src/todo/index.ts +21 -0
- package/external/pi-tools-suite/src/todo/todo.ts +19 -1
- package/external/pi-tools-suite/src/tool-descriptions.ts +47 -19
- package/package.json +10 -9
- package/schemas/pi-tools-suite.json +466 -287
- package/schemas/pix.json +129 -11
- package/schemas/tasks.json +131 -0
- package/skills/simplify/SKILL.md +33 -5
- package/docs/desktop-markdown-media.md +0 -77
- package/external/pi-tools-suite/docs/browser-qa-subagent.md +0 -177
- package/external/pi-tools-suite/docs/dcp-emergency-current-turn.md +0 -102
- package/external/pi-tools-suite/src/async-subagents/agents/browser-qa.md +0 -598
- package/external/pi-tools-suite/src/async-subagents/async-subagents.sample.jsonc +0 -54
- package/external/pi-tools-suite/src/skill-installer/index.ts +0 -333
- package/skills/playwright-cli/SKILL.md +0 -420
- package/skills/playwright-cli/references/element-attributes.md +0 -23
- package/skills/playwright-cli/references/playwright-tests.md +0 -50
- package/skills/playwright-cli/references/request-mocking.md +0 -87
- package/skills/playwright-cli/references/running-code.md +0 -241
- package/skills/playwright-cli/references/session-management.md +0 -273
- package/skills/playwright-cli/references/spec-driven-testing.md +0 -311
- package/skills/playwright-cli/references/storage-state.md +0 -290
- package/skills/playwright-cli/references/test-generation.md +0 -142
- package/skills/playwright-cli/references/tracing.md +0 -154
- package/skills/playwright-cli/references/video-recording.md +0 -147
- package/skills/spec-lite/SKILL.md +0 -140
- /package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/examples/qa-auth.example.jsonc +0 -0
- /package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/examples/qa-flow.example.jsonc +0 -0
- /package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/vendor/fflate.LICENSE +0 -0
- /package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/vendor/fflate.mjs +0 -0
|
@@ -277,14 +277,15 @@ export class NavigationCommandActions {
|
|
|
277
277
|
async runResumeCommand(queryOrOptions = "") {
|
|
278
278
|
const preserveStatus = typeof queryOrOptions === "object" && queryOrOptions.preserveStatus === true;
|
|
279
279
|
const placement = typeof queryOrOptions === "object" ? queryOrOptions.placement : undefined;
|
|
280
|
+
const draft = typeof queryOrOptions === "object" && queryOrOptions.draft === true;
|
|
280
281
|
const initialQuery = typeof queryOrOptions === "string" ? queryOrOptions : "";
|
|
281
|
-
const runtime = preserveStatus ? this.host.runtime() : getIdleRuntime(this.host, "resume");
|
|
282
|
-
if (!runtime) {
|
|
282
|
+
const runtime = draft ? this.host.runtime() : preserveStatus ? this.host.runtime() : getIdleRuntime(this.host, "resume");
|
|
283
|
+
if (!runtime && !draft) {
|
|
283
284
|
if (!preserveStatus)
|
|
284
285
|
this.host.render();
|
|
285
286
|
return;
|
|
286
287
|
}
|
|
287
|
-
if (runtime
|
|
288
|
+
if (runtime?.session.isStreaming) {
|
|
288
289
|
if (!preserveStatus) {
|
|
289
290
|
this.host.toast.warning("/resume is unavailable while the agent is running");
|
|
290
291
|
this.host.render();
|
|
@@ -292,6 +293,12 @@ export class NavigationCommandActions {
|
|
|
292
293
|
return;
|
|
293
294
|
}
|
|
294
295
|
if (this.host.getResumeLoading()) {
|
|
296
|
+
if (draft) {
|
|
297
|
+
this.host.setResumeMenuMode?.("draft");
|
|
298
|
+
this.host.openDirectPopupMenu("resume", { preserveStatus: true, ...(placement === undefined ? {} : { placement }) });
|
|
299
|
+
this.host.setDirectPopupMenuQuery(initialQuery);
|
|
300
|
+
this.host.openResumeMenuWithQuery(initialQuery);
|
|
301
|
+
}
|
|
295
302
|
if (!preserveStatus)
|
|
296
303
|
this.host.setStatus("loading sessions…");
|
|
297
304
|
this.host.render();
|
|
@@ -300,6 +307,7 @@ export class NavigationCommandActions {
|
|
|
300
307
|
this.host.setResumeLoading(true);
|
|
301
308
|
if (!preserveStatus)
|
|
302
309
|
this.host.setStatus("loading sessions…");
|
|
310
|
+
this.host.setResumeMenuMode?.(draft ? "draft" : "resume");
|
|
303
311
|
this.host.openDirectPopupMenu("resume", { preserveStatus, ...(placement === undefined ? {} : { placement }) });
|
|
304
312
|
this.host.setDirectPopupMenuQuery(initialQuery);
|
|
305
313
|
if (this.host.getResumeSessions().length > 0) {
|
|
@@ -344,6 +352,11 @@ export class NavigationCommandActions {
|
|
|
344
352
|
this.host.setSessionStatus(options.scope.session);
|
|
345
353
|
this.host.render();
|
|
346
354
|
}
|
|
355
|
+
finally {
|
|
356
|
+
if (options.loadId === this.resumeLoadId && !isCommandScopeActive(this.host, options.scope)) {
|
|
357
|
+
this.host.setResumeLoading(false);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
347
360
|
}
|
|
348
361
|
formatSessionTree(runtime) {
|
|
349
362
|
const tree = runtime.session.sessionManager.getTree();
|
|
@@ -10,6 +10,8 @@ export type CommandRegistryActions = {
|
|
|
10
10
|
runThinkingSlashCommand(argumentsText: string): Promise<void>;
|
|
11
11
|
runDefaultThinkingSlashCommand(argumentsText: string): Promise<void>;
|
|
12
12
|
runEnhanceCommand(): Promise<void>;
|
|
13
|
+
runCodeReviewCommand(): Promise<void>;
|
|
14
|
+
runCommitMessageCommand(): Promise<void>;
|
|
13
15
|
runExportCommand(argumentsText: string): Promise<void>;
|
|
14
16
|
runImportCommand(argumentsText: string): Promise<void>;
|
|
15
17
|
runShareCommand(): Promise<void>;
|
|
@@ -71,6 +71,20 @@ export function createSlashCommands(actions, host) {
|
|
|
71
71
|
keywords: ["prompt", "rewrite", "improve", "kilocode"],
|
|
72
72
|
run: () => actions.runEnhanceCommand(),
|
|
73
73
|
},
|
|
74
|
+
{
|
|
75
|
+
name: "code-review",
|
|
76
|
+
description: "Review staged, unstaged, and untracked Git changes",
|
|
77
|
+
kind: "builtin",
|
|
78
|
+
keywords: ["git", "review", "diff", "changes"],
|
|
79
|
+
run: () => actions.runCodeReviewCommand(),
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: "commit-message",
|
|
83
|
+
description: "Generate a message for staged changes and commit after confirmation",
|
|
84
|
+
kind: "builtin",
|
|
85
|
+
keywords: ["git", "commit", "message", "staged"],
|
|
86
|
+
run: () => actions.runCommitMessageCommand(),
|
|
87
|
+
},
|
|
74
88
|
{
|
|
75
89
|
name: "export",
|
|
76
90
|
description: "Export session (HTML default, or .jsonl path)",
|
|
@@ -217,7 +231,7 @@ export function createSlashCommands(actions, host) {
|
|
|
217
231
|
},
|
|
218
232
|
{
|
|
219
233
|
name: "reload",
|
|
220
|
-
description: "Reload
|
|
234
|
+
description: "Reload resources and show model-available skills, tools, and agents",
|
|
221
235
|
kind: "builtin",
|
|
222
236
|
keywords: ["restart", "refresh", "resources", "extensions", "skills", "prompts"],
|
|
223
237
|
run: () => actions.runReloadCommand(),
|
|
@@ -11,6 +11,7 @@ import { copyTextToClipboard } from "../screen/clipboard.js";
|
|
|
11
11
|
import { formatAccountUsageReport, queryAccountUsageReport } from "../model/model-usage-status.js";
|
|
12
12
|
import { checkGlobalPiInstall, checkPixUpdate, formatGlobalPiCheck, formatPixUpdateCheck, parsePixUpdateArgs, pixUpdateUsage, } from "../cli/update.js";
|
|
13
13
|
import { createStartupInfoMessage } from "../cli/startup-info.js";
|
|
14
|
+
import { createReloadContextInventory, formatReloadContextInventory } from "./reload-context-inventory.js";
|
|
14
15
|
import { getCompleteSessionStats } from "../session/session-stats.js";
|
|
15
16
|
import { loadSessionTitleConfig } from "../../bundled-extensions/session-title/config.js";
|
|
16
17
|
import { fallbackSessionTitleFromInput, firstUserMessageText, generateSessionTitleWithRuntime, sessionTitleModelRefs, } from "../../bundled-extensions/session-title/title-generation.js";
|
|
@@ -309,7 +310,8 @@ export class SessionCommandActions {
|
|
|
309
310
|
if (!isCommandScopeActive(this.host, scope))
|
|
310
311
|
return;
|
|
311
312
|
this.host.setSessionStatus(runtime.session);
|
|
312
|
-
this.host.
|
|
313
|
+
const inventory = createReloadContextInventory(runtime, this.host.subagentTypes?.(runtime));
|
|
314
|
+
this.host.addEntry({ id: createId("system"), kind: "system", text: formatReloadContextInventory(inventory) });
|
|
313
315
|
this.host.toast.success("Reloaded resources");
|
|
314
316
|
}
|
|
315
317
|
catch (error) {
|
|
@@ -391,7 +393,7 @@ export class SessionCommandActions {
|
|
|
391
393
|
this.host.addEntry({
|
|
392
394
|
id: createId("system"),
|
|
393
395
|
kind: "system",
|
|
394
|
-
text: `Deleted session ${targetSessionId}. Started a new session. cwd=${runtime.cwd}
|
|
396
|
+
text: formatReloadContextInventory(createReloadContextInventory(runtime, this.host.subagentTypes?.(runtime)), `Deleted session ${targetSessionId}. Started a new session. cwd=${runtime.cwd}`),
|
|
395
397
|
});
|
|
396
398
|
if (runtime.modelFallbackMessage)
|
|
397
399
|
this.host.addEntry({ id: createId("system"), kind: "system", text: runtime.modelFallbackMessage });
|
|
@@ -427,7 +429,11 @@ export class SessionCommandActions {
|
|
|
427
429
|
return;
|
|
428
430
|
}
|
|
429
431
|
this.host.resetSessionView();
|
|
430
|
-
this.host.addEntry({
|
|
432
|
+
this.host.addEntry({
|
|
433
|
+
id: createId("system"),
|
|
434
|
+
kind: "system",
|
|
435
|
+
text: formatReloadContextInventory(createReloadContextInventory(runtime, this.host.subagentTypes?.(runtime)), `Started a new session. cwd=${runtime.cwd}`),
|
|
436
|
+
});
|
|
431
437
|
if (runtime.modelFallbackMessage)
|
|
432
438
|
this.host.addEntry({ id: createId("system"), kind: "system", text: runtime.modelFallbackMessage });
|
|
433
439
|
for (const diag of runtime.diagnostics ?? []) {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AgentSessionRuntime } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
export interface ReloadContextInventory {
|
|
3
|
+
readonly model: string;
|
|
4
|
+
readonly skills: readonly string[];
|
|
5
|
+
readonly tools: readonly string[];
|
|
6
|
+
readonly agents: readonly string[] | undefined;
|
|
7
|
+
readonly skillsReadable: boolean;
|
|
8
|
+
readonly subagentsActive: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function createReloadContextInventory(runtime: AgentSessionRuntime, agentTypes: readonly string[] | undefined): ReloadContextInventory;
|
|
11
|
+
export declare function formatReloadContextInventory(inventory: ReloadContextInventory, heading?: string): string;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
export function createReloadContextInventory(runtime, agentTypes) {
|
|
2
|
+
const session = runtime.session;
|
|
3
|
+
const tools = unique(session.getActiveToolNames());
|
|
4
|
+
const skillsReadable = tools.some(isSkillFileAccessTool);
|
|
5
|
+
const subagentsActive = tools.includes("subagents");
|
|
6
|
+
const skills = skillsReadable
|
|
7
|
+
? unique(session.resourceLoader.getSkills().skills.map((skill) => skill.name)).sort(compareText)
|
|
8
|
+
: [];
|
|
9
|
+
const agents = subagentsActive && agentTypes !== undefined
|
|
10
|
+
? unique(agentTypes).sort(compareText)
|
|
11
|
+
: subagentsActive
|
|
12
|
+
? undefined
|
|
13
|
+
: [];
|
|
14
|
+
return {
|
|
15
|
+
model: currentModelLabel(runtime),
|
|
16
|
+
skills,
|
|
17
|
+
tools,
|
|
18
|
+
agents,
|
|
19
|
+
skillsReadable,
|
|
20
|
+
subagentsActive,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function isSkillFileAccessTool(toolName) {
|
|
24
|
+
switch (toolName.trim().toLowerCase()) {
|
|
25
|
+
case "read":
|
|
26
|
+
case "bash":
|
|
27
|
+
case "shell":
|
|
28
|
+
case "shell_command":
|
|
29
|
+
return true;
|
|
30
|
+
default:
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function formatReloadContextInventory(inventory, heading = "Reloaded keybindings, extensions, skills, prompts, themes") {
|
|
35
|
+
return [
|
|
36
|
+
heading,
|
|
37
|
+
"",
|
|
38
|
+
`Model: ${inventory.model}`,
|
|
39
|
+
"",
|
|
40
|
+
`Skills (in context): ${inventory.skillsReadable ? listOrNone(inventory.skills) : "(none; read/bash inactive)"}`,
|
|
41
|
+
"",
|
|
42
|
+
`Tools (active): ${listOrNone(inventory.tools)}`,
|
|
43
|
+
"",
|
|
44
|
+
`Agents (available): ${formatAgents(inventory)}`,
|
|
45
|
+
].join("\n");
|
|
46
|
+
}
|
|
47
|
+
function currentModelLabel(runtime) {
|
|
48
|
+
const model = runtime.session.model;
|
|
49
|
+
if (!model)
|
|
50
|
+
return "unavailable";
|
|
51
|
+
const thinking = runtime.session.thinkingLevel;
|
|
52
|
+
const modelRef = `${model.provider}/${model.id}`;
|
|
53
|
+
return !thinking || thinking === "off" ? modelRef : `${modelRef}:${thinking}`;
|
|
54
|
+
}
|
|
55
|
+
function formatAgents(inventory) {
|
|
56
|
+
if (!inventory.subagentsActive)
|
|
57
|
+
return "(none; subagents tool inactive)";
|
|
58
|
+
if (inventory.agents === undefined)
|
|
59
|
+
return "(catalog unavailable)";
|
|
60
|
+
return listOrNone(inventory.agents);
|
|
61
|
+
}
|
|
62
|
+
function listOrNone(values) {
|
|
63
|
+
return values.length > 0 ? values.join(", ") : "(none)";
|
|
64
|
+
}
|
|
65
|
+
function unique(values) {
|
|
66
|
+
return [...new Set(values.map((value) => value.trim()).filter(Boolean))];
|
|
67
|
+
}
|
|
68
|
+
function compareText(left, right) {
|
|
69
|
+
return left.localeCompare(right);
|
|
70
|
+
}
|
|
@@ -4,6 +4,7 @@ import type { Entry } from "../types.js";
|
|
|
4
4
|
export type AppExtensionActionsHost = {
|
|
5
5
|
isRunning(): boolean;
|
|
6
6
|
runtime(): AgentSessionRuntime | undefined;
|
|
7
|
+
subagentTypes?(runtime: AgentSessionRuntime): readonly string[] | undefined;
|
|
7
8
|
getInput(): string;
|
|
8
9
|
setInput(value: string): void;
|
|
9
10
|
awaitCurrentSessionExtensions(runtime?: AgentSessionRuntime): Promise<void>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { basename } from "node:path";
|
|
2
2
|
import { createId } from "../id.js";
|
|
3
3
|
import { logPixEvent } from "../logger.js";
|
|
4
|
+
import { createReloadContextInventory, formatReloadContextInventory } from "../commands/reload-context-inventory.js";
|
|
4
5
|
export class AppExtensionActionsController {
|
|
5
6
|
host;
|
|
6
7
|
logExtensionError;
|
|
@@ -60,6 +61,11 @@ export class AppExtensionActionsController {
|
|
|
60
61
|
if (!this.isSessionActive(runtime, session))
|
|
61
62
|
return;
|
|
62
63
|
this.host.setSessionStatus(session);
|
|
64
|
+
this.host.addEntry({
|
|
65
|
+
id: createId("system"),
|
|
66
|
+
kind: "system",
|
|
67
|
+
text: formatReloadContextInventory(createReloadContextInventory(runtime, this.host.subagentTypes?.(runtime)), "Reloaded resources"),
|
|
68
|
+
});
|
|
63
69
|
this.host.showToast("Reloaded resources", "success");
|
|
64
70
|
this.host.render();
|
|
65
71
|
},
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const SUBAGENTS_CATALOG_STATE_EVENT = "pi-tools-suite:async-subagents:catalog";
|
|
2
|
+
export interface SubagentCatalogState {
|
|
3
|
+
readonly version: 1;
|
|
4
|
+
readonly sessionId?: string;
|
|
5
|
+
readonly sessionFile?: string;
|
|
6
|
+
readonly model?: string;
|
|
7
|
+
readonly types: readonly string[];
|
|
8
|
+
}
|
|
9
|
+
export declare function parseSubagentCatalogState(value: unknown): SubagentCatalogState | undefined;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export const SUBAGENTS_CATALOG_STATE_EVENT = "pi-tools-suite:async-subagents:catalog";
|
|
2
|
+
export function parseSubagentCatalogState(value) {
|
|
3
|
+
if (!isRecord(value) || value.version !== 1 || !Array.isArray(value.types))
|
|
4
|
+
return undefined;
|
|
5
|
+
if (!value.types.every((type) => typeof type === "string" && type.trim().length > 0))
|
|
6
|
+
return undefined;
|
|
7
|
+
if (value.sessionId !== undefined && typeof value.sessionId !== "string")
|
|
8
|
+
return undefined;
|
|
9
|
+
if (value.sessionFile !== undefined && typeof value.sessionFile !== "string")
|
|
10
|
+
return undefined;
|
|
11
|
+
if (value.model !== undefined && typeof value.model !== "string")
|
|
12
|
+
return undefined;
|
|
13
|
+
return {
|
|
14
|
+
version: 1,
|
|
15
|
+
...(value.sessionId ? { sessionId: value.sessionId } : {}),
|
|
16
|
+
...(value.sessionFile ? { sessionFile: value.sessionFile } : {}),
|
|
17
|
+
...(value.model ? { model: value.model } : {}),
|
|
18
|
+
types: [...new Set(value.types.map((type) => type.trim()))],
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function isRecord(value) {
|
|
22
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23
|
+
}
|
|
@@ -138,57 +138,84 @@ export class AppAutocompleteController {
|
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
export async function completeInputWithPi(runtime, draft, config, signal) {
|
|
141
|
-
const parsedModel = parseModelRef(config.modelRef);
|
|
142
141
|
const modelRuntime = runtime.services.modelRuntime;
|
|
143
|
-
let model = modelRuntime.getModel(parsedModel.provider, parsedModel.modelId);
|
|
144
|
-
if (!model) {
|
|
145
|
-
await modelRuntime.refresh();
|
|
146
|
-
model = modelRuntime.getModel(parsedModel.provider, parsedModel.modelId);
|
|
147
|
-
}
|
|
148
|
-
if (!model)
|
|
149
|
-
throw new Error(`Model not found: ${parsedModel.provider}/${parsedModel.modelId}`);
|
|
150
142
|
const timeoutMs = numberInRange(config.timeoutMs, AUTOCOMPLETE_TIMEOUT_MS, 250, 10_000);
|
|
151
143
|
const maxTokens = numberInRange(config.maxTokens, AUTOCOMPLETE_MAX_TOKENS, 8, 256);
|
|
152
144
|
const maxPromptTokens = numberInRange(config.maxPromptTokens, AUTOCOMPLETE_MAX_PROMPT_TOKENS, 256, 16_000);
|
|
153
145
|
const requestSignal = createTimeoutSignal(signal, timeoutMs);
|
|
154
|
-
const requestMaxTokens = model.maxTokens > 0 ? Math.min(model.maxTokens, maxTokens) : maxTokens;
|
|
155
|
-
const requestModel = { ...model, maxTokens: requestMaxTokens };
|
|
156
146
|
const includeRecentMessages = numberInRange(config.includeRecentMessages, AUTOCOMPLETE_INCLUDE_RECENT_MESSAGES, 0, 20);
|
|
157
147
|
const history = includeRecentMessages > 0 ? autocompleteHistoryFromMessages(runtime.session.messages, includeRecentMessages) : [];
|
|
158
148
|
const prompt = buildAutocompletePrompt({ cwd: runtime.cwd, draft, history, maxPromptTokens });
|
|
159
149
|
if (!prompt)
|
|
160
150
|
return "";
|
|
161
|
-
let output = "";
|
|
162
|
-
let streamError;
|
|
163
151
|
try {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
152
|
+
let refreshed = false;
|
|
153
|
+
let lastError;
|
|
154
|
+
for (const modelRef of modelRefChain(config.modelRef, config.fallbackModels)) {
|
|
155
|
+
if (requestSignal.signal.aborted)
|
|
156
|
+
throw requestSignal.signal.reason ?? new Error("Autocomplete request aborted");
|
|
157
|
+
let parsedModel;
|
|
158
|
+
try {
|
|
159
|
+
parsedModel = parseModelRef(modelRef);
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
lastError = error;
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
let model = modelRuntime.getModel(parsedModel.provider, parsedModel.modelId);
|
|
166
|
+
if (!model && !refreshed) {
|
|
167
|
+
await modelRuntime.refresh();
|
|
168
|
+
refreshed = true;
|
|
169
|
+
model = modelRuntime.getModel(parsedModel.provider, parsedModel.modelId);
|
|
170
|
+
}
|
|
171
|
+
if (!model) {
|
|
172
|
+
lastError = new Error(`Model not found: ${parsedModel.provider}/${parsedModel.modelId}`);
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
try {
|
|
176
|
+
const requestMaxTokens = model.maxTokens > 0 ? Math.min(model.maxTokens, maxTokens) : maxTokens;
|
|
177
|
+
const requestModel = { ...model, maxTokens: requestMaxTokens };
|
|
178
|
+
let output = "";
|
|
179
|
+
let streamError;
|
|
180
|
+
const stream = modelRuntime.streamSimple(requestModel, {
|
|
181
|
+
systemPrompt: AUTOCOMPLETE_SYSTEM_PROMPT,
|
|
182
|
+
messages: [{ role: "user", content: prompt, timestamp: Date.now() }],
|
|
183
|
+
}, {
|
|
184
|
+
cacheRetention: "none",
|
|
185
|
+
maxRetryDelayMs: 0,
|
|
186
|
+
maxRetries: 0,
|
|
187
|
+
maxTokens: requestModel.maxTokens,
|
|
188
|
+
...(parsedModel.thinkingLevel && parsedModel.thinkingLevel !== "off" ? { reasoning: parsedModel.thinkingLevel } : {}),
|
|
189
|
+
signal: requestSignal.signal,
|
|
190
|
+
timeoutMs,
|
|
191
|
+
});
|
|
192
|
+
for await (const event of stream) {
|
|
193
|
+
if (event.type === "text_delta")
|
|
194
|
+
output += event.delta;
|
|
195
|
+
else if (event.type === "done" && !output)
|
|
196
|
+
output = assistantMessageText(event.message);
|
|
197
|
+
else if (event.type === "error")
|
|
198
|
+
streamError = event.error.errorMessage ?? event.reason;
|
|
199
|
+
}
|
|
200
|
+
if (streamError)
|
|
201
|
+
throw new Error(streamError);
|
|
202
|
+
return output;
|
|
203
|
+
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
if (requestSignal.signal.aborted)
|
|
206
|
+
throw requestSignal.signal.reason ?? error;
|
|
207
|
+
lastError = error;
|
|
208
|
+
}
|
|
183
209
|
}
|
|
184
|
-
|
|
185
|
-
throw new Error(streamError);
|
|
186
|
-
return output;
|
|
210
|
+
throw lastError ?? new Error("No autocomplete models are configured");
|
|
187
211
|
}
|
|
188
212
|
finally {
|
|
189
213
|
requestSignal.dispose();
|
|
190
214
|
}
|
|
191
215
|
}
|
|
216
|
+
function modelRefChain(primary, fallbacks) {
|
|
217
|
+
return [...new Set([primary, ...(fallbacks ?? [])].map((ref) => ref.trim()).filter(Boolean))];
|
|
218
|
+
}
|
|
192
219
|
export function autocompleteHistoryFromMessages(messages, includeRecentMessages) {
|
|
193
220
|
const limit = numberInRange(includeRecentMessages, AUTOCOMPLETE_INCLUDE_RECENT_MESSAGES, 0, 20);
|
|
194
221
|
if (limit <= 0)
|
|
@@ -9,6 +9,8 @@ import type { Entry, SessionActivity } from "../types.js";
|
|
|
9
9
|
export type AppInputActionControllerHost = {
|
|
10
10
|
runtime(): AgentSessionRuntime | undefined;
|
|
11
11
|
inputScopeKey?(): string | undefined;
|
|
12
|
+
isDraftTabActive?(): boolean;
|
|
13
|
+
materializeDraftSession?(): Promise<AgentSessionRuntime | undefined>;
|
|
12
14
|
isRunning(): boolean;
|
|
13
15
|
isSessionSwitching(): boolean;
|
|
14
16
|
inputEditor(): InputEditor;
|
|
@@ -149,7 +149,6 @@ export class AppInputActionController {
|
|
|
149
149
|
await this.host.stopVoiceInput();
|
|
150
150
|
if (this.host.inputScopeKey && this.host.inputScopeKey() !== inputScopeKey)
|
|
151
151
|
return;
|
|
152
|
-
const runtime = this.host.runtime();
|
|
153
152
|
const inputEditor = this.host.inputEditor();
|
|
154
153
|
const rawPromptText = inputEditor.promptText;
|
|
155
154
|
const rawDisplayText = inputEditor.expandedText;
|
|
@@ -176,6 +175,14 @@ export class AppInputActionController {
|
|
|
176
175
|
await this.popupActions.submitSlashCommand(promptText);
|
|
177
176
|
return;
|
|
178
177
|
}
|
|
178
|
+
let runtime = this.host.runtime();
|
|
179
|
+
if (!runtime && this.host.isDraftTabActive?.()) {
|
|
180
|
+
runtime = await this.host.materializeDraftSession?.();
|
|
181
|
+
if (this.host.inputScopeKey && this.host.inputScopeKey() !== inputScopeKey)
|
|
182
|
+
return;
|
|
183
|
+
if (!runtime)
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
179
186
|
const message = this.queuedMessages.createSubmittedUserMessage(promptText, displayText, images);
|
|
180
187
|
this.host.requestHistory().add(message.displayText);
|
|
181
188
|
inputEditor.clear();
|
|
@@ -16,6 +16,7 @@ export type InputControllerHost = {
|
|
|
16
16
|
resetInputMenuDismissals(): void;
|
|
17
17
|
render(): void;
|
|
18
18
|
moveActivePopupMenuSelection(delta: number): boolean;
|
|
19
|
+
moveActiveModelThinkingLevel(delta: number): boolean;
|
|
19
20
|
navigateRequestHistory(delta: number): boolean;
|
|
20
21
|
scrollByLines(delta: number): void;
|
|
21
22
|
scrollByPage(delta: number): void;
|
|
@@ -24,8 +25,8 @@ export type InputControllerHost = {
|
|
|
24
25
|
handleInterrupt(): Promise<void>;
|
|
25
26
|
handleEscape(): Promise<void>;
|
|
26
27
|
handleDirectPopupInput(char: string): boolean;
|
|
28
|
+
toggleModelVisibilityMode(): boolean;
|
|
27
29
|
autocompleteModel(): boolean;
|
|
28
|
-
autocompleteThinking(): boolean;
|
|
29
30
|
acceptAutocompleteSuggestion(): boolean;
|
|
30
31
|
autocompleteSlashCommand(): void;
|
|
31
32
|
toggleVoiceRecording(): void;
|
|
@@ -229,6 +229,9 @@ export class AppInputController {
|
|
|
229
229
|
getEscapeSequences() {
|
|
230
230
|
return [
|
|
231
231
|
...SHIFT_ENTER_ESCAPE_SEQUENCES.map((sequence) => [sequence, () => this.insertInputNewline()]),
|
|
232
|
+
["\x1b[Z", () => { this.host.toggleModelVisibilityMode(); }],
|
|
233
|
+
["\x1b[9;2u", () => { this.host.toggleModelVisibilityMode(); }],
|
|
234
|
+
["\x1b[27;2;9~", () => { this.host.toggleModelVisibilityMode(); }],
|
|
232
235
|
["\x1b[13u", () => this.host.handleEnter()],
|
|
233
236
|
["\x1b[13;1u", () => this.host.handleEnter()],
|
|
234
237
|
["\x1b[5~", () => this.host.scrollByPage(-1)],
|
|
@@ -460,6 +463,8 @@ export class AppInputController {
|
|
|
460
463
|
this.host.scrollByLines(1);
|
|
461
464
|
}
|
|
462
465
|
handleArrowLeft() {
|
|
466
|
+
if (this.host.moveActiveModelThinkingLevel(-1))
|
|
467
|
+
return;
|
|
463
468
|
if (this.host.inputEditor.hasSelection) {
|
|
464
469
|
const [start] = this.orderedEditorSelection();
|
|
465
470
|
this.host.inputEditor.clearSelection();
|
|
@@ -473,6 +478,8 @@ export class AppInputController {
|
|
|
473
478
|
}
|
|
474
479
|
}
|
|
475
480
|
handleArrowRight() {
|
|
481
|
+
if (this.host.moveActiveModelThinkingLevel(1))
|
|
482
|
+
return;
|
|
476
483
|
if (this.host.inputEditor.hasSelection) {
|
|
477
484
|
const [, end] = this.orderedEditorSelection();
|
|
478
485
|
this.host.inputEditor.clearSelection();
|
|
@@ -554,8 +561,6 @@ export class AppInputController {
|
|
|
554
561
|
return;
|
|
555
562
|
if (this.host.autocompleteModel())
|
|
556
563
|
return;
|
|
557
|
-
if (this.host.autocompleteThinking())
|
|
558
|
-
return;
|
|
559
564
|
this.host.autocompleteSlashCommand();
|
|
560
565
|
return;
|
|
561
566
|
}
|
|
@@ -129,7 +129,6 @@ export function promptEnhancerTextIsSufficient(text) {
|
|
|
129
129
|
return text.trim().length >= PROMPT_ENHANCER_MIN_TEXT_LENGTH;
|
|
130
130
|
}
|
|
131
131
|
async function enhancePromptWithPi(runtime, draft, config) {
|
|
132
|
-
const parsedModel = parseModelRef(config.modelRef);
|
|
133
132
|
const services = await promptEnhancerPiDeps.createAgentSessionServices({
|
|
134
133
|
cwd: runtime.cwd,
|
|
135
134
|
agentDir: runtime.services.agentDir,
|
|
@@ -145,41 +144,60 @@ async function enhancePromptWithPi(runtime, draft, config) {
|
|
|
145
144
|
},
|
|
146
145
|
});
|
|
147
146
|
await services.modelRuntime.refresh();
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
147
|
+
let lastError;
|
|
148
|
+
for (const modelRef of modelRefChain(config.modelRef, config.fallbackModels)) {
|
|
149
|
+
let parsedModel;
|
|
150
|
+
try {
|
|
151
|
+
parsedModel = parseModelRef(modelRef);
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
lastError = error;
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
const model = services.modelRuntime.getModel(parsedModel.provider, parsedModel.modelId);
|
|
158
|
+
if (!model) {
|
|
159
|
+
lastError = new Error(modelNotFoundMessage(parsedModel.provider, parsedModel.modelId, services.modelRuntime.getModels()));
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
const { session } = await promptEnhancerPiDeps.createAgentSessionFromServices({
|
|
163
|
+
services,
|
|
164
|
+
sessionManager: promptEnhancerPiDeps.sessionManagerInMemory(runtime.cwd),
|
|
165
|
+
model,
|
|
166
|
+
thinkingLevel: parsedModel.thinkingLevel ?? "minimal",
|
|
167
|
+
noTools: "all",
|
|
168
|
+
});
|
|
169
|
+
let output = "";
|
|
170
|
+
let streamError;
|
|
171
|
+
const unsubscribe = session.subscribe((event) => {
|
|
172
|
+
if (event.type !== "message_update")
|
|
173
|
+
return;
|
|
174
|
+
const assistantEvent = event.assistantMessageEvent;
|
|
175
|
+
if (assistantEvent.type === "text_delta")
|
|
176
|
+
output += assistantEvent.delta;
|
|
177
|
+
else if (assistantEvent.type === "error")
|
|
178
|
+
streamError = assistantEvent.error.errorMessage ?? assistantEvent.reason;
|
|
179
|
+
});
|
|
180
|
+
try {
|
|
181
|
+
await session.prompt(buildEnhancerPrompt(draft), { expandPromptTemplates: false });
|
|
182
|
+
if (streamError)
|
|
183
|
+
throw new Error(streamError);
|
|
184
|
+
const cleaned = cleanupEnhancedPrompt(output);
|
|
185
|
+
if (cleaned.length === 0)
|
|
186
|
+
throw new Error("model returned an empty prompt");
|
|
187
|
+
return cleaned;
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
lastError = error;
|
|
191
|
+
}
|
|
192
|
+
finally {
|
|
193
|
+
unsubscribe();
|
|
194
|
+
session.dispose();
|
|
195
|
+
}
|
|
182
196
|
}
|
|
197
|
+
throw lastError ?? new Error("No prompt enhancer models are configured");
|
|
198
|
+
}
|
|
199
|
+
function modelRefChain(primary, fallbacks) {
|
|
200
|
+
return [...new Set([primary, ...(fallbacks ?? [])].map((ref) => ref.trim()).filter(Boolean))];
|
|
183
201
|
}
|
|
184
202
|
function buildEnhancerPrompt(draft) {
|
|
185
203
|
return [
|