@tt-a1i/openpi 0.3.1 → 0.5.0
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 +184 -59
- package/SETUP.md +23 -7
- package/assets/openpi-launch-card-v1.webp +0 -0
- package/bin/openpi.js +145 -0
- package/extensions/ask-user/index.ts +30 -14
- package/extensions/background-terminals/index.ts +30 -2
- package/extensions/background-terminals/src/domain.ts +2 -0
- package/extensions/background-terminals/src/manager.ts +486 -106
- package/extensions/background-terminals/src/output.ts +33 -0
- package/extensions/background-terminals/src/prompt.ts +14 -6
- package/extensions/background-terminals/src/result-delivery.ts +4 -1
- package/extensions/background-terminals/src/ui/ps.ts +132 -129
- package/extensions/capabilities/index.ts +30 -42
- package/extensions/capabilities/src/ui.ts +93 -0
- package/extensions/clear-context/index.ts +83 -0
- package/extensions/context-pivot/index.ts +16 -6
- package/extensions/cron/schedule.ts +7 -1
- package/extensions/file-mutation-display/index.ts +34 -76
- package/extensions/file-mutation-display/render.ts +146 -87
- package/extensions/file-search/index.ts +8 -7
- package/extensions/file-search/src/binaries.ts +75 -59
- package/extensions/git-info/src/changed-files-view.ts +47 -14
- package/extensions/git-read/index.ts +328 -0
- package/extensions/git-read/src/args.ts +171 -0
- package/extensions/git-read/src/process.ts +81 -0
- package/extensions/git-read/src/prompt.ts +56 -0
- package/extensions/model-info/index.ts +21 -33
- package/extensions/model-info/session-metrics.ts +96 -0
- package/extensions/plan-mode/bash-policy.ts +54 -9
- package/extensions/plan-mode/index.ts +7 -2
- package/extensions/post-edit/index.ts +16 -6
- package/extensions/sessions/git-stats.ts +258 -72
- package/extensions/sessions/index.ts +222 -140
- package/extensions/sessions/preview-cache.ts +104 -0
- package/extensions/sessions/preview-loader.ts +856 -0
- package/extensions/sessions/sessions.ts +43 -4
- package/extensions/setup/index.ts +127 -131
- package/extensions/shared/activity-status.ts +36 -5
- package/extensions/shared/agent-session-page.ts +319 -0
- package/extensions/shared/agent-tool-renderer.ts +218 -0
- package/extensions/shared/agent-transcript.ts +524 -0
- package/extensions/shared/below-editor-navigation.ts +26 -0
- package/extensions/shared/capability-intent.ts +53 -0
- package/extensions/shared/child-session.ts +444 -22
- package/extensions/shared/result-budget.ts +134 -0
- package/extensions/shared/result-delivery.ts +34 -0
- package/extensions/shared/screen-chrome.ts +133 -0
- package/extensions/shared/setup-config.ts +97 -38
- package/extensions/shared/setup-episode-state.ts +1 -1
- package/extensions/shared/spinner.ts +28 -0
- package/extensions/shared/terminal-text.ts +110 -23
- package/extensions/shared/text-projection.ts +113 -0
- package/extensions/shared/tool-activity.ts +382 -0
- package/extensions/shared/tool-surface.ts +42 -8
- package/extensions/shared/transcript-viewport.ts +46 -0
- package/extensions/shared/web-observer-registry.ts +390 -0
- package/extensions/shared/worktree.ts +11 -0
- package/extensions/subagents/index.ts +461 -186
- package/extensions/subagents/navigation.ts +86 -28
- package/extensions/subagents/src/agent-types.ts +37 -15
- package/extensions/subagents/src/backend.ts +12 -1
- package/extensions/subagents/src/backends/pi.ts +375 -66
- package/extensions/subagents/src/domain.ts +5 -0
- package/extensions/subagents/src/id-sequence.ts +84 -0
- package/extensions/subagents/src/manager.ts +651 -536
- package/extensions/subagents/src/prompt.ts +185 -42
- package/extensions/subagents/src/result-artifact.ts +146 -0
- package/extensions/subagents/src/result-delivery.ts +7 -1
- package/extensions/subagents/src/runtime.ts +23 -6
- package/extensions/subagents/src/ui/takeover.ts +128 -337
- package/extensions/subagents/src/ui/transcript.ts +38 -501
- package/extensions/subagents/src/ui/wait-result.ts +103 -15
- package/extensions/suggestions/src/ui.ts +10 -4
- package/extensions/tasks/index.ts +0 -3
- package/extensions/tasks/ui.ts +79 -62
- package/extensions/ui-customization/footer.ts +7 -44
- package/extensions/ui-customization/index.ts +0 -4
- package/extensions/user-input-fold/index.ts +185 -0
- package/extensions/web/index.ts +234 -0
- package/extensions/workflows/artifacts.ts +147 -22
- package/extensions/workflows/completion-projection.ts +457 -0
- package/extensions/workflows/controller.ts +14 -2
- package/extensions/workflows/coordinator.ts +62 -0
- package/extensions/workflows/dashboard.ts +458 -339
- package/extensions/workflows/handoff.ts +121 -25
- package/extensions/workflows/index.ts +1042 -492
- package/extensions/workflows/journal.ts +148 -13
- package/extensions/workflows/model.ts +131 -19
- package/extensions/workflows/navigation.ts +61 -18
- package/extensions/workflows/progress-projection.ts +306 -0
- package/extensions/workflows/prompt.ts +166 -10
- package/extensions/workflows/replay-safety.ts +58 -27
- package/extensions/workflows/result-delivery.ts +253 -0
- package/extensions/workflows/retention.ts +593 -0
- package/extensions/workflows/runner.ts +388 -279
- package/extensions/workflows/sandbox-child.cjs +36 -3
- package/extensions/workflows/sandbox.ts +62 -8
- package/extensions/workflows/serialization.ts +325 -17
- package/extensions/workflows/tool-renderer.ts +22 -0
- package/extensions/workflows/transcript.ts +149 -0
- package/extensions/workspace-cleanup-guard/index.ts +54 -0
- package/extensions/workspace-cleanup-guard/workspace-provenance.ts +563 -0
- package/package.json +28 -8
- package/skills/subagents/REFERENCE.md +189 -0
- package/skills/subagents/SKILL.md +2 -2
- package/skills/workflows/REFERENCE.md +10 -5
- package/skills/workflows/SKILL.md +53 -10
- package/web/adapter/pi-adapter.ts +661 -0
- package/web/host/browser-launcher.ts +20 -0
- package/web/host/static-assets.ts +4 -0
- package/web/host/terminal-status.ts +38 -0
- package/web/host/web-host.ts +789 -0
- package/web/http-dispatcher.ts +125 -0
- package/web/protocol/types.ts +462 -0
- package/web/runtime/pi-runtime.ts +991 -0
- package/web/runtime/types.ts +71 -0
- package/web/runtime/web-host-lease.ts +497 -0
- package/web/trace.ts +18 -0
- package/web/ui/app.js +1398 -0
- package/web/ui/index.html +139 -0
- package/web/ui/styles.css +598 -0
- package/web/vite.config.mjs +34 -0
- package/extensions/execution-convergence/active-evidence.ts +0 -129
- package/extensions/execution-convergence/index.ts +0 -442
- package/extensions/execution-convergence/workspace-provenance.ts +0 -338
- package/extensions/setup/intercom-fs-helper.cjs +0 -130
- package/extensions/setup/intercom.ts +0 -603
- package/extensions/subagents/src/backends/stub.ts +0 -296
- package/extensions/subagents/src/format.ts +0 -48
|
@@ -2,21 +2,28 @@ import type { Theme } from "@earendil-works/pi-coding-agent";
|
|
|
2
2
|
import type { TUI } from "@earendil-works/pi-tui";
|
|
3
3
|
import {
|
|
4
4
|
fitNavigationSides,
|
|
5
|
+
renderNavigationMetrics,
|
|
5
6
|
type BelowEditorStripState,
|
|
6
7
|
} from "../shared/below-editor-navigation.ts";
|
|
7
8
|
import {
|
|
8
9
|
unreadActivityCounts,
|
|
9
10
|
type ActivityCounts,
|
|
10
11
|
} from "../shared/activity-status.ts";
|
|
12
|
+
import { spinnerFrame } from "../shared/spinner.ts";
|
|
11
13
|
import { sanitizeTerminalText } from "../shared/terminal-text.ts";
|
|
12
14
|
import { formatElapsed, type SubagentSnapshot } from "./src/domain.ts";
|
|
13
|
-
import {
|
|
15
|
+
import { contextPercent } from "../shared/context-utilization.ts";
|
|
14
16
|
|
|
15
17
|
export interface SubagentStripEntry {
|
|
16
18
|
snapshot: SubagentSnapshot;
|
|
17
19
|
counts: ActivityCounts;
|
|
18
20
|
}
|
|
19
21
|
|
|
22
|
+
/** Changes only when the strip needs an immediate lifecycle repaint. */
|
|
23
|
+
export function subagentStripEntryKey(entry: SubagentStripEntry | undefined) {
|
|
24
|
+
return entry ? `${entry.snapshot.id}:${entry.snapshot.status}` : undefined;
|
|
25
|
+
}
|
|
26
|
+
|
|
20
27
|
function cleanLine(value: string) {
|
|
21
28
|
return sanitizeTerminalText(value).replace(/\s+/g, " ").trim();
|
|
22
29
|
}
|
|
@@ -58,13 +65,22 @@ function statusColor(status: SubagentSnapshot["status"]) {
|
|
|
58
65
|
return "error" as const;
|
|
59
66
|
}
|
|
60
67
|
|
|
61
|
-
|
|
62
|
-
|
|
68
|
+
/**
|
|
69
|
+
* One status indicator per run state; doubles as the focus marker when
|
|
70
|
+
* selected. Running spins, in step with the dashboard and takeover headers.
|
|
71
|
+
*/
|
|
72
|
+
function statusGlyph(snapshot: SubagentSnapshot, theme: Theme, now: number) {
|
|
73
|
+
if (snapshot.status === "running")
|
|
74
|
+
return theme.fg("warning", spinnerFrame(now));
|
|
75
|
+
if (snapshot.status === "done") return theme.fg("success", "✓");
|
|
76
|
+
return theme.fg("error", "✗");
|
|
63
77
|
}
|
|
64
78
|
|
|
79
|
+
const SUBAGENT_STRIP_INTERVAL_MS = 500;
|
|
80
|
+
|
|
65
81
|
/** One-line subagent manager entry with the same affordance as Workflow. */
|
|
66
82
|
export class SubagentStripWidget {
|
|
67
|
-
private
|
|
83
|
+
private timer: ReturnType<typeof setInterval> | undefined;
|
|
68
84
|
private readonly tui: TUI;
|
|
69
85
|
private readonly theme: Theme;
|
|
70
86
|
private readonly strip: BelowEditorStripState;
|
|
@@ -80,42 +96,84 @@ export class SubagentStripWidget {
|
|
|
80
96
|
this.theme = theme;
|
|
81
97
|
this.strip = strip;
|
|
82
98
|
this.getEntry = getEntry;
|
|
83
|
-
this.
|
|
84
|
-
this.timer.unref?.();
|
|
99
|
+
this.syncSpinner();
|
|
85
100
|
}
|
|
86
101
|
|
|
87
102
|
dispose() {
|
|
88
|
-
clearInterval(this.timer);
|
|
103
|
+
if (this.timer) clearInterval(this.timer);
|
|
104
|
+
this.timer = undefined;
|
|
89
105
|
}
|
|
90
106
|
|
|
91
|
-
invalidate() {
|
|
107
|
+
invalidate() {
|
|
108
|
+
this.syncSpinner();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
private syncSpinner() {
|
|
112
|
+
if (this.getEntry()?.snapshot.status === "running") {
|
|
113
|
+
if (this.timer) return;
|
|
114
|
+
const timer = setInterval(() => {
|
|
115
|
+
if (this.timer !== timer) return;
|
|
116
|
+
if (this.getEntry()?.snapshot.status !== "running") {
|
|
117
|
+
clearInterval(timer);
|
|
118
|
+
this.timer = undefined;
|
|
119
|
+
}
|
|
120
|
+
this.tui.requestRender();
|
|
121
|
+
}, SUBAGENT_STRIP_INTERVAL_MS);
|
|
122
|
+
this.timer = timer;
|
|
123
|
+
timer.unref?.();
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (this.timer) clearInterval(this.timer);
|
|
127
|
+
this.timer = undefined;
|
|
128
|
+
}
|
|
92
129
|
|
|
93
130
|
render(width: number) {
|
|
131
|
+
this.syncSpinner();
|
|
94
132
|
const entry = this.getEntry();
|
|
95
133
|
if (!entry || width <= 0) return [];
|
|
96
134
|
const { snapshot, counts } = entry;
|
|
97
|
-
const
|
|
135
|
+
const glyph = this.strip.focused
|
|
98
136
|
? this.theme.fg("accent", "❯")
|
|
99
|
-
: this.theme.
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const
|
|
105
|
-
?
|
|
106
|
-
:
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
137
|
+
: statusGlyph(snapshot, this.theme, Date.now());
|
|
138
|
+
// A name only means something when it names the only active subagent; with
|
|
139
|
+
// several, an aggregate label is honest and the counts carry the detail.
|
|
140
|
+
const total = counts.running + counts.done + counts.failed;
|
|
141
|
+
const single = total === 1;
|
|
142
|
+
const labelText = single
|
|
143
|
+
? normalizeSubagentTitle(snapshot.title, snapshot.id)
|
|
144
|
+
: "subagents";
|
|
145
|
+
const label = this.strip.focused
|
|
146
|
+
? this.theme.bold(this.theme.fg("accent", labelText))
|
|
147
|
+
: this.theme.fg("text", labelText);
|
|
148
|
+
// The footer already shows the session model; the takeover view keeps the
|
|
149
|
+
// per-subagent model, so the one-line strip stays title-only.
|
|
150
|
+
const left = ` ${glyph} ${label}`;
|
|
151
|
+
// Worded counts read at a glance; the selected run's own state comes
|
|
152
|
+
// first so the emphasis colour always lands on the matching count. A lone
|
|
153
|
+
// subagent needs no count — the glyph and label already say it.
|
|
154
|
+
const donePart = counts.done > 0 ? `${counts.done} done` : undefined;
|
|
155
|
+
const failedPart =
|
|
156
|
+
counts.failed > 0 ? `${counts.failed} failed` : undefined;
|
|
157
|
+
const activity = single
|
|
158
|
+
? []
|
|
159
|
+
: counts.running > 0
|
|
160
|
+
? [`${counts.running} running`]
|
|
161
|
+
: snapshot.status === "error"
|
|
162
|
+
? [failedPart, donePart]
|
|
163
|
+
: [donePart, failedPart];
|
|
164
|
+
const percent = contextPercent(snapshot.usage);
|
|
165
|
+
const right = renderNavigationMetrics(
|
|
166
|
+
this.theme,
|
|
167
|
+
[
|
|
168
|
+
...activity,
|
|
169
|
+
formatElapsed(snapshot),
|
|
170
|
+
percent === undefined ? undefined : `${percent}% ctx`,
|
|
171
|
+
],
|
|
114
172
|
this.strip.focused ? "enter open · ↑ back" : "↓ to manage",
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
173
|
+
single || snapshot.status === "running"
|
|
174
|
+
? undefined
|
|
175
|
+
: statusColor(snapshot.status),
|
|
176
|
+
);
|
|
119
177
|
return [fitNavigationSides(left, right, width)];
|
|
120
178
|
}
|
|
121
179
|
}
|
|
@@ -24,18 +24,18 @@ import * as fs from "node:fs";
|
|
|
24
24
|
import * as path from "node:path";
|
|
25
25
|
import type { Model } from "@earendil-works/pi-ai";
|
|
26
26
|
import {
|
|
27
|
-
parseFrontmatter,
|
|
28
27
|
type ModelRegistry,
|
|
28
|
+
parseFrontmatter,
|
|
29
29
|
} from "@earendil-works/pi-coding-agent";
|
|
30
30
|
import {
|
|
31
31
|
CHILD_EXCLUDED_TOOL_NAMES,
|
|
32
32
|
CHILD_SAFE_PACKAGE_TOOL_NAMES,
|
|
33
33
|
} from "../../shared/child-session.ts";
|
|
34
|
-
import { sanitizeTerminalText } from "../../shared/terminal-text.ts";
|
|
35
34
|
import {
|
|
36
35
|
isSubagentRoleName,
|
|
37
36
|
type SubagentRoleModel,
|
|
38
37
|
} from "../../shared/subagent-roles.ts";
|
|
38
|
+
import { sanitizeTerminalText } from "../../shared/terminal-text.ts";
|
|
39
39
|
import { REASONING_EFFORTS, type ReasoningEffort } from "./domain.ts";
|
|
40
40
|
|
|
41
41
|
/** Directory name scanned under both the agent dir and a project's `.pi`. */
|
|
@@ -101,7 +101,17 @@ export interface AgentType {
|
|
|
101
101
|
readonly source: string;
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
const
|
|
104
|
+
export const READ_ONLY_AGENT_TOOLS = [
|
|
105
|
+
"read",
|
|
106
|
+
"grep",
|
|
107
|
+
"find",
|
|
108
|
+
"ls",
|
|
109
|
+
"fd",
|
|
110
|
+
"rg",
|
|
111
|
+
"git_show",
|
|
112
|
+
"git_diff",
|
|
113
|
+
"git_log",
|
|
114
|
+
];
|
|
105
115
|
|
|
106
116
|
/**
|
|
107
117
|
* Built-in role definitions are deliberately provider-free: model selection is
|
|
@@ -112,33 +122,45 @@ export const BUILT_IN_AGENT_TYPES: readonly AgentType[] = [
|
|
|
112
122
|
{
|
|
113
123
|
name: "explorer",
|
|
114
124
|
description:
|
|
115
|
-
"Read-only codebase exploration.
|
|
116
|
-
tools:
|
|
117
|
-
reasoningEffort: "high",
|
|
125
|
+
"Read-only codebase exploration. Usually use moderate reasoning, increasing it for harder tasks.",
|
|
126
|
+
tools: READ_ONLY_AGENT_TOOLS,
|
|
118
127
|
body: "Explore the codebase read-only. Trace the real flow, inspect related callers, and report concise evidence with file paths and line references.",
|
|
119
128
|
source: "built-in:explorer",
|
|
120
129
|
},
|
|
121
130
|
{
|
|
122
131
|
name: "implementer",
|
|
123
|
-
description:
|
|
124
|
-
|
|
125
|
-
|
|
132
|
+
description:
|
|
133
|
+
"Focused implementation with repository checks. Usually use medium-high reasoning, adjusted for scope, risk, and task difficulty.",
|
|
134
|
+
tools: [
|
|
135
|
+
"read",
|
|
136
|
+
"bash",
|
|
137
|
+
"edit",
|
|
138
|
+
"write",
|
|
139
|
+
"grep",
|
|
140
|
+
"find",
|
|
141
|
+
"ls",
|
|
142
|
+
"fd",
|
|
143
|
+
"rg",
|
|
144
|
+
"git_show",
|
|
145
|
+
"git_diff",
|
|
146
|
+
"git_log",
|
|
147
|
+
],
|
|
126
148
|
body: "Implement the requested change carefully. Trace the affected flow first, make the smallest correct edit, and run relevant checks before reporting results.",
|
|
127
149
|
source: "built-in:implementer",
|
|
128
150
|
},
|
|
129
151
|
{
|
|
130
152
|
name: "reviewer",
|
|
131
|
-
description:
|
|
132
|
-
|
|
133
|
-
|
|
153
|
+
description:
|
|
154
|
+
"Read-only review for correctness, safety, and regressions. Usually use high reasoning, adjusted for task difficulty.",
|
|
155
|
+
tools: READ_ONLY_AGENT_TOOLS,
|
|
134
156
|
body: "Review the requested code or change read-only. Identify concrete correctness, security, and regression risks with evidence; do not modify files.",
|
|
135
157
|
source: "built-in:reviewer",
|
|
136
158
|
},
|
|
137
159
|
{
|
|
138
160
|
name: "advisor",
|
|
139
|
-
description:
|
|
140
|
-
|
|
141
|
-
|
|
161
|
+
description:
|
|
162
|
+
"Deep read-only analysis and technical advice. Usually use high reasoning, adjusted for task difficulty.",
|
|
163
|
+
tools: READ_ONLY_AGENT_TOOLS,
|
|
142
164
|
body: "Analyze the problem deeply without modifying files. Explain the relevant tradeoffs, risks, and recommended next step using repository evidence.",
|
|
143
165
|
source: "built-in:advisor",
|
|
144
166
|
},
|
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
* on it rather than on the pi session directly.
|
|
6
6
|
*
|
|
7
7
|
* - pi (./backends/pi.ts): in-process `createAgentSession()` via the pi SDK.
|
|
8
|
-
* - stub (./backends/stub.ts): scripted sessions, test-only.
|
|
9
8
|
*/
|
|
10
9
|
|
|
11
10
|
import type { Effect, Scope, Stream } from "effect";
|
|
12
11
|
import { Context } from "effect";
|
|
12
|
+
import type { AgentToolRenderer } from "../../shared/agent-tool-renderer.ts";
|
|
13
13
|
import type {
|
|
14
14
|
BackendName,
|
|
15
15
|
SendError,
|
|
@@ -19,6 +19,13 @@ import type {
|
|
|
19
19
|
SubagentMeta,
|
|
20
20
|
} from "./domain.ts";
|
|
21
21
|
|
|
22
|
+
export interface SubagentCleanupReceipt {
|
|
23
|
+
/** True when the session/worktree state could not be proven quiescent. */
|
|
24
|
+
readonly uncertain: boolean;
|
|
25
|
+
/** Bounded operator-facing explanation of the cleanup result. */
|
|
26
|
+
readonly message: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
22
29
|
/**
|
|
23
30
|
* A live subagent session. The manager is the single consumer of `events`;
|
|
24
31
|
* it folds them into the `SubagentSnapshot` everything else reads.
|
|
@@ -42,6 +49,10 @@ export interface SubagentSession {
|
|
|
42
49
|
* this with a timeout and fall back to closing the session scope.
|
|
43
50
|
*/
|
|
44
51
|
readonly interrupt: Effect.Effect<void>;
|
|
52
|
+
/** Ephemeral Pi-native tool projection for the operator-facing child page. */
|
|
53
|
+
readonly toolRenderer?: AgentToolRenderer;
|
|
54
|
+
/** Cleanup receipt populated when scope teardown cannot prove safety. */
|
|
55
|
+
readonly cleanupReceipt?: () => SubagentCleanupReceipt | undefined;
|
|
45
56
|
}
|
|
46
57
|
|
|
47
58
|
export interface SubagentBackend {
|