@oh-my-pi/pi-coding-agent 15.13.1 → 15.13.3
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 +47 -0
- package/dist/cli.js +1057 -289
- package/dist/types/config/model-registry.d.ts +1 -0
- package/dist/types/config/models-config-schema.d.ts +3 -0
- package/dist/types/config/models-config.d.ts +3 -0
- package/dist/types/config/settings-schema.d.ts +97 -0
- package/dist/types/edit/hashline/block-resolver.d.ts +1 -1
- package/dist/types/edit/index.d.ts +2 -0
- package/dist/types/eval/js/context-manager.d.ts +15 -0
- package/dist/types/modes/components/welcome.d.ts +1 -0
- package/dist/types/modes/controllers/input-controller.d.ts +4 -4
- package/dist/types/modes/interactive-mode.d.ts +1 -0
- package/dist/types/modes/rpc/rpc-types.d.ts +2 -1
- package/dist/types/modes/types.d.ts +6 -0
- package/dist/types/sdk.d.ts +3 -0
- package/dist/types/session/session-dump-format.d.ts +2 -1
- package/dist/types/session/unexpected-stop-classifier.d.ts +13 -0
- package/dist/types/stt/asr-client.d.ts +1 -1
- package/dist/types/system-prompt.d.ts +11 -0
- package/dist/types/tiny/title-client.d.ts +1 -1
- package/dist/types/tools/ask.d.ts +2 -0
- package/dist/types/tools/ast-edit.d.ts +2 -0
- package/dist/types/tools/ast-grep.d.ts +2 -0
- package/dist/types/tools/browser.d.ts +2 -0
- package/dist/types/tools/debug.d.ts +2 -0
- package/dist/types/tools/eval.d.ts +2 -0
- package/dist/types/tools/find.d.ts +2 -0
- package/dist/types/tools/inspect-image.d.ts +2 -1
- package/dist/types/tools/irc.d.ts +2 -0
- package/dist/types/tools/job.d.ts +1 -0
- package/dist/types/tools/ssh.d.ts +2 -0
- package/dist/types/tools/todo.d.ts +2 -0
- package/dist/types/tts/tts-client.d.ts +1 -1
- package/dist/types/tui/tree-list.d.ts +1 -0
- package/dist/types/utils/thinking-display.d.ts +1 -17
- package/package.json +12 -12
- package/src/cli.ts +25 -12
- package/src/config/model-registry.ts +16 -2
- package/src/config/models-config-schema.ts +2 -0
- package/src/config/models-config.ts +1 -0
- package/src/config/settings-schema.ts +78 -0
- package/src/edit/hashline/block-resolver.ts +1 -1
- package/src/edit/hashline/execute.ts +1 -6
- package/src/edit/index.ts +48 -0
- package/src/eval/__tests__/agent-bridge.test.ts +106 -46
- package/src/eval/__tests__/js-context-manager.test.ts +53 -3
- package/src/eval/js/context-manager.ts +132 -29
- package/src/eval/js/worker-core.ts +1 -1
- package/src/eval/js/worker-entry.ts +7 -0
- package/src/export/html/template.js +18 -22
- package/src/internal-urls/docs-index.generated.ts +12 -3
- package/src/main.ts +15 -5
- package/src/modes/acp/acp-agent.ts +2 -2
- package/src/modes/acp/acp-event-mapper.ts +2 -2
- package/src/modes/components/agent-hub.ts +31 -7
- package/src/modes/components/assistant-message.ts +24 -15
- package/src/modes/components/snapcompact-shape-preview-doc.md +2 -2
- package/src/modes/components/snapcompact-shape-preview.ts +2 -2
- package/src/modes/components/tree-selector.ts +3 -2
- package/src/modes/components/welcome.ts +14 -4
- package/src/modes/controllers/event-controller.ts +3 -3
- package/src/modes/controllers/input-controller.ts +28 -39
- package/src/modes/controllers/streaming-reveal.ts +4 -4
- package/src/modes/interactive-mode.ts +2 -0
- package/src/modes/rpc/rpc-mode.ts +1 -0
- package/src/modes/rpc/rpc-types.ts +2 -2
- package/src/modes/types.ts +6 -0
- package/src/modes/utils/ui-helpers.ts +3 -3
- package/src/prompts/agents/oracle.md +0 -1
- package/src/prompts/agents/reviewer.md +0 -1
- package/src/prompts/system/system-prompt.md +17 -21
- package/src/prompts/system/unexpected-stop-classifier.md +17 -0
- package/src/prompts/system/unexpected-stop-retry.md +4 -0
- package/src/prompts/tools/ask.md +0 -8
- package/src/prompts/tools/ast-edit.md +0 -15
- package/src/prompts/tools/ast-grep.md +0 -13
- package/src/prompts/tools/browser.md +0 -21
- package/src/prompts/tools/debug.md +0 -13
- package/src/prompts/tools/eval.md +0 -9
- package/src/prompts/tools/find.md +0 -13
- package/src/prompts/tools/inspect-image.md +0 -9
- package/src/prompts/tools/irc.md +0 -15
- package/src/prompts/tools/patch.md +0 -13
- package/src/prompts/tools/ssh.md +0 -9
- package/src/prompts/tools/todo.md +1 -19
- package/src/sdk.ts +19 -0
- package/src/session/agent-session.ts +289 -29
- package/src/session/session-dump-format.ts +17 -49
- package/src/session/unexpected-stop-classifier.ts +129 -0
- package/src/stt/asr-client.ts +1 -1
- package/src/system-prompt.ts +31 -0
- package/src/tiny/title-client.ts +1 -1
- package/src/tools/ask.ts +41 -0
- package/src/tools/ast-edit.ts +46 -0
- package/src/tools/ast-grep.ts +24 -0
- package/src/tools/browser/tab-supervisor.ts +1 -1
- package/src/tools/browser/tab-worker-entry.ts +12 -4
- package/src/tools/browser.ts +52 -0
- package/src/tools/debug.ts +17 -0
- package/src/tools/eval.ts +20 -1
- package/src/tools/find.ts +24 -0
- package/src/tools/inspect-image.ts +27 -1
- package/src/tools/irc.ts +41 -0
- package/src/tools/job.ts +1 -0
- package/src/tools/ssh.ts +16 -0
- package/src/tools/todo.ts +82 -3
- package/src/tts/tts-client.ts +1 -1
- package/src/tui/tree-list.ts +68 -19
- package/src/utils/thinking-display.ts +8 -34
|
@@ -24,27 +24,6 @@ Use tools whenever they materially improve correctness, completeness, or groundi
|
|
|
24
24
|
- SHOULD parallelize calls when possible.
|
|
25
25
|
{{#has tools "task"}}- User says `parallel`/`parallelize` → MUST use `{{toolRefs.task}}` subagents; parallel tool calls alone do not satisfy.{{/has}}
|
|
26
26
|
|
|
27
|
-
{{#if toolInfo.length}}
|
|
28
|
-
# Inventory
|
|
29
|
-
{{#if mcpDiscoveryMode}}
|
|
30
|
-
<discovery-notice>
|
|
31
|
-
{{#if hasMCPDiscoveryServers}}Discoverable MCP servers in this session: {{#list mcpDiscoveryServerSummaries join=", "}}{{this}}{{/list}}.{{/if}}
|
|
32
|
-
If the task may involve external systems, SaaS APIs, chat, tickets, databases, deployments, or other non-local integrations, you SHOULD call `{{toolRefs.search_tool_bm25}}` before concluding no such tool exists.
|
|
33
|
-
</discovery-notice>
|
|
34
|
-
{{/if}}
|
|
35
|
-
{{#if repeatToolDescriptions}}
|
|
36
|
-
{{#each toolInfo}}
|
|
37
|
-
<tool name={{name}}>
|
|
38
|
-
{{description}}
|
|
39
|
-
</tool>
|
|
40
|
-
{{/each}}
|
|
41
|
-
{{else}}
|
|
42
|
-
{{#each toolInfo}}
|
|
43
|
-
- {{#if label}}{{label}}: `{{name}}`{{else}}`{{name}}`{{/if}}
|
|
44
|
-
{{/each}}
|
|
45
|
-
{{/if}}
|
|
46
|
-
{{/if}}
|
|
47
|
-
|
|
48
27
|
# I/O
|
|
49
28
|
- For tools taking `path` or path-like fields, prefer relative paths.
|
|
50
29
|
{{#if intentTracing}}- Most tools have a `{{intentField}}` parameter. Fill it with a concise intent in present participle form, 2-6 words, no period, capitalized.{{/if}}
|
|
@@ -115,6 +94,23 @@ Delegation is preferred here. Once the design is settled, you SHOULD fan substan
|
|
|
115
94
|
{{/has}}
|
|
116
95
|
{{/if}}
|
|
117
96
|
|
|
97
|
+
{{#if toolInfo.length}}
|
|
98
|
+
# Inventory
|
|
99
|
+
{{#if mcpDiscoveryMode}}
|
|
100
|
+
<discovery-notice>
|
|
101
|
+
{{#if hasMCPDiscoveryServers}}Discoverable MCP servers in this session: {{#list mcpDiscoveryServerSummaries join=", "}}{{this}}{{/list}}.{{/if}}
|
|
102
|
+
If the task may involve external systems, SaaS APIs, chat, tickets, databases, deployments, or other non-local integrations, you SHOULD call `{{toolRefs.search_tool_bm25}}` before concluding no such tool exists.
|
|
103
|
+
</discovery-notice>
|
|
104
|
+
{{/if}}
|
|
105
|
+
{{#if toolListMode}}
|
|
106
|
+
{{#each toolInfo}}
|
|
107
|
+
- {{#if label}}{{label}}: `{{name}}`{{else}}`{{name}}`{{/if}}
|
|
108
|
+
{{/each}}
|
|
109
|
+
{{else}}
|
|
110
|
+
{{toolInventory}}
|
|
111
|
+
{{/if}}
|
|
112
|
+
{{/if}}
|
|
113
|
+
|
|
118
114
|
ENV
|
|
119
115
|
===================================
|
|
120
116
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
You are checking whether an assistant message is an unexpected stop. A message is an unexpected stop if the assistant says it will take an action, continue working, or call a tool, but then ends without actually doing so.
|
|
2
|
+
|
|
3
|
+
Examples of unexpected stops:
|
|
4
|
+
- "I should do the same for the JS eval worker. Doing that now."
|
|
5
|
+
- "Let me run the tests next."
|
|
6
|
+
- "I'll fix that now."
|
|
7
|
+
- "Should I do that for you?"
|
|
8
|
+
|
|
9
|
+
Not an unexpected stop:
|
|
10
|
+
- "I've completed the task."
|
|
11
|
+
- "Is there anything else I can help with?"
|
|
12
|
+
- "The fix is done and tests pass."
|
|
13
|
+
|
|
14
|
+
Message:
|
|
15
|
+
{{message}}
|
|
16
|
+
|
|
17
|
+
Answer with a single word: YES if this is an unexpected stop, NO otherwise.
|
package/src/prompts/tools/ask.md
CHANGED
|
@@ -20,11 +20,3 @@ Asks user when you need clarification or input during task execution.
|
|
|
20
20
|
- **If multiple choices are acceptable**, pick the most conservative/standard option and proceed; state the choice.
|
|
21
21
|
- **Do NOT include "Other" option** — UI automatically adds "Other (type your own)" to every question.
|
|
22
22
|
</critical>
|
|
23
|
-
|
|
24
|
-
<examples>
|
|
25
|
-
# Single question
|
|
26
|
-
questions: [{"id": "auth_method", "question": "Which authentication method should this API use?", "options": [{"label": "JWT", "description": "Bearer tokens for stateless API clients."}, {"label": "OAuth2", "description": "Delegated authorization with external identity providers."}, {"label": "Session cookies", "description": "Browser-first authentication backed by server-side sessions."}], "recommended": 0}]
|
|
27
|
-
|
|
28
|
-
# Multiple questions
|
|
29
|
-
questions: [{"id": "storage_type", "question": "Which storage backend?", "options": [{"label": "SQLite"}, {"label": "PostgreSQL"}]}, {"id": "auth_method", "question": "Which auth method?", "options": [{"label": "JWT"}, {"label": "Session cookies"}]}]
|
|
30
|
-
</examples>
|
|
@@ -18,21 +18,6 @@ Performs structural AST-aware rewrites via native ast-grep.
|
|
|
18
18
|
- Parse issues when files cannot be processed
|
|
19
19
|
</output>
|
|
20
20
|
|
|
21
|
-
<examples>
|
|
22
|
-
# Rename a call site across TypeScript files
|
|
23
|
-
`{"ops":[{"pat":"oldApi($$$ARGS)","out":"newApi($$$ARGS)"}],"paths":["src/**/*.ts"]}`
|
|
24
|
-
# Delete matching calls
|
|
25
|
-
`{"ops":[{"pat":"console.log($$$ARGS)","out":""}],"paths":["src/**/*.ts"]}`
|
|
26
|
-
# Rewrite import source path
|
|
27
|
-
`{"ops":[{"pat":"import { $$$IMPORTS } from \"old-package\"","out":"import { $$$IMPORTS } from \"new-package\""}],"paths":["src/**/*.ts"]}`
|
|
28
|
-
# Modernize to optional chaining (same metavariable enforces identity)
|
|
29
|
-
`{"ops":[{"pat":"$A && $A()","out":"$A?.()"}],"paths":["src/**/*.ts"]}`
|
|
30
|
-
# Swap two arguments using captures
|
|
31
|
-
`{"ops":[{"pat":"assertEqual($A, $B)","out":"assertEqual($B, $A)"}],"paths":["tests/**/*.ts"]}`
|
|
32
|
-
# Python — convert print calls to logging
|
|
33
|
-
`{"ops":[{"pat":"print($$$ARGS)","out":"logger.info($$$ARGS)"}],"paths":["src/**/*.py"]}`
|
|
34
|
-
</examples>
|
|
35
|
-
|
|
36
21
|
<critical>
|
|
37
22
|
- Parse issues mean the rewrite is malformed or mis-scoped — fix the pattern before assuming a clean no-op
|
|
38
23
|
- For one-off local text edits, you SHOULD prefer the Edit tool
|
|
@@ -22,19 +22,6 @@ Performs structural code search using AST matching via native ast-grep.
|
|
|
22
22
|
- Summary counts (`totalMatches`, `filesWithMatches`, `filesSearched`) and parse issues when present
|
|
23
23
|
</output>
|
|
24
24
|
|
|
25
|
-
<examples>
|
|
26
|
-
# Search TypeScript files under src
|
|
27
|
-
`{"pat":"console.log($$$)","paths":["src/**/*.ts"]}`
|
|
28
|
-
# Named imports from a specific package
|
|
29
|
-
`{"pat":"import { $$$IMPORTS } from \"react\"","paths":["src/**/*.ts"]}`
|
|
30
|
-
# Arrow functions assigned to a const
|
|
31
|
-
`{"pat":"const $NAME = ($$$ARGS) => $BODY","paths":["src/utils/**/*.ts"]}`
|
|
32
|
-
# Method call on any object, ignoring method name with `$_`
|
|
33
|
-
`{"pat":"logger.$_($$$ARGS)","paths":["src/**/*.ts"]}`
|
|
34
|
-
# Loosest existence check for a symbol in one file
|
|
35
|
-
`{"pat":"processItems","paths":["src/worker.ts"]}`
|
|
36
|
-
</examples>
|
|
37
|
-
|
|
38
25
|
<critical>
|
|
39
26
|
- AVOID repo-root scans — narrow `paths` first
|
|
40
27
|
- Parse issues are query failure, not evidence of absence: repair the pattern or tighten `paths` before concluding "no matches"
|
|
@@ -37,27 +37,6 @@ Drives real Chromium tab; full puppeteer access via JS execution.
|
|
|
37
37
|
- `code` runs with full Node access. Treat as your code, not sandboxed code.
|
|
38
38
|
</critical>
|
|
39
39
|
|
|
40
|
-
<examples>
|
|
41
|
-
# Open a tab and read structured page data
|
|
42
|
-
`{"action":"open","name":"docs","url":"https://example.com"}`
|
|
43
|
-
`{"action":"run","name":"docs","code":"const obs = await tab.observe(); display(obs); return obs.elements.length;"}`
|
|
44
|
-
|
|
45
|
-
# Click an observed element by id
|
|
46
|
-
`{"action":"run","name":"docs","code":"const obs = await tab.observe(); const link = obs.elements.find(e => e.role === 'link' && e.name === 'Sign in'); assert(link, 'Sign in link missing'); await (await tab.id(link.id)).click();"}`
|
|
47
|
-
|
|
48
|
-
# Fill and submit a form via selectors
|
|
49
|
-
`{"action":"run","name":"docs","code":"await tab.fill('input[name=email]', 'me@example.com'); await tab.click('text/Continue');"}`
|
|
50
|
-
|
|
51
|
-
# Screenshot to look at the page — no save path
|
|
52
|
-
`{"action":"run","name":"docs","code":"await tab.screenshot();"}`
|
|
53
|
-
|
|
54
|
-
# Attach to an existing Electron app
|
|
55
|
-
`{"action":"open","name":"cursor","app":{"path":"/Applications/Cursor.app/Contents/MacOS/Cursor"}}`
|
|
56
|
-
|
|
57
|
-
# Close every tab and kill spawned-app processes
|
|
58
|
-
`{"action":"close","all":true,"kill":true}`
|
|
59
|
-
</examples>
|
|
60
|
-
|
|
61
40
|
<output>
|
|
62
41
|
Per call: `display(value)` outputs (text/images), then the JSON-stringified return value of `code`. `run` always produces at least a status line.
|
|
63
42
|
</output>
|
|
@@ -19,16 +19,3 @@ Use for launching or attaching debuggers, setting breakpoints, stepping through
|
|
|
19
19
|
- `program` must be an executable file or debug target, not a directory or interpreter name that resolves to a workspace directory.
|
|
20
20
|
- Python debugging requires `debugpy`; install with `pip install debugpy` if the adapter is unavailable.
|
|
21
21
|
</caution>
|
|
22
|
-
|
|
23
|
-
<examples>
|
|
24
|
-
# Launch and inspect hang
|
|
25
|
-
1. `debug(action: "launch", program: "./my_app")`
|
|
26
|
-
2. `debug(action: "set_breakpoint", file: "src/main.c", line: 42)`
|
|
27
|
-
3. `debug(action: "continue")`
|
|
28
|
-
4. If the program appears hung: `debug(action: "pause")`
|
|
29
|
-
5. Inspect state with `threads`, `stack_trace`, `scopes`, and `variables`
|
|
30
|
-
# Launch a Python script with debugpy
|
|
31
|
-
`debug(action: "launch", adapter: "debugpy", program: "scripts/job.py", args: ["--flag"])`
|
|
32
|
-
# Raw debugger command through repl
|
|
33
|
-
`debug(action: "evaluate", expression: "info registers", context: "repl")`
|
|
34
|
-
</examples>
|
|
@@ -58,12 +58,3 @@ budget → per-turn token budget
|
|
|
58
58
|
{{#if py}}`budget.total` (ceiling or None), `budget.spent()`, `budget.remaining()` (math.inf when no ceiling), `budget.hard` (bool).{{/if}}{{#if js}}`await budget.total()` (ceiling or null), `await budget.spent()`, `await budget.remaining()` (Infinity when no ceiling), `await budget.hard()`.{{/if}} Ceiling comes from a `+Nk` directive (advisory) or `+Nk!`/Goal Mode (hard — `agent()` refuses to spawn past it); otherwise None/null, spend still tracked across the turn.
|
|
59
59
|
```
|
|
60
60
|
</prelude>
|
|
61
|
-
|
|
62
|
-
<example>
|
|
63
|
-
{
|
|
64
|
-
"cells": [
|
|
65
|
-
{ "language": "py", "title": "imports", "timeout": 10, "code": "import json\nfrom pathlib import Path" },
|
|
66
|
-
{ "language": "py", "title": "load config", "code": "data = json.loads(read('package.json'))\ndisplay(data)" }
|
|
67
|
-
]
|
|
68
|
-
}
|
|
69
|
-
</example>
|
|
@@ -14,19 +14,6 @@ Finds files and directories using fast pattern matching that works with any code
|
|
|
14
14
|
Matching file and directory paths sorted by modification time (most recent first), grouped by directory to reduce token usage. Each group starts with `# <dir>/` followed by basenames (one per line); directory entries get a trailing `/`. Root-level entries have no header. Truncated at 200 entries or 50KB.
|
|
15
15
|
</output>
|
|
16
16
|
|
|
17
|
-
<examples>
|
|
18
|
-
# Find files
|
|
19
|
-
`{"paths": ["src/**/*.ts"]}`
|
|
20
|
-
# Multiple targets — separate array elements
|
|
21
|
-
`{"paths": ["src/**/*.ts", "test/**/*.ts"]}`
|
|
22
|
-
# Find gitignored files like .env
|
|
23
|
-
`{"paths": [".env*"], "gitignore": false}`
|
|
24
|
-
# Find directories matching a name (returns both files and dirs; directories are suffixed with `/`)
|
|
25
|
-
`{"paths": ["**/tests"]}`
|
|
26
|
-
# Long-running search on a slow volume
|
|
27
|
-
`{"paths": ["/Volumes/Storage/**/*.py"], "timeout": 30}`
|
|
28
|
-
</examples>
|
|
29
|
-
|
|
30
17
|
<avoid>
|
|
31
18
|
For open-ended searches requiring multiple rounds of globbing and searching, you MUST use Task tool instead.
|
|
32
19
|
</avoid>
|
|
@@ -11,15 +11,6 @@ Inspects an image file with a vision-capable model and returns compact text anal
|
|
|
11
11
|
- Use this tool over `read` when the goal is image analysis
|
|
12
12
|
</instruction>
|
|
13
13
|
|
|
14
|
-
<examples>
|
|
15
|
-
# OCR with strict formatting
|
|
16
|
-
`{"path":"screenshots/error.png","question":"Extract all visible text verbatim. Return as bullet list in reading order."}`
|
|
17
|
-
# Screenshot debugging
|
|
18
|
-
`{"path":"screenshots/settings.png","question":"Identify the likely cause of the disabled Save button. Return: (1) observations, (2) likely cause, (3) confidence."}`
|
|
19
|
-
# Scene/object question
|
|
20
|
-
`{"path":"photos/shelf.jpg","question":"List all clearly visible product labels and their shelf positions (top/middle/bottom). If unreadable, say unreadable."}`
|
|
21
|
-
</examples>
|
|
22
|
-
|
|
23
14
|
<output>
|
|
24
15
|
- Returns text-only analysis from the vision model
|
|
25
16
|
- No image content blocks are returned in tool output
|
package/src/prompts/tools/irc.md
CHANGED
|
@@ -40,18 +40,3 @@ Applies to sending and replying.
|
|
|
40
40
|
- `inbox`: pending messages, oldest first.
|
|
41
41
|
- `list`: peers with status, unread count, parent, last activity.
|
|
42
42
|
</output>
|
|
43
|
-
|
|
44
|
-
<examples>
|
|
45
|
-
# List peers
|
|
46
|
-
`{"op": "list"}`
|
|
47
|
-
# Fire-and-forget DM — same send wakes idle/parked peers
|
|
48
|
-
`{"op": "send", "to": "AuthLoader", "message": "Still touching src/server/auth.ts? I need to add a 401 path."}`
|
|
49
|
-
# Round-trip when you cannot proceed without the answer
|
|
50
|
-
`{"op": "send", "to": "Main", "message": "JWT or session cookies for the auth flow?", "await": true}`
|
|
51
|
-
# Block until a specific peer answers
|
|
52
|
-
`{"op": "wait", "from": "AuthLoader", "timeoutMs": 60000}`
|
|
53
|
-
# Drain pending messages
|
|
54
|
-
`{"op": "inbox"}`
|
|
55
|
-
# Broadcast to live peers (no replies expected)
|
|
56
|
-
`{"op": "send", "to": "all", "message": "About to refactor src/server/middleware/*. Anyone already in there?"}`
|
|
57
|
-
</examples>
|
|
@@ -50,19 +50,6 @@ Returns success/failure; on failure, error message indicates:
|
|
|
50
50
|
- NEVER use edit to fix indentation, whitespace, or reformat code. Formatting is a single command run once at the end (`bun fmt`, `cargo fmt`, `prettier --write`, etc.) — not N individual edits. If you see inconsistent indentation after an edit, leave it; the formatter will fix all of it in one pass.
|
|
51
51
|
</critical>
|
|
52
52
|
|
|
53
|
-
<examples>
|
|
54
|
-
# Create
|
|
55
|
-
`edit {"path":"hello.txt","edits":[{"op":"create","diff":"Hello\n"}]}`
|
|
56
|
-
# Update
|
|
57
|
-
`edit {"path":"src/app.py","edits":[{"op":"update","diff":"@@ def greet():\n def greet():\n-print('Hi')\n+print('Hello')\n"}]}`
|
|
58
|
-
# Rename
|
|
59
|
-
`edit {"path":"src/app.py","edits":[{"op":"update","rename":"src/main.py","diff":"@@\n …\n"}]}`
|
|
60
|
-
# Delete
|
|
61
|
-
`edit {"path":"obsolete.txt","edits":[{"op":"delete"}]}`
|
|
62
|
-
# Multiple entries
|
|
63
|
-
All entries in one call apply to the top-level `path`; use separate calls for different files.
|
|
64
|
-
</examples>
|
|
65
|
-
|
|
66
53
|
<avoid>
|
|
67
54
|
- Generic anchors: `import`, `export`, `describe`, `function`, `const`
|
|
68
55
|
- Repeating same addition in multiple hunks (duplicate blocks)
|
package/src/prompts/tools/ssh.md
CHANGED
|
@@ -20,12 +20,3 @@ Runs commands on remote hosts.
|
|
|
20
20
|
<critical>
|
|
21
21
|
You MUST verify the shell type from "Available hosts" and use matching commands.
|
|
22
22
|
</critical>
|
|
23
|
-
|
|
24
|
-
<examples>
|
|
25
|
-
# List files: Linux
|
|
26
|
-
Host: server1 (10.0.0.1) | linux/bash. Command: `ls -la /home/user`
|
|
27
|
-
# Show running processes: Windows cmd
|
|
28
|
-
Host: winbox (192.168.1.5) | windows/cmd. Command: `tasklist /v`
|
|
29
|
-
# Get system info: macOS
|
|
30
|
-
Host: macbook (10.0.0.20) | macos/zsh. Command: `uname -a && sw_vers`
|
|
31
|
-
</examples>
|
|
@@ -9,6 +9,7 @@ Allowed `op` values are only `init`, `start`, `done`, `drop`, `rm`, `append`, an
|
|
|
9
9
|
|`op`|Required fields|Effect|
|
|
10
10
|
|---|---|---|
|
|
11
11
|
|`init`|`list: [{phase, items: string[]}]`|Initialize the full list (replaces any existing list)|
|
|
12
|
+
|`init`|`items: string[]`|Flattened single-phase init|
|
|
12
13
|
|`start`|`task`|Mark in progress|
|
|
13
14
|
|`done`|`task` or `phase`|Mark completed|
|
|
14
15
|
|`drop`|`task` or `phase`|Mark abandoned|
|
|
@@ -33,25 +34,6 @@ Allowed `op` values are only `init`, `start`, `done`, `drop`, `rm`, `append`, an
|
|
|
33
34
|
- User provides a set of tasks to complete
|
|
34
35
|
- New instructions arrive mid-task — capture before proceeding
|
|
35
36
|
|
|
36
|
-
<examples>
|
|
37
|
-
# Initial setup (multi-phase)
|
|
38
|
-
`{"ops":[{"op":"init","list":[{"phase":"Foundation","items":["Scaffold crate","Wire workspace"]},{"phase":"Auth","items":["Port credential store","Wire OAuth providers"]},{"phase":"Verification","items":["Run cargo test"]}]}]}`
|
|
39
|
-
# View current state (read-only)
|
|
40
|
-
`{"ops":[{"op":"view"}]}`
|
|
41
|
-
# Initial setup (single phase)
|
|
42
|
-
`{"ops":[{"op":"init","list":[{"phase":"Implementation","items":["Apply fix","Run tests"]}]}]}`
|
|
43
|
-
# Complete one task
|
|
44
|
-
`{"ops":[{"op":"done","task":"Wire workspace"}]}`
|
|
45
|
-
# Complete a whole phase
|
|
46
|
-
`{"ops":[{"op":"done","phase":"Auth"}]}`
|
|
47
|
-
# Remove all tasks
|
|
48
|
-
`{"ops":[{"op":"rm"}]}`
|
|
49
|
-
# Drop one task
|
|
50
|
-
`{"ops":[{"op":"drop","task":"Run cargo test"}]}`
|
|
51
|
-
# Append tasks to a phase
|
|
52
|
-
`{"ops":[{"op":"append","phase":"Auth","items":["Handle retries","Run tests"]}]}`
|
|
53
|
-
</examples>
|
|
54
|
-
|
|
55
37
|
<critical>
|
|
56
38
|
When the user hands you a multi-step plan — a phased todo, a numbered or bulleted checklist, or "N bugs/items/tasks" to work through:
|
|
57
39
|
- You MUST `init` the list with EVERY item as its own task before doing the work.
|
package/src/sdk.ts
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
type SimpleStreamOptions,
|
|
17
17
|
streamSimple,
|
|
18
18
|
} from "@oh-my-pi/pi-ai";
|
|
19
|
+
import type { ToolCallSyntax } from "@oh-my-pi/pi-ai/grammar";
|
|
19
20
|
import {
|
|
20
21
|
getOpenAICodexTransportDetails,
|
|
21
22
|
prewarmOpenAICodexResponses,
|
|
@@ -550,6 +551,17 @@ export interface CreateAgentSessionResult {
|
|
|
550
551
|
eventBus: EventBus;
|
|
551
552
|
}
|
|
552
553
|
|
|
554
|
+
export type ToolCallFormat = "auto" | "native" | ToolCallSyntax;
|
|
555
|
+
|
|
556
|
+
export function resolveToolCallSyntax(
|
|
557
|
+
format: ToolCallFormat,
|
|
558
|
+
model: Pick<Model, "supportsTools"> | undefined,
|
|
559
|
+
): ToolCallSyntax | undefined {
|
|
560
|
+
if (format === "native") return undefined;
|
|
561
|
+
if (format === "auto") return model?.supportsTools === false ? "glm" : undefined;
|
|
562
|
+
return format;
|
|
563
|
+
}
|
|
564
|
+
|
|
553
565
|
// Re-exports
|
|
554
566
|
|
|
555
567
|
export type { PromptTemplate } from "./config/prompt-templates";
|
|
@@ -2149,6 +2161,10 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2149
2161
|
}
|
|
2150
2162
|
appendPrompt = parts.join("\n\n");
|
|
2151
2163
|
}
|
|
2164
|
+
// Owned/in-band tool syntax (non-native) repeats the catalog as `# Tool:`
|
|
2165
|
+
// sections; native tool calling lets the compact name list suffice.
|
|
2166
|
+
const nativeTools =
|
|
2167
|
+
resolveToolCallSyntax(settings.get("tools.format"), agent?.state.model ?? model) === undefined;
|
|
2152
2168
|
const defaultPrompt = await buildSystemPromptInternal({
|
|
2153
2169
|
cwd,
|
|
2154
2170
|
skills,
|
|
@@ -2160,6 +2176,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2160
2176
|
skillsSettings: settings.getGroup("skills"),
|
|
2161
2177
|
appendSystemPrompt: appendPrompt,
|
|
2162
2178
|
repeatToolDescriptions,
|
|
2179
|
+
nativeTools,
|
|
2163
2180
|
intentField,
|
|
2164
2181
|
mcpDiscoveryMode: hasDiscoverableTools,
|
|
2165
2182
|
mcpDiscoveryServerSummaries: discoverableToolSummary.servers.map(formatDiscoverableToolServerSummary),
|
|
@@ -2489,6 +2506,8 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2489
2506
|
return result;
|
|
2490
2507
|
},
|
|
2491
2508
|
intentTracing: !!intentField,
|
|
2509
|
+
toolCallSyntax: resolveToolCallSyntax(settings.get("tools.format"), model),
|
|
2510
|
+
abortOnFabricatedToolResult: settings.get("tools.abortOnFabricatedResult"),
|
|
2492
2511
|
getToolChoice: () => session?.nextToolChoice(),
|
|
2493
2512
|
telemetry: options.telemetry,
|
|
2494
2513
|
appendOnlyContext: model
|