@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.
@@ -1,317 +1,135 @@
1
1
  # Task
2
2
 
3
- Launch subagents to execute parallel, well-scoped tasks.
3
+ Launches subagents to parallelize workflows.
4
+
4
5
  {{#if asyncEnabled}}
5
- Use `read jobs://` to inspect background task state and `read jobs://<job-id>` for detailed status/output when needed.
6
- When you need to wait for async results before continuing, call `poll_jobs` it blocks until jobs complete. You MUST NOT poll `read jobs://` in a loop or yield and hope for delivery.
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
- ## What subagents inherit automatically
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
- Agent type for all tasks in this batch.
28
-
29
- ### `context` (optional strongly recommended)
30
-
31
- Shared background prepended verbatim to every task `assignment`. Use only for session-specific information subagents lack.
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
- You MUST NOT include project rules, coding conventions, or style guidelines — subagents already have AGENTS.md and context files in their system prompt. Repeating them wastes tokens and inflates context. Restating any rule from AGENTS.md in `context` is a bug — treat it like a lint error.
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
- WRONG — restating project rules the subagent already has:
39
- ```
40
- ## Constraints
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
- RIGHT — only session-specific decisions the subagent cannot infer from project files:
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
- ## Acceptance (global)
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
- |`id`|✓|CamelCase identifier, max 32 chars|
92
- |`description`|✓|Short one-liner for UI display only — not seen by subagent|
93
- |`assignment`|✓|Complete per-task instructions. See [Writing an assignment](#writing-an-assignment).|
94
- |`skills`||Skill names preload. Use only when changes correctness — don’t spam every task.|
95
-
96
- {{#if isolationEnabled}}
97
- ### `isolated` (optional)
98
-
99
- Run in isolated git worktree; returns patches. Use when tasks edit overlapping files or when you want clean per-task diffs.
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
- ## Target
121
- - Files: exact path(s)
122
- - Symbols/entrypoints: specific functions, types, exports
123
- - Non-goals: what task must NOT touch (prevents scope creep)
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
- Delegating (agent thinks within constraints):
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
- assignment: "## Target\n- Files: src/api/handler.ts\n\n## Change\nImprove error handling: replace raw throws
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
- ## Example
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 type="bad" label="Duplicated context inflates tokens">
192
- <tasks>
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
- Port WASM modules to N-API, matching existing pi-natives conventions.
204
-
80
+ Rename `parseConfig` `loadConfig` in `src/config/parser.ts` and all callers.
205
81
  ## Non-goals
206
- Do not touch TS bindings or downstream consumers separate phase.
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 testsrename only.
214
83
  ## Acceptance (global)
215
- - Caller verifies after all tasks: `cargo test -p pi-natives` and `cargo build -p pi-natives` with no warnings
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="PortGrep">
221
- <description>Port grep module to N-API</description>
87
+ <task name="RenameExport">
88
+ <description>Rename the export in parser.ts</description>
222
89
  <assignment>
223
90
  ## Target
224
- - Files: `src/grep.rs`, `src/lib.rs` (registration only)
225
- - Symbols: search, search_multi, compile_pattern
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
- - Implement three N-API exports in grep.rs:
229
- - `search(pattern: JsString, path: JsString, env: Env) → napi::Result<Vec<Match>>`
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 (task-local)
233
- - Three functions exported with correct signatures (caller verifies build after all tasks)
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
- <task name="PortHighlight">
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/highlight.rs`, `src/lib.rs` (registration only)
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
- <agent name="{{name}}"{{#if output}} output="structured"{{/if}}>
314
- <description>{{description}}</description>
315
- <tools>{{default (join tools ", ") "All tools"}}</tools>
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 { Agent, type AgentEvent, type AgentMessage, type AgentTool, type ThinkingLevel } from "@oh-my-pi/pi-agent-core";
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: settings.get("tools.intentTracing") || $env.PI_INTENT_TRACING === "1",
1296
+ intentTracing: !!intentField,
1287
1297
  });
1288
1298
  cursorEventEmitter = event => agent.emitExternalEvent(event);
1289
1299
 
@@ -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 pollJobsDescription from "../prompts/tools/poll-jobs.md" with { type: "text" };
4
+ import awaitDescription from "../prompts/tools/await.md" with { type: "text" };
5
5
  import type { ToolSession } from "./index";
6
6
 
7
- const pollJobsSchema = Type.Object({
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 PollJobsParams = Static<typeof pollJobsSchema>;
20
+ type AwaitParams = Static<typeof awaitSchema>;
21
21
 
22
- interface PollJobResult {
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 PollJobsToolDetails {
33
- jobs: PollJobResult[];
32
+ export interface AwaitToolDetails {
33
+ jobs: AwaitResult[];
34
34
  timedOut: boolean;
35
35
  }
36
36
 
37
- export class PollJobsTool implements AgentTool<typeof pollJobsSchema, PollJobsToolDetails> {
38
- readonly name = "poll_jobs";
39
- readonly label = "PollJobs";
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 = pollJobsSchema;
41
+ readonly parameters = awaitSchema;
42
42
  readonly strict = true;
43
43
 
44
44
  constructor(private readonly session: ToolSession) {
45
- this.description = renderPromptTemplate(pollJobsDescription);
45
+ this.description = renderPromptTemplate(awaitDescription);
46
46
  }
47
47
 
48
- static createIf(session: ToolSession): PollJobsTool | null {
48
+ static createIf(session: ToolSession): AwaitTool | null {
49
49
  if (!session.settings.get("async.enabled")) return null;
50
- return new PollJobsTool(session);
50
+ return new AwaitTool(session);
51
51
  }
52
52
 
53
53
  async execute(
54
54
  _toolCallId: string,
55
- params: PollJobsParams,
55
+ params: AwaitParams,
56
56
  signal?: AbortSignal,
57
- _onUpdate?: AgentToolUpdateCallback<PollJobsToolDetails>,
57
+ _onUpdate?: AgentToolUpdateCallback<AwaitToolDetails>,
58
58
  _context?: AgentToolContext,
59
- ): Promise<AgentToolResult<PollJobsToolDetails>> {
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<PollJobsToolDetails> {
132
+ ): AgentToolResult<AwaitToolDetails> {
133
133
  const now = Date.now();
134
- const jobResults: PollJobResult[] = jobs.map(j => ({
134
+ const jobResults: AwaitResult[] = jobs.map(j => ({
135
135
  id: j.id,
136
136
  type: j.type,
137
- status: j.status as PollJobResult["status"],
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 } : {}),