@tt-a1i/openpi 0.3.1 → 0.4.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 +87 -24
- package/SETUP.md +3 -3
- package/extensions/ask-user/index.ts +30 -14
- package/extensions/background-terminals/src/prompt.ts +1 -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/file-mutation-display/index.ts +34 -76
- package/extensions/file-mutation-display/render.ts +387 -88
- package/extensions/file-search/index.ts +8 -7
- package/extensions/file-search/src/binaries.ts +18 -18
- package/extensions/git-info/src/changed-files-view.ts +47 -14
- package/extensions/git-read/index.ts +330 -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/sessions/index.ts +70 -55
- package/extensions/setup/index.ts +6 -6
- package/extensions/shared/activity-status.ts +6 -5
- package/extensions/shared/below-editor-navigation.ts +26 -0
- package/extensions/shared/capability-intent.ts +53 -0
- package/extensions/shared/child-session.ts +7 -1
- package/extensions/shared/result-budget.ts +134 -0
- package/extensions/shared/screen-chrome.ts +133 -0
- package/extensions/shared/setup-config.ts +24 -5
- package/extensions/shared/spinner.ts +28 -0
- package/extensions/shared/text-projection.ts +56 -0
- package/extensions/shared/tool-surface.ts +13 -6
- package/extensions/subagents/index.ts +204 -140
- package/extensions/subagents/navigation.ts +52 -23
- package/extensions/subagents/src/agent-types.ts +37 -15
- package/extensions/subagents/src/backends/stub.ts +7 -0
- package/extensions/subagents/src/id-sequence.ts +84 -0
- package/extensions/subagents/src/manager.ts +620 -537
- package/extensions/subagents/src/prompt.ts +153 -38
- package/extensions/subagents/src/result-artifact.ts +142 -0
- package/extensions/subagents/src/runtime.ts +8 -5
- package/extensions/subagents/src/ui/takeover.ts +84 -109
- package/extensions/subagents/src/ui/transcript.ts +76 -42
- package/extensions/subagents/src/ui/wait-result.ts +1 -1
- package/extensions/tasks/ui.ts +79 -62
- package/extensions/ui-customization/footer.ts +7 -4
- package/extensions/user-input-fold/index.ts +185 -0
- package/extensions/workflows/artifacts.ts +35 -0
- package/extensions/workflows/controller.ts +14 -2
- package/extensions/workflows/coordinator.ts +64 -0
- package/extensions/workflows/dashboard.ts +353 -173
- package/extensions/workflows/handoff.ts +62 -20
- package/extensions/workflows/index.ts +647 -387
- package/extensions/workflows/model.ts +57 -15
- package/extensions/workflows/navigation.ts +33 -14
- package/extensions/workflows/prompt.ts +104 -8
- package/extensions/workflows/replay-safety.ts +16 -6
- package/extensions/workflows/result-delivery.ts +189 -0
- package/extensions/workflows/sandbox-child.cjs +11 -0
- package/package.json +1 -1
- package/skills/subagents/SKILL.md +2 -2
- package/skills/workflows/REFERENCE.md +7 -4
- package/skills/workflows/SKILL.md +53 -10
- package/extensions/subagents/src/format.ts +0 -48
|
@@ -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
|
},
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
* - supports interrupt (RunSettled Interrupted -> status "error", matching v1);
|
|
11
11
|
* - fails the run when the prompt starts with "FAIL:", and refuses to spawn
|
|
12
12
|
* at all when it starts with "SPAWNFAIL:" (error-path testing);
|
|
13
|
+
* - hangs the run after RunStarted without any assistant event when the
|
|
14
|
+
* prompt starts with "HANG:" (first-response watchdog testing);
|
|
13
15
|
* - appends every event to a JSONL "session file" in tmpdir so the
|
|
14
16
|
* "full transcript in session file" pointers resolve.
|
|
15
17
|
*/
|
|
@@ -114,6 +116,11 @@ const makeStubSession = (
|
|
|
114
116
|
Effect.gen(function* () {
|
|
115
117
|
yield* emit({ _tag: "RunStarted" });
|
|
116
118
|
const failing = userText.trimStart().startsWith("FAIL:");
|
|
119
|
+
// Stand in for a provider that accepts the request but never emits
|
|
120
|
+
// its first assistant event.
|
|
121
|
+
if (userText.trimStart().startsWith("HANG:")) {
|
|
122
|
+
return yield* Effect.never;
|
|
123
|
+
}
|
|
117
124
|
|
|
118
125
|
const thinking = "Looking at the task and planning an approach...";
|
|
119
126
|
for (const delta of chunked(thinking, 16)) {
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { SessionEntry } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
|
|
3
|
+
export const SUBAGENT_ID_WATERMARK_ENTRY_TYPE = "subagent-id-watermark";
|
|
4
|
+
|
|
5
|
+
export interface SubagentIdCounters {
|
|
6
|
+
readonly modelCounter: number;
|
|
7
|
+
readonly btwCounter: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface IdWatermarkData {
|
|
11
|
+
readonly version: 1;
|
|
12
|
+
readonly id: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function record(value: unknown): Record<string, unknown> | undefined {
|
|
16
|
+
return typeof value === "object" && value !== null
|
|
17
|
+
? (value as Record<string, unknown>)
|
|
18
|
+
: undefined;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function idFrom(value: unknown) {
|
|
22
|
+
const candidate = record(value)?.id;
|
|
23
|
+
return typeof candidate === "string" ? candidate : undefined;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function idFromEntry(entry: SessionEntry) {
|
|
27
|
+
if (entry.type === "custom") {
|
|
28
|
+
const data = record(entry.data);
|
|
29
|
+
if (
|
|
30
|
+
entry.customType === SUBAGENT_ID_WATERMARK_ENTRY_TYPE &&
|
|
31
|
+
data?.version === 1
|
|
32
|
+
) {
|
|
33
|
+
return idFrom(data);
|
|
34
|
+
}
|
|
35
|
+
if (
|
|
36
|
+
entry.customType === "subagent-finished" ||
|
|
37
|
+
entry.customType === "btw-result"
|
|
38
|
+
) {
|
|
39
|
+
return idFrom(data);
|
|
40
|
+
}
|
|
41
|
+
if (entry.customType === "subagent-result") {
|
|
42
|
+
return idFrom(data?.details) ?? idFrom(data);
|
|
43
|
+
}
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (entry.type === "custom_message") {
|
|
48
|
+
return entry.customType === "subagent-result"
|
|
49
|
+
? idFrom(entry.details)
|
|
50
|
+
: undefined;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (entry.type !== "message") return undefined;
|
|
54
|
+
const message = record(entry.message);
|
|
55
|
+
return message?.role === "toolResult" && message.toolName === "subagent_spawn"
|
|
56
|
+
? idFrom(message.details)
|
|
57
|
+
: undefined;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function sequence(id: string | undefined, prefix: "sa" | "btw") {
|
|
61
|
+
if (!id) return undefined;
|
|
62
|
+
const match = new RegExp(`^${prefix}-(\\d+)$`, "u").exec(id);
|
|
63
|
+
if (!match) return undefined;
|
|
64
|
+
const value = Number(match[1]);
|
|
65
|
+
return Number.isSafeInteger(value) && value > 0 ? value : undefined;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Restore branch-local id high-water marks, including sessions from before watermarks existed. */
|
|
69
|
+
export function restoreSubagentIdCounters(
|
|
70
|
+
entries: readonly SessionEntry[],
|
|
71
|
+
): SubagentIdCounters {
|
|
72
|
+
let modelCounter = 0;
|
|
73
|
+
let btwCounter = 0;
|
|
74
|
+
for (const entry of entries) {
|
|
75
|
+
const id = idFromEntry(entry);
|
|
76
|
+
modelCounter = Math.max(modelCounter, sequence(id, "sa") ?? 0);
|
|
77
|
+
btwCounter = Math.max(btwCounter, sequence(id, "btw") ?? 0);
|
|
78
|
+
}
|
|
79
|
+
return { modelCounter, btwCounter };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function subagentIdWatermark(id: string): IdWatermarkData {
|
|
83
|
+
return { version: 1, id };
|
|
84
|
+
}
|