@timurproko/a1 0.2.7-dev.1270 → 0.2.7-dev.1275
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 +6 -0
- package/dist/app/session-shell/apps-dialog.d.ts +33 -0
- package/dist/app/session-shell/apps-dialog.js +61 -0
- package/dist/app/session-shell/dialog-coordinator.d.ts +8 -0
- package/dist/app/session-shell/dialog-coordinator.js +72 -3
- package/dist/app/session-shell/session-selectors.d.ts +1 -1
- package/dist/app/session-shell/session-selectors.js +1 -1
- package/dist/app/session-shell/session-shell.js +9 -3
- package/dist/app/session-shell/shell-host.d.ts +1 -0
- package/dist/app/session-shell/shell-host.js +22 -11
- package/dist/app/session-shell/workflow-output.js +12 -0
- package/dist/app/session-shell/workflow-router.d.ts +1 -1
- package/dist/composition/owned-ui.js +17 -13
- package/dist/contracts/owned-ui/session-presenters.d.ts +1 -1
- package/dist/contracts/owned-ui/session-workflows.d.ts +3 -1
- package/dist/contracts/owned-ui/shell-components.d.ts +2 -0
- package/dist/contracts/presentation/progress-palette.generated.d.ts +1 -1
- package/dist/contracts/presentation/progress-palette.generated.js +1 -1
- package/dist/contracts/presentation/terminal.d.ts +4 -0
- package/dist/contracts/presentation/theme.d.ts +2 -0
- package/dist/foundation/lifecycle/user-exports.d.ts +5 -0
- package/dist/foundation/lifecycle/user-exports.js +37 -0
- package/dist/foundation/startup/startup-descriptor.js +2 -2
- package/dist/integrations/pi/components/models-dialog-loader.d.ts +11 -0
- package/dist/integrations/pi/components/models-dialog-loader.js +45 -0
- package/dist/integrations/pi/components/models-dialog.d.ts +2 -0
- package/dist/integrations/pi/components/models-dialog.js +13 -7
- package/dist/integrations/pi/components/resources/builtin-themes.d.ts +2 -2
- package/dist/integrations/pi/components/resources/builtin-themes.js +2 -2
- package/dist/integrations/pi/components/shell-editor-autocomplete.js +21 -15
- package/dist/integrations/pi/components/shell-footer-status.js +3 -2
- package/dist/integrations/pi/components/shell-presenters-info.js +1 -1
- package/dist/integrations/pi/components/shell-presenters-transcript.js +3 -1
- package/dist/integrations/pi/components/shell-selectors-dialogs.d.ts +2 -1
- package/dist/integrations/pi/components/shell-selectors-dialogs.js +2 -8
- package/dist/integrations/pi/components/theme.d.ts +2 -0
- package/dist/integrations/pi/components/theme.js +5 -0
- package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.d.ts +8 -7
- package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.js +13 -7
- package/dist/integrations/pi/components/upstream/assets/earendil-image.json +2 -2
- package/dist/integrations/pi/components/upstream/components/countdown-timer.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/earendil-announcement.js +1 -1
- package/dist/integrations/pi/components/upstream/components/extension-editor.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/extension-editor.js +1 -1
- package/dist/integrations/pi/components/upstream/components/extension-input.js +1 -1
- package/dist/integrations/pi/components/upstream/components/extension-selector.js +9 -2
- package/dist/integrations/pi/components/upstream/components/mermaid.d.ts +2 -1
- package/dist/integrations/pi/components/upstream/components/mermaid.js +26 -21
- package/dist/integrations/pi/components/upstream/components/owned-editor.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/owned-editor.js +1 -1
- package/dist/integrations/pi/components/upstream/components/pi-logo.js +1 -1
- package/dist/integrations/pi/components/upstream/components/scoped-models-selector.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/session-footer.js +9 -14
- package/dist/integrations/pi/components/upstream/components/session-selector-search.js +1 -1
- package/dist/integrations/pi/components/upstream/components/session-selector.js +1 -1
- package/dist/integrations/pi/components/upstream/components/skill-invocation-message.d.ts +6 -2
- package/dist/integrations/pi/components/upstream/components/skill-invocation-message.js +27 -3
- package/dist/integrations/pi/components/upstream/components/status-indicator.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/status-indicator.js +1 -1
- package/dist/integrations/pi/components/upstream/components/themed-text.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/themed-text.js +1 -1
- package/dist/integrations/pi/components/upstream/components/thinking-selector.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/thinking-selector.js +1 -1
- package/dist/integrations/pi/components/upstream/components/tool-execution.js +1 -1
- package/dist/integrations/pi/components/upstream/components/tree-selector.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/tree-selector.js +7 -6
- package/dist/integrations/pi/components/upstream/components/trust-selector.js +1 -1
- package/dist/integrations/pi/components/upstream/external-editor.js +1 -1
- package/dist/integrations/pi/components/upstream/history/editor-core.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/history/editor-core.js +2 -2
- package/dist/integrations/pi/components/upstream/history/kill-ring.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/history/kill-ring.js +1 -1
- package/dist/integrations/pi/components/upstream/history/printable-key.js +1 -1
- package/dist/integrations/pi/components/upstream/history/text-helpers.js +1 -1
- package/dist/integrations/pi/components/upstream/history/undo-stack.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/history/undo-stack.js +1 -1
- package/dist/integrations/pi/components/upstream/history/word-navigation.js +1 -1
- package/dist/integrations/pi/components/upstream/model-search.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/program-status-reporter.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/theme/theme.js +1 -1
- package/dist/integrations/pi/engine/adapter.d.ts +1 -1
- package/dist/integrations/pi/engine/adapter.js +3 -3
- package/dist/integrations/pi/engine/host.d.ts +1 -1
- package/dist/integrations/pi/engine/resources/changelog.json +4 -4
- package/dist/integrations/pi/engine/workflow-export.d.ts +4 -0
- package/dist/integrations/pi/engine/workflow-export.js +25 -0
- package/dist/integrations/pi/engine/workflow-runner.d.ts +1 -0
- package/dist/integrations/pi/engine/workflow-runner.js +6 -10
- package/dist/integrations/pi/engine/workflow-support.d.ts +2 -1
- package/dist/integrations/pi/engine/workflow-support.js +28 -25
- package/dist/integrations/pi/engine/workflows.d.ts +6 -1
- package/dist/integrations/pi/engine/workflows.js +1 -1
- package/dist/integrations/pi/session-presenters/presentation.js +2 -1
- package/dist/integrations/pi/session-presenters/presenters.js +22 -10
- package/dist/integrations/pi/startup-public.js +289 -240
- package/dist/integrations/pi/startup-public.manifest.json +579 -363
- package/dist/integrations/pi/tui-runtime/adapter.js +3 -1
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +1 -1
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.js +1 -1
- package/dist/integrations/pi/tui-runtime/overlay-geometry.d.ts +5 -2
- package/dist/integrations/pi/tui-runtime/overlay-geometry.js +12 -2
- package/dist/runtime-payload-inventory.json +8044 -6930
- package/dist/ui/components/dialog-panel.d.ts +4 -3
- package/dist/ui/components/dialog-panel.js +9 -13
- package/dist/ui/components/index.d.ts +1 -1
- package/dist/ui/components/index.js +1 -1
- package/dist/ui/components/spans.d.ts +7 -0
- package/dist/ui/components/spans.js +63 -1
- package/docs/architecture/prompt-suggestions.md +1 -1
- package/docs/architecture/ui-reference-provenance.md +2 -1
- package/docs/features/prompt-history.md +1 -1
- package/docs/features/session-exports.md +15 -0
- package/docs/local-worktree-cleanup.md +24 -0
- package/package.json +6 -6
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { AgentSession } from "../startup-public.js";
|
|
2
|
+
import type { PiWorkflowHost, PiWorkflowRequest, PiWorkflowResult } from "./workflows.js";
|
|
3
|
+
/** Explicit paths and comparison defaults stay pinned; only bare-A1 implicit exports use persistent user storage. */
|
|
4
|
+
export declare function exportWorkflow(request: PiWorkflowRequest, session: AgentSession, bare: boolean, reserve?: PiWorkflowHost["reserveExport"]): Promise<PiWorkflowResult>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { requireCapability } from "./message-values.js";
|
|
2
|
+
import { pathArgument, workflowResult } from "./workflow-support.js";
|
|
3
|
+
/** Explicit paths and comparison defaults stay pinned; only bare-A1 implicit exports use persistent user storage. */
|
|
4
|
+
export async function exportWorkflow(request, session, bare, reserve) {
|
|
5
|
+
const argument = request.argument.trim();
|
|
6
|
+
const flag = bare ? /^(--jsonl|--html)(?:\s+([\s\S]+))?$/u.exec(argument) : null;
|
|
7
|
+
const explicit = pathArgument(flag ? flag[2] ?? "" : argument);
|
|
8
|
+
if (bare && (flag?.[2] || argument && !flag) && explicit === undefined)
|
|
9
|
+
throw new Error("Export destination is invalid");
|
|
10
|
+
const format = flag ? flag[1] === "--jsonl" ? "jsonl" : "html" : explicit?.toLowerCase().endsWith(".jsonl") ? "jsonl" : "html";
|
|
11
|
+
if (bare && explicit === undefined && reserve === undefined)
|
|
12
|
+
throw new Error("Session export storage is unavailable");
|
|
13
|
+
const reserved = bare && explicit === undefined ? await reserve(session.sessionId ?? "session", format) : undefined;
|
|
14
|
+
const path = reserved?.path ?? explicit;
|
|
15
|
+
try {
|
|
16
|
+
const file = format === "jsonl"
|
|
17
|
+
? await requireCapability(session.exportToJsonl, "exportToJsonl").call(session, path)
|
|
18
|
+
: await requireCapability(session.exportToHtml, "exportToHtml").call(session, path);
|
|
19
|
+
return workflowResult(request.command, "completed", `Session exported to: ${String(file)}`);
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
await reserved?.failed();
|
|
23
|
+
throw error;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -5,6 +5,7 @@ import type { PiBashWorkflowResult, PiWorkflowHost, PiWorkflowInteractionHost, P
|
|
|
5
5
|
type PiSessionApi = AgentSession;
|
|
6
6
|
type PiRuntimeApi = AgentSessionRuntime;
|
|
7
7
|
interface PiWorkflowRunnerOptions {
|
|
8
|
+
readonly productMode?: "bare" | "comparison";
|
|
8
9
|
readonly agentDir: string;
|
|
9
10
|
readonly host: PiWorkflowHost;
|
|
10
11
|
readonly contexts: PiWorkflowContexts;
|
|
@@ -14,6 +14,7 @@ const MAX_PENDING_WORK = 32;
|
|
|
14
14
|
*/
|
|
15
15
|
export class PiWorkflowRunner {
|
|
16
16
|
#agentDir;
|
|
17
|
+
#bare;
|
|
17
18
|
#host;
|
|
18
19
|
#authentication;
|
|
19
20
|
#ports;
|
|
@@ -21,6 +22,7 @@ export class PiWorkflowRunner {
|
|
|
21
22
|
#clipboardWriter;
|
|
22
23
|
constructor(options, ports) {
|
|
23
24
|
this.#agentDir = options.agentDir;
|
|
25
|
+
this.#bare = options.productMode === "bare";
|
|
24
26
|
this.#host = options.host;
|
|
25
27
|
this.#ports = ports;
|
|
26
28
|
this.#authentication = new PiProviderAuthentication({ agentDir: options.agentDir, contexts: options.contexts }, {
|
|
@@ -68,7 +70,7 @@ export class PiWorkflowRunner {
|
|
|
68
70
|
const reasoning = result.model.reasoning === true;
|
|
69
71
|
const thinking = this.#ports.thinkingLevel();
|
|
70
72
|
const suffix = reasoning && thinking !== "off" ? ` (thinking: ${thinking})` : "";
|
|
71
|
-
return workflowResult("model", "completed", `Switched to ${modelName}${suffix}`, undefined, "status");
|
|
73
|
+
return { ...workflowResult("model", "completed", `Switched to ${modelName}${suffix}`, undefined, "status"), presentation: { kind: "model-change" } };
|
|
72
74
|
}
|
|
73
75
|
catch (error) {
|
|
74
76
|
return workflowResult("model", "failed", error instanceof Error ? error.message : String(error));
|
|
@@ -221,9 +223,10 @@ export class PiWorkflowRunner {
|
|
|
221
223
|
this.#ports.setActiveModel({ providerId, modelId, displayName: stringProperty(model, "name") ?? modelId });
|
|
222
224
|
this.#ports.emitView();
|
|
223
225
|
const resultMessage = { kind: "status", message: options.persist ? `Default model: ${providerId}/${modelId}` : `Model: ${modelId}` };
|
|
224
|
-
|
|
226
|
+
const result = messages.length === 0
|
|
225
227
|
? workflowResult(request.command, "completed", resultMessage.message)
|
|
226
228
|
: workflowResult(request.command, "completed", resultMessage.message, undefined, "status", [...messages, resultMessage]);
|
|
229
|
+
return { ...result, presentation: { kind: "model-change" } };
|
|
227
230
|
}
|
|
228
231
|
async #performWorkflow(request) {
|
|
229
232
|
const session = this.#requireSession();
|
|
@@ -240,7 +243,7 @@ export class PiWorkflowRunner {
|
|
|
240
243
|
case "model": return this.#modelWorkflow(call);
|
|
241
244
|
case "models": return this.#modelsWorkflow(call);
|
|
242
245
|
case "scoped-models": return scopedModelsWorkflow(call);
|
|
243
|
-
case "export": return exportWorkflow(
|
|
246
|
+
case "export": return (await import("./workflow-export.js")).exportWorkflow(request, session, this.#bare, this.#host.reserveExport);
|
|
244
247
|
case "import": return importWorkflow(call);
|
|
245
248
|
case "share": return (await import("./workflow-share.js")).runShareWorkflow({ request, session, runtime, host: this.#host });
|
|
246
249
|
case "copy": return copyWorkflow(call, text => this.copyWorkflowText(text));
|
|
@@ -340,13 +343,6 @@ function scopedModelsWorkflow({ request, session, runtime, selection }) {
|
|
|
340
343
|
requireCapability(session.setScopedModels, "setScopedModels").call(session, [{ model }]);
|
|
341
344
|
return workflowResult(request.command, "completed", `Enabled scoped model ${selection}`);
|
|
342
345
|
}
|
|
343
|
-
async function exportWorkflow({ request, session, argument }) {
|
|
344
|
-
const path = pathArgument(argument);
|
|
345
|
-
const file = path?.toLowerCase().endsWith(".jsonl")
|
|
346
|
-
? requireCapability(session.exportToJsonl, "exportToJsonl").call(session, path)
|
|
347
|
-
: await requireCapability(session.exportToHtml, "exportToHtml").call(session, path);
|
|
348
|
-
return workflowResult(request.command, "completed", `Session exported to: ${String(file)}`);
|
|
349
|
-
}
|
|
350
346
|
async function importWorkflow({ request, runtime, argument }) {
|
|
351
347
|
const path = pathArgument(argument);
|
|
352
348
|
if (!path)
|
|
@@ -7,7 +7,8 @@ export declare function pinnedSessionInfoPresentation(value: unknown, sessionNam
|
|
|
7
7
|
readonly mode: unknown;
|
|
8
8
|
readonly status: unknown;
|
|
9
9
|
}): PiSessionInfoPresentation;
|
|
10
|
-
|
|
10
|
+
/** Fill optional host services while retaining class methods and their original receiver. */
|
|
11
|
+
export declare function resolveWorkflowHost(host?: Partial<PiWorkflowHost>): PiWorkflowHost;
|
|
11
12
|
export declare function workflowLoginNotification(event: unknown): PiWorkflowLoginNotification | undefined;
|
|
12
13
|
export declare function workflowResult(command: PiWorkflowRequest["command"], outcome: PiWorkflowResult["outcome"], message: string, detail?: string, messageKind?: PiWorkflowResult["messageKind"], messages?: readonly PiWorkflowMessage[]): PiWorkflowResult;
|
|
13
14
|
export declare function workflowConfirmation(command: PiWorkflowRequest["command"], message: string, detail?: string): PiWorkflowResult;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/** Pure helpers behind pinned Pi's workflows: result wording, session-info presentation, model matching, and option shaping. */
|
|
2
2
|
import { execFile } from "node:child_process";
|
|
3
3
|
import { promisify } from "node:util";
|
|
4
|
-
import { readPinnedCommandChangelog } from "./changelog.js";
|
|
5
4
|
import { dynamicObject, finiteNumber, isRecord, stringProperty, stringValue } from "./message-values.js";
|
|
6
5
|
import { copyToClipboard } from "../startup-public.js";
|
|
7
6
|
const execFileAsync = promisify(execFile);
|
|
@@ -9,43 +8,44 @@ export const AUTH_REFRESH_TIMEOUT_MS = 15_000;
|
|
|
9
8
|
// Provenance: the pinned engine's core/model-resolver.ts defaultModelPerProvider, which every
|
|
10
9
|
// upgrade that adds a provider extends; the version this mirrors is the pin, not one named here.
|
|
11
10
|
export const PINNED_DEFAULT_MODEL_BY_PROVIDER = Object.freeze({
|
|
12
|
-
"amazon-bedrock": "us.anthropic.claude-opus-
|
|
11
|
+
"amazon-bedrock": "us.anthropic.claude-opus-5-5",
|
|
13
12
|
"ant-ling": "Ring-2.6-1T",
|
|
14
|
-
anthropic: "claude-opus-
|
|
13
|
+
anthropic: "claude-opus-5-5",
|
|
15
14
|
openai: "gpt-6.1-sol",
|
|
16
|
-
azure: "gpt-
|
|
15
|
+
azure: "gpt-6.1-sol",
|
|
17
16
|
"openai-codex": "gpt-6.1-sol",
|
|
18
17
|
radius: "balanced",
|
|
19
18
|
nvidia: "nvidia/nemotron-3.5-super-vl-120b-a12b",
|
|
20
19
|
deepseek: "deepseek-v4-pro",
|
|
21
|
-
google: "gemini-
|
|
22
|
-
"google-vertex": "gemini-
|
|
20
|
+
google: "gemini-4-argon",
|
|
21
|
+
"google-vertex": "gemini-4-argon",
|
|
23
22
|
"github-copilot": "gpt-6.1-sol",
|
|
24
|
-
openrouter: "moonshotai/kimi-k2.
|
|
25
|
-
"vercel-ai-gateway": "zai/glm-5.
|
|
23
|
+
openrouter: "moonshotai/kimi-k2.7-code",
|
|
24
|
+
"vercel-ai-gateway": "zai/glm-5.3",
|
|
26
25
|
xai: "grok-4.7",
|
|
27
26
|
groq: "openai/gpt-oss-120b",
|
|
28
27
|
cerebras: "gpt-oss-120b",
|
|
29
28
|
zai: "glm-5.3",
|
|
30
29
|
"zai-coding-cn": "glm-5.3",
|
|
31
30
|
mistral: "devstral-medium-latest",
|
|
32
|
-
minimax: "MiniMax-
|
|
33
|
-
"minimax-cn": "MiniMax-
|
|
34
|
-
moonshotai: "kimi-k2.
|
|
35
|
-
"moonshotai-cn": "kimi-k2.
|
|
36
|
-
huggingface: "moonshotai/Kimi-K2.
|
|
31
|
+
minimax: "MiniMax-M3",
|
|
32
|
+
"minimax-cn": "MiniMax-M3",
|
|
33
|
+
moonshotai: "kimi-k2.7-code",
|
|
34
|
+
"moonshotai-cn": "kimi-k2.7-code",
|
|
35
|
+
huggingface: "moonshotai/Kimi-K2.7-Code",
|
|
37
36
|
fireworks: "accounts/fireworks/models/kimi-k3",
|
|
38
37
|
together: "moonshotai/Kimi-K3",
|
|
39
|
-
baseten: "zai-org/GLM-5.
|
|
40
|
-
opencode: "kimi-k2.
|
|
41
|
-
"opencode-go": "kimi-k3",
|
|
38
|
+
baseten: "zai-org/GLM-5.3",
|
|
39
|
+
opencode: "kimi-k2.7-code",
|
|
40
|
+
"opencode-go": "kimi-k3.1-pro",
|
|
42
41
|
"kimi-coding": "kimi-for-coding",
|
|
43
42
|
meta: "muse-spark-1.3",
|
|
44
|
-
"cloudflare-workers-ai": "@cf/moonshotai/kimi-k2.
|
|
45
|
-
"cloudflare-ai-gateway": "workers-ai/@cf/moonshotai/kimi-k2.
|
|
46
|
-
"qwen-token-plan": "qwen3.
|
|
47
|
-
"qwen-token-plan-cn": "qwen3.
|
|
43
|
+
"cloudflare-workers-ai": "@cf/moonshotai/kimi-k2.7-code",
|
|
44
|
+
"cloudflare-ai-gateway": "workers-ai/@cf/moonshotai/kimi-k2.7-code",
|
|
45
|
+
"qwen-token-plan": "qwen3.8-max",
|
|
46
|
+
"qwen-token-plan-cn": "qwen3.8-max",
|
|
48
47
|
"qwen-token-plan-individual": "qwen3.8-max",
|
|
48
|
+
"qwen-token-plan-individual-cn": "qwen3.8-max",
|
|
49
49
|
xiaomi: "mimo-v2.6-pro",
|
|
50
50
|
"xiaomi-token-plan-cn": "mimo-v2.6-pro",
|
|
51
51
|
"xiaomi-token-plan-ams": "mimo-v2.6-pro",
|
|
@@ -196,14 +196,17 @@ function pinnedCacheWaste(entries, modelRuntime) {
|
|
|
196
196
|
}
|
|
197
197
|
return totals;
|
|
198
198
|
}
|
|
199
|
-
|
|
199
|
+
/** Fill optional host services while retaining class methods and their original receiver. */
|
|
200
|
+
export function resolveWorkflowHost(host) {
|
|
200
201
|
return {
|
|
201
|
-
copyText: copyToClipboard,
|
|
202
|
-
|
|
202
|
+
copyText: host?.copyText?.bind(host) ?? copyToClipboard,
|
|
203
|
+
runCommand: host?.runCommand?.bind(host) ?? (async (command, arguments_, options) => {
|
|
203
204
|
const result = await execFileAsync(command, [...arguments_], { encoding: "utf8", signal: options?.signal });
|
|
204
205
|
return { stdout: result.stdout, stderr: result.stderr };
|
|
205
|
-
},
|
|
206
|
-
readChangelog: readPinnedCommandChangelog,
|
|
206
|
+
}),
|
|
207
|
+
readChangelog: host?.readChangelog?.bind(host) ?? (async (since) => (await import("./changelog.js")).readPinnedCommandChangelog(since)),
|
|
208
|
+
...(host?.reserveExport === undefined ? {} : { reserveExport: host.reserveExport.bind(host) }),
|
|
209
|
+
...(host?.fetch === undefined ? {} : { fetch: host.fetch.bind(host) }),
|
|
207
210
|
};
|
|
208
211
|
}
|
|
209
212
|
export function workflowLoginNotification(event) {
|
|
@@ -13,7 +13,7 @@ export type PiWorkflowCommandName = OwnedUiWorkflowCommandName;
|
|
|
13
13
|
export type PiHiddenWorkflowCommandName = OwnedUiHiddenWorkflowCommandName;
|
|
14
14
|
export declare const OWNED_MODELS_COMMAND_NAME: "models";
|
|
15
15
|
type OwnedModelsCommandName = OwnedUiModelsCommandName;
|
|
16
|
-
type OwnedWorkflowCommandName = Exclude<PiWorkflowCommandName, "model" | "scoped-models"> | OwnedModelsCommandName;
|
|
16
|
+
type OwnedWorkflowCommandName = Exclude<PiWorkflowCommandName, "model" | "scoped-models" | "settings" | "changelog" | "hotkeys"> | OwnedModelsCommandName;
|
|
17
17
|
/** Bare A1's advertised catalog: `models` replaces the pinned pair and is followed by `thinking`. */
|
|
18
18
|
export declare const OWNED_WORKFLOW_COMMAND_NAMES: readonly OwnedWorkflowCommandName[];
|
|
19
19
|
export type PiProductMode = OwnedUiSessionProductMode;
|
|
@@ -52,6 +52,11 @@ export type PiScopedModelsRefreshResult = OwnedUiScopedModelsRefreshResult;
|
|
|
52
52
|
export type PiModelsContext = OwnedUiModelsContext;
|
|
53
53
|
export type PiModelsRefreshResult = OwnedUiModelsRefreshResult;
|
|
54
54
|
export interface PiWorkflowHost {
|
|
55
|
+
/** Product-owned persistent storage; integrations never choose the user's home or disposable roots. */
|
|
56
|
+
reserveExport?(sessionId: string, format: "html" | "jsonl"): Promise<{
|
|
57
|
+
readonly path: string;
|
|
58
|
+
failed(): Promise<void>;
|
|
59
|
+
}>;
|
|
55
60
|
copyText(text: string): Promise<void>;
|
|
56
61
|
runCommand(command: string, arguments_: readonly string[], options?: {
|
|
57
62
|
readonly signal?: AbortSignal;
|
|
@@ -14,7 +14,7 @@ export const OWNED_MODELS_COMMAND_NAME = OWNED_UI_MODELS_COMMAND_NAME;
|
|
|
14
14
|
/** Bare A1's advertised catalog: `models` replaces the pinned pair and is followed by `thinking`. */
|
|
15
15
|
export const OWNED_WORKFLOW_COMMAND_NAMES = Object.freeze(PINNED_PI_WORKFLOW_COMMAND_NAMES.flatMap((name) => name === "model"
|
|
16
16
|
? [OWNED_MODELS_COMMAND_NAME, "thinking"]
|
|
17
|
-
: name === "thinking" || name === "scoped-models" ? [] : [name]));
|
|
17
|
+
: name === "thinking" || name === "scoped-models" || name === "settings" || name === "changelog" || name === "hotkeys" ? [] : [name]));
|
|
18
18
|
/** The advertised command catalog for a product mode; hidden routes are shared by both. */
|
|
19
19
|
export function workflowCommandNames(productMode) {
|
|
20
20
|
return productMode === "bare" ? OWNED_WORKFLOW_COMMAND_NAMES : PINNED_PI_WORKFLOW_COMMAND_NAMES;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PI_THEME_SOURCE } from "../components/theme.js";
|
|
1
|
+
import { PI_THEME_SOURCE, paintPiFloatingDialog } from "../components/theme.js";
|
|
2
2
|
import { piCanvasBackgroundAnsi, PINNED_PI_LAYOUT } from "../components/upstream/theme/theme.js";
|
|
3
3
|
import { PI_TERMINAL_RUNTIME } from "../tui-runtime/runtime-factory.js";
|
|
4
4
|
/** Everything the shell takes from Pi's presentation, assembled once from the component and TUI adapters. */
|
|
@@ -6,5 +6,6 @@ export const PI_SHELL_PRESENTATION = Object.freeze({
|
|
|
6
6
|
theme: PI_THEME_SOURCE,
|
|
7
7
|
canvasBackground: (style) => piCanvasBackgroundAnsi(style),
|
|
8
8
|
pinnedOutputPad: PINNED_PI_LAYOUT.outputPad,
|
|
9
|
+
floatingDialogSurface: paintPiFloatingDialog,
|
|
9
10
|
terminalRuntime: PI_TERMINAL_RUNTIME,
|
|
10
11
|
});
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { createPiShellModelSelector, createPiShellModelsDialog, createPiShellScopedModelsSelector, createPiShellSessionSelector, createPiShellSettingsSelector, } from "../components/shell-selectors-dialogs.js";
|
|
2
2
|
import { PI_SHELL_PRESENTATION } from "./presentation.js";
|
|
3
3
|
import { createPiShellComponents } from "./components.js";
|
|
4
|
+
/** An explicit session scope wins; otherwise use persisted members still present in the catalog. */
|
|
5
|
+
function modelDialogScope(context) {
|
|
6
|
+
const available = new Set(context.models.map(model => `${model.provider}/${model.id}`));
|
|
7
|
+
const savedScopeIds = context.persistedScopeIds.filter(id => available.has(id));
|
|
8
|
+
return { savedScopeIds, scopeIds: context.sessionScopeIds.length > 0 ? context.sessionScopeIds : savedScopeIds };
|
|
9
|
+
}
|
|
4
10
|
const MODEL_REFRESH_TIMEOUT_MS = 15_000;
|
|
5
11
|
const MODEL_REFRESH_TIMED_OUT = "Model refresh timed out; showing cached models.";
|
|
6
12
|
/**
|
|
@@ -179,13 +185,10 @@ export function createPiSessionPresenters(adapter, options = {}) {
|
|
|
179
185
|
host.requestRender();
|
|
180
186
|
},
|
|
181
187
|
/** The bare-A1 unified Models dialog: switch on Enter, scope on Space, persist on Ctrl+S, all through the engine. */
|
|
182
|
-
openModelsDialog(host, initialQuery) {
|
|
188
|
+
async openModelsDialog(host, initialQuery) {
|
|
183
189
|
const catalog = adapter.catalog;
|
|
184
190
|
const context = catalog.modelsContext();
|
|
185
|
-
const
|
|
186
|
-
const savedScopeIds = context.persistedScopeIds.filter(id => available.has(id));
|
|
187
|
-
// Invariant: an explicit session scope wins; otherwise the dialog starts from what is persisted, never from "all rows scoped".
|
|
188
|
-
const scopeIds = context.sessionScopeIds.length > 0 ? context.sessionScopeIds : savedScopeIds;
|
|
191
|
+
const { savedScopeIds, scopeIds } = modelDialogScope(context);
|
|
189
192
|
const refresh = new ModelCatalogRefresh();
|
|
190
193
|
const close = () => {
|
|
191
194
|
refresh.stop();
|
|
@@ -193,12 +196,11 @@ export function createPiSessionPresenters(adapter, options = {}) {
|
|
|
193
196
|
host.requestRender();
|
|
194
197
|
};
|
|
195
198
|
const dialog = createPiShellModelsDialog({
|
|
196
|
-
models: context.models,
|
|
199
|
+
viewportHeight: () => host.viewport().rows, models: context.models,
|
|
197
200
|
activeModelId: context.activeModelId,
|
|
198
201
|
scopeIds,
|
|
199
202
|
savedScopeIds,
|
|
200
203
|
...(initialQuery === undefined ? {} : { initialQuery }),
|
|
201
|
-
refreshStatus: "Refreshing model catalogs…",
|
|
202
204
|
requestRender: () => host.requestRender(),
|
|
203
205
|
onSelect: modelId => {
|
|
204
206
|
void host.runWorkflow({ command: "models", argument: "", selection: modelId }).then(result => {
|
|
@@ -231,9 +233,7 @@ export function createPiSessionPresenters(adapter, options = {}) {
|
|
|
231
233
|
dialog.dispose?.();
|
|
232
234
|
},
|
|
233
235
|
};
|
|
234
|
-
host
|
|
235
|
-
host.requestRender();
|
|
236
|
-
refresh.run(host, component, signal => catalog.refreshModels(signal), refreshed => component.updateModels(refreshed.models));
|
|
236
|
+
await presentModelsSurface(host, component, refresh, catalog);
|
|
237
237
|
},
|
|
238
238
|
openScopedModelsSelector(host) {
|
|
239
239
|
const catalog = adapter.catalog;
|
|
@@ -286,6 +286,18 @@ export function createPiSessionPresenters(adapter, options = {}) {
|
|
|
286
286
|
},
|
|
287
287
|
};
|
|
288
288
|
}
|
|
289
|
+
async function presentModelsSurface(host, component, refresh, catalog) {
|
|
290
|
+
const releasePresentation = host.beginPresentationHold?.();
|
|
291
|
+
try {
|
|
292
|
+
host.setInputSurface(component);
|
|
293
|
+
host.requestRender();
|
|
294
|
+
refresh.run(host, component, signal => catalog.refreshModels(signal), refreshed => component.updateModels(refreshed.models));
|
|
295
|
+
await component.ready;
|
|
296
|
+
}
|
|
297
|
+
finally {
|
|
298
|
+
releasePresentation?.();
|
|
299
|
+
}
|
|
300
|
+
}
|
|
289
301
|
/**
|
|
290
302
|
* One model-catalog refresh owned by an open dialog: it aborts after fifteen seconds or when the dialog
|
|
291
303
|
* closes, and a result that arrives after the dialog closed is dropped.
|