@oh-my-pi/pi-coding-agent 13.0.2 → 13.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/package.json +7 -7
- package/src/patch/index.ts +9 -9
- package/src/patch/shared.ts +2 -3
- package/src/prompts/system/system-prompt.md +8 -8
- package/src/prompts/tools/ask.md +3 -18
- package/src/prompts/tools/{poll-jobs.md → await.md} +1 -1
- package/src/prompts/tools/bash.md +3 -2
- package/src/prompts/tools/browser.md +11 -18
- package/src/prompts/tools/fetch.md +2 -5
- package/src/prompts/tools/find.md +1 -1
- package/src/prompts/tools/grep.md +1 -4
- package/src/prompts/tools/hashline.md +19 -18
- package/src/prompts/tools/lsp.md +6 -16
- package/src/prompts/tools/read.md +3 -6
- package/src/prompts/tools/task.md +93 -275
- package/src/prompts/tools/web-search.md +0 -7
- package/src/prompts/tools/write.md +0 -5
- package/src/sdk.ts +12 -2
- package/src/system-prompt.ts +5 -0
- package/src/tools/{poll-jobs.ts → await-tool.ts} +19 -19
- package/src/tools/bash-skill-urls.ts +28 -3
- package/src/tools/bash.ts +5 -1
- package/src/tools/browser.ts +18 -4
- package/src/tools/index.ts +3 -3
- package/src/tools/notebook.ts +1 -1
|
@@ -1,317 +1,135 @@
|
|
|
1
1
|
# Task
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Launches subagents to parallelize workflows.
|
|
4
|
+
|
|
4
5
|
{{#if asyncEnabled}}
|
|
5
|
-
Use `read jobs://` to inspect
|
|
6
|
-
|
|
6
|
+
- Use `read jobs://` to inspect state; `read jobs://<job_id>` for detail.
|
|
7
|
+
- Use the `await` tool to wait until completion. You MUST NOT poll `read jobs://` in a loop.
|
|
7
8
|
{{/if}}
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
Subagents receive the **full system prompt**, including AGENTS.md, context files, and skills. You MUST NOT repeat project rules, coding conventions, or style guidelines in `context` — they already have them.
|
|
11
|
-
|
|
12
|
-
## What subagents do NOT have
|
|
13
|
-
Subagents have no access to your conversation history. They don't know:
|
|
14
|
-
- Decisions you made but didn't write down
|
|
15
|
-
- Which approach you chose among alternatives
|
|
16
|
-
- What you learned from reading files during this session
|
|
17
|
-
- Requirements the user stated only in conversation
|
|
18
|
-
|
|
19
|
-
Subagents CAN grep the parent conversation file for supplementary details.
|
|
20
|
-
|
|
21
|
-
For large intermediate outputs (long traces, JSON payloads, temporary analysis snapshots), you SHOULD write them to `local://<path>` and pass the path in task context instead of inlining bulky text.
|
|
22
|
-
|
|
23
|
-
## Parameters
|
|
24
|
-
|
|
25
|
-
### `agent` (required)
|
|
10
|
+
Subagents lack your conversation history. Every decision, file content, and user requirement they need MUST be explicit in `context` or `assignment`.
|
|
26
11
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
12
|
+
<parameters>
|
|
13
|
+
- `agent`: Agent type for all tasks.
|
|
14
|
+
- `.id`: CamelCase, max 32 chars
|
|
15
|
+
- `.description`: UI display only — subagent never sees it
|
|
16
|
+
- `.assignment`: Complete self-contained instructions. One-liners PROHIBITED; missing acceptance criteria = too vague.
|
|
17
|
+
- `.skills`: Skill names to preload
|
|
18
|
+
- `context`: Shared background prepended to every assignment. Session-specific info only.
|
|
19
|
+
- `schema`: JTD schema for expected output. Format lives here — MUST NOT be duplicated in assignments.
|
|
20
|
+
- `tasks`: Tasks to execute in parallel.
|
|
21
|
+
- `isolated`: Run in isolated git worktree; returns patches. Use when tasks edit overlapping files.
|
|
22
|
+
</parameters>
|
|
32
23
|
|
|
33
24
|
<critical>
|
|
34
|
-
|
|
25
|
+
- MUST NOT include AGENTS.md rules, coding conventions, or style guidelines — subagents already have them.
|
|
26
|
+
- MUST NOT duplicate shared constraints across assignments — put them in `context` once.
|
|
27
|
+
- MUST NOT tell tasks to run project-wide build/test/lint. Parallel agents share the working tree; each task edits, stops. Caller verifies after all complete.
|
|
28
|
+
- For large payloads (traces, JSON blobs), write to `local://<path>` and pass the path in context.
|
|
29
|
+
- If scope is unclear, run a **Discovery task** first to enumerate files and callsites, then fan out.
|
|
35
30
|
</critical>
|
|
36
|
-
**Before writing each line of context, ask:** "Would this sentence be true for ANY task in this repo, or only for THIS specific batch?" If it applies to any task → it's a project rule → the subagent already has it → you MUST delete the line.
|
|
37
31
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
- Use X import style, not Y (per AGENTS.md)
|
|
42
|
-
- Use Z for private fields per AGENTS.md
|
|
43
|
-
- Run the formatter after changes
|
|
44
|
-
- Follow the logging convention
|
|
45
|
-
```
|
|
46
|
-
Every line above restates a project convention. The subagent reads AGENTS.md. You MUST delete them all.
|
|
32
|
+
<scope>
|
|
33
|
+
Each task: **at most 3–5 files**. Globs in file paths, "update all", or package-wide scope = too broad. Enumerate files explicitly and fan out to a cluster of agents.
|
|
34
|
+
</scope>
|
|
47
35
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
## Constraints
|
|
51
|
-
- We decided to use approach A over B (session decision)
|
|
52
|
-
- The migration target type is `Foo` from `bar` package (looked up this session)
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
Use template; omit non-applicable sections:
|
|
56
|
-
|
|
57
|
-
````
|
|
58
|
-
## Goal
|
|
59
|
-
One sentence: batch accomplishes together.
|
|
60
|
-
|
|
61
|
-
## Non-goals
|
|
62
|
-
Explicitly exclude tempting scope — what tasks must not touch/attempt.
|
|
63
|
-
|
|
64
|
-
## Constraints
|
|
65
|
-
- Task-specific MUST / MUST NOT rules not already in AGENTS.md
|
|
66
|
-
- Decisions made during this session that affect implementation
|
|
67
|
-
|
|
68
|
-
## Reference Files
|
|
69
|
-
- `path/to/file.ext` — pattern demo
|
|
70
|
-
- `path/to/other.ext` — reuse or avoid
|
|
71
|
-
|
|
72
|
-
## API Contract (if tasks produce/consume shared interface)
|
|
73
|
-
```language
|
|
74
|
-
// Exact type definitions, function signatures, interface shapes
|
|
75
|
-
```
|
|
36
|
+
<parallelization>
|
|
37
|
+
**Test:** Can task B produce correct output without seeing A's result? Yes → parallel. No → sequential.
|
|
76
38
|
|
|
77
|
-
|
|
78
|
-
- Definition of "done" for batch
|
|
79
|
-
- Note: build/test/lint verification happens AFTER all tasks complete — not inside tasks (see below)
|
|
80
|
-
````
|
|
81
|
-
**Belongs in `context`**: task-specific goal, non-goals, session decisions, reference paths, shared type definitions, API contracts, global acceptance commands — anything 2+ tasks need that isn't already in AGENTS.md.
|
|
82
|
-
**Rule of thumb:** if repeat in 2+ tasks, belongs in `context`.
|
|
83
|
-
**Does NOT belong in `context`**: project rules already in AGENTS.md/context files, per-task file lists, one-off requirements (go in `assignment`), structured output format (goes in `schema`).
|
|
84
|
-
|
|
85
|
-
### `tasks` (required)
|
|
86
|
-
|
|
87
|
-
Array tasks execute in parallel.
|
|
88
|
-
|
|
89
|
-
|Field|Required|Purpose|
|
|
39
|
+
|Sequential first|Then|Reason|
|
|
90
40
|
|---|---|---|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
{{/if}}
|
|
101
|
-
### `schema` (optional — recommended for structured output)
|
|
102
|
-
|
|
103
|
-
JTD schema defining expected response structure. Use typed properties. If you care about parsing result, define here — you MUST NOT describe output format in `context` or `assignment`.
|
|
104
|
-
|
|
105
|
-
<caution>
|
|
106
|
-
**Schema vs agent mismatch causes null output.** Agents with `output="structured"` (e.g., `explore`) have a built-in schema. If you also pass `schema`, yours takes precedence — but if you describe output format in `context`/`assignment` instead, the agent's built-in schema wins. The agent gets confused trying to fit your requested format into its schema shape and submits `null`. Either: (1) use `schema` to override the built-in one, (2) use `task` agent which has no built-in schema, or (3) match your instructions to the agent's expected output shape.
|
|
107
|
-
</caution>
|
|
108
|
-
---
|
|
109
|
-
|
|
110
|
-
## Writing an assignment
|
|
111
|
-
|
|
112
|
-
<critical>## Task scope
|
|
113
|
-
|
|
114
|
-
`assignment` MUST contain enough info for agent to act **without asking a clarifying question**.
|
|
115
|
-
**Minimum bar:** assignment under ~8 lines or missing acceptance criteria = too vague. One-liners guaranteed failure.
|
|
116
|
-
|
|
117
|
-
Use structure every assignment:
|
|
118
|
-
|
|
41
|
+
|Types/interfaces|Consumers|Need contract|
|
|
42
|
+
|API exports|Callers|Need signatures|
|
|
43
|
+
|Core module|Dependents|Import dependency|
|
|
44
|
+
|Schema/migration|App logic|Schema dependency|
|
|
45
|
+
**Safe to parallelize:** independent modules, isolated file-scoped refactors, tests for existing code.
|
|
46
|
+
</parallelization>
|
|
47
|
+
|
|
48
|
+
<templates>
|
|
49
|
+
**context:**
|
|
119
50
|
```
|
|
120
|
-
##
|
|
121
|
-
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
## Change
|
|
126
|
-
- Step-by-step: add/remove/rename/restructure
|
|
127
|
-
- Patterns/APIs to use; reference files if applicable
|
|
128
|
-
|
|
129
|
-
## Edge Cases / Don't Break
|
|
130
|
-
- Tricky case 1: …
|
|
131
|
-
- Tricky case 2: …
|
|
132
|
-
- Existing behavior must survive: …
|
|
133
|
-
|
|
134
|
-
## Acceptance (task-local)
|
|
135
|
-
- Expected behavior or observable result
|
|
136
|
-
- DO NOT include project-wide build/test/lint commands (see below)
|
|
51
|
+
## Goal ← one sentence: what the batch accomplishes
|
|
52
|
+
## Non-goals ← what tasks must not touch
|
|
53
|
+
## Constraints ← MUST/MUST NOT rules beyond AGENTS.md; session decisions
|
|
54
|
+
## API Contract ← exact types/signatures if tasks share an interface (omit if N/A)
|
|
55
|
+
## Acceptance ← definition of done; build/lint runs AFTER all tasks complete
|
|
137
56
|
```
|
|
138
|
-
|
|
139
|
-
`context` carries shared background. `assignment` carries only delta: file-specific instructions, local edge cases, per-task acceptance checks. You MUST NOT duplicate shared constraints across assignments.
|
|
140
|
-
|
|
141
|
-
### Anti-patterns (ban these)
|
|
142
|
-
**Vague assignments** — agent guesses wrong or stalls:
|
|
143
|
-
- "Refactor this to be cleaner."
|
|
144
|
-
- "Migrate to N-API."
|
|
145
|
-
- "Fix the bug in streaming."
|
|
146
|
-
- "Update all constructors in `src/**/*.ts`."
|
|
147
|
-
**Vague context** — forces agent invent conventions:
|
|
148
|
-
- "Use existing patterns."
|
|
149
|
-
- "Follow conventions."
|
|
150
|
-
- "No WASM."
|
|
151
|
-
**Redundant context** — wastes tokens repeating what subagents already have:
|
|
152
|
-
- Restating AGENTS.md rules (coding style, import conventions, formatting commands, logger usage, etc.)
|
|
153
|
-
- Repeating project constraints from context files
|
|
154
|
-
- Listing tool/framework preferences already documented in the repo
|
|
155
|
-
|
|
156
|
-
If a constraint appears in AGENTS.md, it MUST NOT appear in `context`. The subagent has the full system prompt.
|
|
157
|
-
|
|
158
|
-
If tempted to write above, expand using templates.
|
|
159
|
-
**Output format in prose instead of `schema`** — agent returns null:
|
|
160
|
-
Structured agents (`explore`, `reviewer`) have built-in output schemas. Describing a different output format in `context`/`assignment` without overriding via `schema` creates a mismatch — the agent can't reconcile your prose instructions with its schema and submits null data. You MUST use `schema` for output structure, or pick an agent whose built-in schema matches your needs.
|
|
161
|
-
**Test/lint commands in parallel tasks** — edit wars:
|
|
162
|
-
Parallel agents share working tree. If two agents run `bun check` or `bun test` concurrently, they see each other's half-finished edits, "fix" phantom errors, loop. You MUST NOT tell parallel tasks to run project-wide build/test/lint commands. Each task edits, stops. Caller verifies after all tasks complete.
|
|
163
|
-
**If you can't specify scope yet**, create **Discovery task** first: enumerate files, find callsites, list candidates. Then fan out with explicit paths.
|
|
164
|
-
|
|
165
|
-
### Delegate intent, not keystrokes
|
|
166
|
-
|
|
167
|
-
Your role as tech lead: set direction, define boundaries, call out pitfalls — then get out of way. Don’t read every file, decide every edit, dictate line-by-line. That makes you bottleneck; agent typist.
|
|
168
|
-
**Be specific about:** constraints, naming conventions, API contracts, "don’t break" items, acceptance criteria.
|
|
169
|
-
**Delegate:** code reading, approach selection, exact edit locations, implementation details. Agent has tools, can reason about code.
|
|
170
|
-
|
|
171
|
-
Micromanaging (you think, agent types):
|
|
172
|
-
```
|
|
173
|
-
assignment: "In src/api/handler.ts, line 47, change `throw err` to `throw new ApiError(err.message, 500)`.
|
|
174
|
-
On line 63, wrap fetch call try/catch return 502 on failure.
|
|
175
|
-
On line 89, add null check before accessing resp.body…"
|
|
57
|
+
**assignment:**
|
|
176
58
|
```
|
|
177
|
-
|
|
178
|
-
|
|
59
|
+
## Target ← exact file paths; named symbols; explicit non-goals
|
|
60
|
+
## Change ← step-by-step what to add/remove/rename; patterns/APIs to use
|
|
61
|
+
## Edge Cases ← tricky inputs; existing behavior that must survive
|
|
62
|
+
## Acceptance ← observable result proving the task is done; no project-wide commands
|
|
179
63
|
```
|
|
180
|
-
|
|
181
|
-
with typed ApiError instances, add try/catch around external calls, guard against null responses.\n\n
|
|
182
|
-
## Edge Cases / Don't Break\n- Existing error codes in tests must still match\n
|
|
183
|
-
- Don't change public function signatures"
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
First style wastes your time, brittle if code shifts. Second gives agent room to do work.
|
|
187
|
-
</critical>
|
|
64
|
+
</templates>
|
|
188
65
|
|
|
189
|
-
|
|
66
|
+
<checklist>
|
|
67
|
+
Before invoking:
|
|
68
|
+
- `context` contains only session-specific info not in AGENTS.md
|
|
69
|
+
- Every `assignment` follows the template; no one-liners; edge cases covered
|
|
70
|
+
- Tasks are truly parallel — you can articulate why none depends on another's output
|
|
71
|
+
- File paths are explicit; no globs
|
|
72
|
+
- `schema` is set if you expect structured output
|
|
73
|
+
</checklist>
|
|
190
74
|
|
|
191
|
-
<example
|
|
192
|
-
|
|
193
|
-
<task name="Grep">
|
|
194
|
-
<description>Port grep module from WASM to N-API…</description>
|
|
195
|
-
<assignment>Port grep module from WASM to N-API… (same blob repeated)</assignment>
|
|
196
|
-
</task>
|
|
197
|
-
</tasks>
|
|
198
|
-
</example>
|
|
75
|
+
<example label="Rename exported symbol + update all call sites">
|
|
76
|
+
Two tasks with non-overlapping file sets. Neither depends on the other's edits.
|
|
199
77
|
|
|
200
|
-
<example type="good" label="Shared rules in context, only deltas in assignment">
|
|
201
78
|
<context>
|
|
202
79
|
## Goal
|
|
203
|
-
|
|
204
|
-
|
|
80
|
+
Rename `parseConfig` → `loadConfig` in `src/config/parser.ts` and all callers.
|
|
205
81
|
## Non-goals
|
|
206
|
-
Do not
|
|
207
|
-
|
|
208
|
-
## Constraints
|
|
209
|
-
- MUST use `#[napi]` attribute macro on all exports
|
|
210
|
-
- MUST return `napi::Result<T>` for fallible ops; never panic
|
|
211
|
-
- MUST use `spawn_blocking` for filesystem I/O or >1ms work
|
|
212
|
-
…
|
|
213
|
-
|
|
82
|
+
Do not change function behavior, signature, or tests — rename only.
|
|
214
83
|
## Acceptance (global)
|
|
215
|
-
|
|
216
|
-
- Individual tasks must NOT run these commands themselves
|
|
84
|
+
Caller runs `bun check:ts` after both tasks complete. Tasks must NOT run it.
|
|
217
85
|
</context>
|
|
218
|
-
|
|
219
86
|
<tasks>
|
|
220
|
-
<task name="
|
|
221
|
-
<description>
|
|
87
|
+
<task name="RenameExport">
|
|
88
|
+
<description>Rename the export in parser.ts</description>
|
|
222
89
|
<assignment>
|
|
223
90
|
## Target
|
|
224
|
-
-
|
|
225
|
-
-
|
|
91
|
+
- File: `src/config/parser.ts`
|
|
92
|
+
- Symbol: exported function `parseConfig`
|
|
93
|
+
- Non-goals: do not touch callers or tests
|
|
226
94
|
|
|
227
95
|
## Change
|
|
228
|
-
-
|
|
229
|
-
|
|
230
|
-
|
|
96
|
+
- Rename `parseConfig` → `loadConfig` (declaration + any JSDoc referencing it)
|
|
97
|
+
- If `src/config/index.ts` re-exports `parseConfig`, update that re-export too
|
|
98
|
+
|
|
99
|
+
## Edge Cases
|
|
100
|
+
- If the function is overloaded, rename all overload signatures
|
|
101
|
+
- Internal helpers named `_parseConfigValue` or similar: leave untouched — different symbols
|
|
102
|
+
- Do not add a backwards-compat alias
|
|
231
103
|
|
|
232
|
-
## Acceptance
|
|
233
|
-
-
|
|
104
|
+
## Acceptance
|
|
105
|
+
- `src/config/parser.ts` exports `loadConfig`; `parseConfig` no longer appears as a top-level export in that file
|
|
234
106
|
</assignment>
|
|
235
107
|
</task>
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
<description>Port highlight module to N-API</description>
|
|
108
|
+
<task name="UpdateCallers">
|
|
109
|
+
<description>Update import and call sites in consuming modules</description>
|
|
239
110
|
<assignment>
|
|
240
111
|
## Target
|
|
241
|
-
- Files: `src/
|
|
242
|
-
|
|
112
|
+
- Files: `src/cli/init.ts`, `src/server/bootstrap.ts`, `src/worker/index.ts`
|
|
113
|
+
- Non-goals: do not touch `src/config/parser.ts` or `src/config/index.ts` — handled by sibling task
|
|
114
|
+
|
|
115
|
+
## Change
|
|
116
|
+
- In each file: replace `import { parseConfig }` → `import { loadConfig }` from its config path
|
|
117
|
+
- Replace every call site `parseConfig(` → `loadConfig(`
|
|
118
|
+
|
|
119
|
+
## Edge Cases
|
|
120
|
+
- If a file spreads the import (`import * as cfg from "…"`) and calls `cfg.parseConfig(…)`, update the property access too
|
|
121
|
+
- String literals containing "parseConfig" (log messages, comments) are documentation — leave them
|
|
122
|
+
- If any file re-exports `parseConfig` to an external package boundary, keep the old name via `export { loadConfig as parseConfig }` and add a `// TODO: remove after next major` comment
|
|
123
|
+
|
|
124
|
+
## Acceptance
|
|
125
|
+
- No bare reference to `parseConfig` (as identifier, not string) remains in the three target files
|
|
243
126
|
</assignment>
|
|
244
127
|
</task>
|
|
245
128
|
</tasks>
|
|
246
129
|
</example>
|
|
247
|
-
---
|
|
248
|
-
|
|
249
|
-
## Task scope
|
|
250
|
-
|
|
251
|
-
Each task MUST have small, well-defined scope — **at most 3–5 files**.
|
|
252
|
-
**Signs task too broad:**
|
|
253
|
-
- File paths use globs (`src/**/*.ts`) instead of explicit names
|
|
254
|
-
- Assignment says "update all" / "migrate everything" / "refactor across"
|
|
255
|
-
- Scope covers entire package or directory tree
|
|
256
|
-
**Fix:** You MUST enumerate files first (grep/glob discovery), then fan out one task per file or small cluster.
|
|
257
|
-
---
|
|
258
|
-
|
|
259
|
-
## Parallelization
|
|
260
|
-
**Test:** Can task B produce correct output without seeing task A's result?
|
|
261
|
-
- **Yes** → parallelize
|
|
262
|
-
- **No** → run sequentially (A completes, then launch B with A output in context)
|
|
263
|
-
|
|
264
|
-
### Must be sequential
|
|
265
|
-
|
|
266
|
-
|First|Then|Reason|
|
|
267
|
-
|---|---|---|
|
|
268
|
-
|Define types/interfaces|Implement consumers|Consumers need contract|
|
|
269
|
-
|Create API exports|Write bindings/callers|Callers need export names/signatures|
|
|
270
|
-
|Scaffold structure|Implement bodies|Bodies need shape|
|
|
271
|
-
|Core module|Dependent modules|Dependents import from core|
|
|
272
|
-
|Schema/DB migration|Application logic|Logic depends on new schema shape|
|
|
273
|
-
|
|
274
|
-
### Safe to parallelize
|
|
275
|
-
- Independent modules, no cross-imports
|
|
276
|
-
- Tests for already-implemented code
|
|
277
|
-
- Isolated file-scoped refactors
|
|
278
|
-
- Documentation for stable APIs
|
|
279
|
-
|
|
280
|
-
### Phased execution
|
|
281
|
-
|
|
282
|
-
<caution>
|
|
283
|
-
**Parallel agents share the working tree.** They see each other's half-finished edits in real time. This is why:
|
|
284
|
-
- Parallel tasks MUST NOT run project-wide build/test/lint — they will collide on phantom errors
|
|
285
|
-
- Tasks editing overlapping files MUST use `isolated: true` (worktree isolation) or be made sequential
|
|
286
|
-
- The caller MUST run verification after all tasks complete, not inside any individual task
|
|
287
|
-
</caution>
|
|
288
|
-
|
|
289
|
-
Layered work with dependencies:
|
|
290
|
-
**Phase 1 — Foundation** (caller MUST do this, MUST NOT delegate): define interfaces, create scaffolds, establish API shape. You MUST NOT fan out until contract is known.
|
|
291
|
-
**Phase 2 — Parallel implementation**: fan out tasks consuming same known interface. Include Phase 1 API contract in `context`.
|
|
292
|
-
**Phase 3 — Integration** (caller MUST do this, MUST NOT delegate): wire modules, fix mismatches, verify builds.
|
|
293
|
-
**Phase 4 — Dependent layer**: fan out tasks consuming Phase 2 outputs.
|
|
294
|
-
---
|
|
295
|
-
|
|
296
|
-
## Pre-flight checklist
|
|
297
|
-
|
|
298
|
-
<critical>
|
|
299
|
-
Before calling tool, verify each item:
|
|
300
|
-
- [ ] `context` MUST include only session-specific info not already in AGENTS.md/context files
|
|
301
|
-
- [ ] Each `assignment` MUST follow the assignment template — one-liners are PROHIBITED
|
|
302
|
-
- [ ] Each `assignment` MUST include edge cases / "don't break" items
|
|
303
|
-
- [ ] Tasks MUST be truly parallel — you MUST be able to articulate why no task depends on another's output
|
|
304
|
-
- [ ] Scope MUST be small; file paths MUST be explicit (no globs)
|
|
305
|
-
- [ ] Tasks MUST NOT run project-wide build/test/lint — caller MUST verify after all tasks complete
|
|
306
|
-
- [ ] `schema` MUST be used if you expect structured output
|
|
307
|
-
</critical>
|
|
308
|
-
---
|
|
309
|
-
|
|
310
|
-
## Agents
|
|
311
130
|
|
|
312
131
|
{{#list agents join="\n"}}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
</agent>
|
|
132
|
+
### Agent: {{name}}
|
|
133
|
+
**Tools:** {{default (join tools ", ") "All"}}
|
|
134
|
+
{{description}}
|
|
317
135
|
{{/list}}
|
|
@@ -7,13 +7,6 @@ Search the web for up-to-date information beyond Claude's knowledge cutoff.
|
|
|
7
7
|
- You MUST include links for cited sources in the final response
|
|
8
8
|
</instruction>
|
|
9
9
|
|
|
10
|
-
<output>
|
|
11
|
-
Returns search results formatted as blocks with:
|
|
12
|
-
- Result summaries and relevant excerpts
|
|
13
|
-
- Links as markdown hyperlinks for citation
|
|
14
|
-
- Provider-dependent structure based on selected backend
|
|
15
|
-
</output>
|
|
16
|
-
|
|
17
10
|
<caution>
|
|
18
11
|
Searches are performed automatically within a single API call—no pagination or follow-up requests needed.
|
|
19
12
|
</caution>
|
|
@@ -5,13 +5,8 @@ Creates or overwrites file at specified path.
|
|
|
5
5
|
<conditions>
|
|
6
6
|
- Creating new files explicitly required by task
|
|
7
7
|
- Replacing entire file contents when editing would be more complex
|
|
8
|
-
- Prefer `local://<path>` for large temporary artifacts, subagent handoff payloads, and reusable planning artifacts that should survive within the session
|
|
9
8
|
</conditions>
|
|
10
9
|
|
|
11
|
-
<output>
|
|
12
|
-
Confirmation of file creation/write with path. When LSP available, content may be auto-formatted before writing and diagnostics returned. Returns error if write fails (permissions, invalid path, disk full).
|
|
13
|
-
</output>
|
|
14
|
-
|
|
15
10
|
<critical>
|
|
16
11
|
- You SHOULD use Edit tool for modifying existing files (more precise, preserves formatting)
|
|
17
12
|
- You MUST NOT create documentation files (*.md, README) unless explicitly requested
|
package/src/sdk.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
Agent,
|
|
3
|
+
type AgentEvent,
|
|
4
|
+
type AgentMessage,
|
|
5
|
+
type AgentTool,
|
|
6
|
+
INTENT_FIELD,
|
|
7
|
+
type ThinkingLevel,
|
|
8
|
+
} from "@oh-my-pi/pi-agent-core";
|
|
2
9
|
import { type Message, type Model, supportsXhigh } from "@oh-my-pi/pi-ai";
|
|
3
10
|
import { prewarmOpenAICodexResponses } from "@oh-my-pi/pi-ai/providers/openai-codex-responses";
|
|
4
11
|
import type { Component } from "@oh-my-pi/pi-tui";
|
|
@@ -1114,6 +1121,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1114
1121
|
});
|
|
1115
1122
|
|
|
1116
1123
|
const repeatToolDescriptions = settings.get("repeatToolDescriptions");
|
|
1124
|
+
const intentField = settings.get("tools.intentTracing") || $env.PI_INTENT_TRACING === "1" ? INTENT_FIELD : undefined;
|
|
1117
1125
|
const rebuildSystemPrompt = async (toolNames: string[], tools: Map<string, AgentTool>): Promise<string> => {
|
|
1118
1126
|
toolContextStore.setToolNames(toolNames);
|
|
1119
1127
|
const memoryInstructions = await buildMemoryToolDeveloperInstructions(agentDir, settings);
|
|
@@ -1128,6 +1136,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1128
1136
|
skillsSettings: settings.getGroup("skills") as SkillsSettings,
|
|
1129
1137
|
appendSystemPrompt: memoryInstructions,
|
|
1130
1138
|
repeatToolDescriptions,
|
|
1139
|
+
intentField,
|
|
1131
1140
|
});
|
|
1132
1141
|
|
|
1133
1142
|
if (options.systemPrompt === undefined) {
|
|
@@ -1146,6 +1155,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1146
1155
|
customPrompt: options.systemPrompt,
|
|
1147
1156
|
appendSystemPrompt: memoryInstructions,
|
|
1148
1157
|
repeatToolDescriptions,
|
|
1158
|
+
intentField,
|
|
1149
1159
|
});
|
|
1150
1160
|
}
|
|
1151
1161
|
return options.systemPrompt(defaultPrompt);
|
|
@@ -1283,7 +1293,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1283
1293
|
},
|
|
1284
1294
|
cursorExecHandlers,
|
|
1285
1295
|
transformToolCallArguments: obfuscator?.hasSecrets() ? args => obfuscator!.deobfuscateObject(args) : undefined,
|
|
1286
|
-
intentTracing:
|
|
1296
|
+
intentTracing: !!intentField,
|
|
1287
1297
|
});
|
|
1288
1298
|
cursorEventEmitter = event => agent.emitExternalEvent(event);
|
|
1289
1299
|
|
package/src/system-prompt.ts
CHANGED
|
@@ -419,6 +419,8 @@ export interface BuildSystemPromptOptions {
|
|
|
419
419
|
preloadedSkills?: Skill[];
|
|
420
420
|
/** Pre-loaded rulebook rules (rules with descriptions, excluding TTSR and always-apply). */
|
|
421
421
|
rules?: Array<{ name: string; description?: string; path: string; globs?: string[] }>;
|
|
422
|
+
/** Intent field name injected into every tool schema. If set, explains the field in the prompt. */
|
|
423
|
+
intentField?: string;
|
|
422
424
|
}
|
|
423
425
|
|
|
424
426
|
/** Build the system prompt with tools, guidelines, and context */
|
|
@@ -439,6 +441,7 @@ export async function buildSystemPrompt(options: BuildSystemPromptOptions = {}):
|
|
|
439
441
|
skills: providedSkills,
|
|
440
442
|
preloadedSkills: providedPreloadedSkills,
|
|
441
443
|
rules,
|
|
444
|
+
intentField,
|
|
442
445
|
} = options;
|
|
443
446
|
const resolvedCwd = cwd ?? getProjectDir();
|
|
444
447
|
const preloadedSkills = providedPreloadedSkills;
|
|
@@ -609,5 +612,7 @@ export async function buildSystemPrompt(options: BuildSystemPromptOptions = {}):
|
|
|
609
612
|
dateTime,
|
|
610
613
|
cwd: resolvedCwd,
|
|
611
614
|
appendSystemPrompt: resolvedAppendPrompt ?? "",
|
|
615
|
+
intentTracing: !!intentField,
|
|
616
|
+
intentField: intentField ?? "",
|
|
612
617
|
});
|
|
613
618
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
|
|
2
2
|
import { type Static, Type } from "@sinclair/typebox";
|
|
3
3
|
import { renderPromptTemplate } from "../config/prompt-templates";
|
|
4
|
-
import
|
|
4
|
+
import awaitDescription from "../prompts/tools/await.md" with { type: "text" };
|
|
5
5
|
import type { ToolSession } from "./index";
|
|
6
6
|
|
|
7
|
-
const
|
|
7
|
+
const awaitSchema = Type.Object({
|
|
8
8
|
job_ids: Type.Optional(
|
|
9
9
|
Type.Array(Type.String(), {
|
|
10
10
|
description: "Specific job IDs to wait for. If omitted, waits for any running job.",
|
|
@@ -17,9 +17,9 @@ const pollJobsSchema = Type.Object({
|
|
|
17
17
|
),
|
|
18
18
|
});
|
|
19
19
|
|
|
20
|
-
type
|
|
20
|
+
type AwaitParams = Static<typeof awaitSchema>;
|
|
21
21
|
|
|
22
|
-
interface
|
|
22
|
+
interface AwaitResult {
|
|
23
23
|
id: string;
|
|
24
24
|
type: "bash" | "task";
|
|
25
25
|
status: "running" | "completed" | "failed" | "cancelled";
|
|
@@ -29,34 +29,34 @@ interface PollJobResult {
|
|
|
29
29
|
errorText?: string;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
export interface
|
|
33
|
-
jobs:
|
|
32
|
+
export interface AwaitToolDetails {
|
|
33
|
+
jobs: AwaitResult[];
|
|
34
34
|
timedOut: boolean;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
export class
|
|
38
|
-
readonly name = "
|
|
39
|
-
readonly label = "
|
|
37
|
+
export class AwaitTool implements AgentTool<typeof awaitSchema, AwaitToolDetails> {
|
|
38
|
+
readonly name = "await";
|
|
39
|
+
readonly label = "Await";
|
|
40
40
|
readonly description: string;
|
|
41
|
-
readonly parameters =
|
|
41
|
+
readonly parameters = awaitSchema;
|
|
42
42
|
readonly strict = true;
|
|
43
43
|
|
|
44
44
|
constructor(private readonly session: ToolSession) {
|
|
45
|
-
this.description = renderPromptTemplate(
|
|
45
|
+
this.description = renderPromptTemplate(awaitDescription);
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
static createIf(session: ToolSession):
|
|
48
|
+
static createIf(session: ToolSession): AwaitTool | null {
|
|
49
49
|
if (!session.settings.get("async.enabled")) return null;
|
|
50
|
-
return new
|
|
50
|
+
return new AwaitTool(session);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
async execute(
|
|
54
54
|
_toolCallId: string,
|
|
55
|
-
params:
|
|
55
|
+
params: AwaitParams,
|
|
56
56
|
signal?: AbortSignal,
|
|
57
|
-
_onUpdate?: AgentToolUpdateCallback<
|
|
57
|
+
_onUpdate?: AgentToolUpdateCallback<AwaitToolDetails>,
|
|
58
58
|
_context?: AgentToolContext,
|
|
59
|
-
): Promise<AgentToolResult<
|
|
59
|
+
): Promise<AgentToolResult<AwaitToolDetails>> {
|
|
60
60
|
const manager = this.session.asyncJobManager;
|
|
61
61
|
if (!manager) {
|
|
62
62
|
return {
|
|
@@ -129,12 +129,12 @@ export class PollJobsTool implements AgentTool<typeof pollJobsSchema, PollJobsTo
|
|
|
129
129
|
errorText?: string;
|
|
130
130
|
}[],
|
|
131
131
|
timedOut: boolean,
|
|
132
|
-
): AgentToolResult<
|
|
132
|
+
): AgentToolResult<AwaitToolDetails> {
|
|
133
133
|
const now = Date.now();
|
|
134
|
-
const jobResults:
|
|
134
|
+
const jobResults: AwaitResult[] = jobs.map(j => ({
|
|
135
135
|
id: j.id,
|
|
136
136
|
type: j.type,
|
|
137
|
-
status: j.status as
|
|
137
|
+
status: j.status as AwaitResult["status"],
|
|
138
138
|
label: j.label,
|
|
139
139
|
durationMs: Math.max(0, now - j.startTime),
|
|
140
140
|
...(j.resultText ? { resultText: j.resultText } : {}),
|