Improve system prompt docs, clean up theme/skills/hooks docs, fix toolResults type

- System prompt: clearer pointers to specific doc files
- theme.md: added thinkingXhigh, bashMode tokens, fixed Theme class methods
- skills.md: rewrote with better framing, examples, and skill repositories
- hooks.md: fixed timeout/error handling docs, added custom tool interception note
- Breaking: turn_end event toolResults changed from AppMessage[] to ToolResultMessage[]
This commit is contained in:
Mario Zechner 2025-12-17 21:27:28 +01:00
parent 5cc0126991
commit 5e5bdadbf9
8 changed files with 232 additions and 141 deletions

View file

@ -4,6 +4,7 @@ import type {
AssistantMessageEvent, AssistantMessageEvent,
Message, Message,
Model, Model,
ToolResultMessage,
UserMessage, UserMessage,
} from "@mariozechner/pi-ai"; } from "@mariozechner/pi-ai";
@ -87,7 +88,7 @@ export type AgentEvent =
| { type: "agent_end"; messages: AppMessage[] } | { type: "agent_end"; messages: AppMessage[] }
// Turn lifecycle - a turn is one assistant response + any tool calls/results // Turn lifecycle - a turn is one assistant response + any tool calls/results
| { type: "turn_start" } | { type: "turn_start" }
| { type: "turn_end"; message: AppMessage; toolResults: AppMessage[] } | { type: "turn_end"; message: AppMessage; toolResults: ToolResultMessage[] }
// Message lifecycle - emitted for user, assistant, and toolResult messages // Message lifecycle - emitted for user, assistant, and toolResult messages
| { type: "message_start"; message: AppMessage } | { type: "message_start"; message: AppMessage }
// Only emitted for assistant messages during streaming // Only emitted for assistant messages during streaming

View file

@ -2,6 +2,16 @@
## [Unreleased] ## [Unreleased]
### Changed
- Improved system prompt documentation section with clearer pointers to specific doc files for custom models, themes, skills, hooks, custom tools, and RPC.
- Cleaned up documentation: `theme.md` (added missing color tokens), `skills.md` (rewrote with better framing and examples), `hooks.md` (fixed timeout/error handling docs, added examples).
### Breaking Changes
- **Hooks**: `turn_end` event's `toolResults` type changed from `AppMessage[]` to `ToolResultMessage[]`. If you have hooks that handle `turn_end` events and explicitly type the results, update your type annotations.
## [0.23.2] - 2025-12-17 ## [0.23.2] - 2025-12-17
### Fixed ### Fixed

View file

@ -488,66 +488,41 @@ Usage: `/component Button "onClick handler" "disabled support"`
### Skills ### Skills
Skills are instruction files loaded on-demand when tasks match their descriptions. Compatible with Claude Code and Codex CLI skill formats. Skills are self-contained capability packages that the agent loads on-demand. A skill provides specialized workflows, setup instructions, helper scripts, and reference documentation for specific tasks. Skills are loaded when the agent decides a task matches the description, or when you explicitly ask to use one.
**Skill locations:** **Skill locations:**
- Pi user: `~/.pi/agent/skills/**/SKILL.md` (recursive, colon-separated names) - Pi user: `~/.pi/agent/skills/**/SKILL.md` (recursive)
- Pi project: `.pi/skills/**/SKILL.md` (recursive, colon-separated names) - Pi project: `.pi/skills/**/SKILL.md` (recursive)
- Claude Code user: `~/.claude/skills/*/SKILL.md` (one level) - Claude Code: `~/.claude/skills/*/SKILL.md` and `.claude/skills/*/SKILL.md`
- Claude Code project: `.claude/skills/*/SKILL.md` (one level)
- Codex CLI: `~/.codex/skills/**/SKILL.md` (recursive) - Codex CLI: `~/.codex/skills/**/SKILL.md` (recursive)
Later locations win on name collisions (Pi skills override Claude/Codex).
Pi skills in subdirectories use colon-separated names: `~/.pi/agent/skills/db/migrate/SKILL.md``db:migrate`
**Format:** **Format:**
```markdown ```markdown
--- ---
description: Extract text and tables from PDF files description: Web search via Brave Search API. Use for documentation, facts, or web content.
--- ---
# PDF Processing # Brave Search
Use `pdftotext` for plain text extraction. ## Setup
For tables, use `tabula-py`. \`\`\`bash
cd {baseDir} && npm install
\`\`\`
Helper scripts: {baseDir}/scripts/ ## Usage
\`\`\`bash
{baseDir}/search.js "query" # Basic search
{baseDir}/search.js "query" --content # Include page content
\`\`\`
``` ```
- `description`: Required. Shown in system prompt for agent to decide when to load. - `description`: Required. Determines when the skill is loaded.
- `name`: Optional. Overrides directory name. - `{baseDir}`: Placeholder for the skill's directory.
- `{baseDir}`: Placeholder for the skill's directory. Agent substitutes it when following instructions.
**How it works:** **Disable skills:** `pi --no-skills` or set `skills.enabled: false` in settings.
Skills are listed in the system prompt with descriptions: See [docs/skills.md](docs/skills.md) for details, examples, and links to skill repositories.
```
<available_skills>
- pdf-extract: Extract text and tables from PDF files
File: ~/.pi/agent/skills/pdf-extract/SKILL.md
Base directory: ~/.pi/agent/skills/pdf-extract
</available_skills>
```
Agent uses `read` tool to load full instructions when needed.
**Disable skills:**
CLI: `pi --no-skills`
Settings (`~/.pi/agent/settings.json`):
```json
{
"skills": {
"enabled": false
}
}
```
See [docs/skills.md](docs/skills.md) for details.
### Hooks ### Hooks

View file

@ -2,6 +2,15 @@
Hooks are TypeScript modules that extend the coding agent's behavior by subscribing to lifecycle events. They can intercept tool calls, prompt the user for input, modify results, and more. Hooks are TypeScript modules that extend the coding agent's behavior by subscribing to lifecycle events. They can intercept tool calls, prompt the user for input, modify results, and more.
**Example use cases:**
- Block dangerous commands (permission gates for `rm -rf`, `sudo`, etc.)
- Checkpoint code state (git stash at each turn, restore on `/branch`)
- Protect paths (block writes to `.env`, `node_modules/`, etc.)
- Modify tool output (filter or transform results before the LLM sees them)
- Inject messages from external sources (file watchers, webhooks, CI systems)
See [examples/hooks/](../examples/hooks/) for working implementations.
## Hook Locations ## Hook Locations
Hooks are automatically discovered from two locations: Hooks are automatically discovered from two locations:
@ -33,7 +42,7 @@ You can also add explicit hook paths in `~/.pi/agent/settings.json`:
``` ```
- `hooks`: Additional hook file paths (supports `~` expansion) - `hooks`: Additional hook file paths (supports `~` expansion)
- `hookTimeout`: Timeout in milliseconds for non-interactive hook operations (default: 30000) - `hookTimeout`: Timeout in milliseconds for hook operations (default: 30000). Does not apply to `tool_call` events, which have no timeout since they may prompt the user.
## Writing a Hook ## Writing a Hook
@ -51,23 +60,17 @@ export default function (pi: HookAPI) {
### Setup ### Setup
Create a hooks directory and initialize it: Create a hooks directory:
```bash ```bash
# Global hooks # Global hooks
mkdir -p ~/.pi/agent/hooks mkdir -p ~/.pi/agent/hooks
cd ~/.pi/agent/hooks
npm init -y
npm install @mariozechner/pi-coding-agent
# Or project-local hooks # Or project-local hooks
mkdir -p .pi/hooks mkdir -p .pi/hooks
cd .pi/hooks
npm init -y
npm install @mariozechner/pi-coding-agent
``` ```
Hooks are loaded using [jiti](https://github.com/unjs/jiti), so TypeScript works without compilation. Then create `.ts` files directly in these directories. Hooks are loaded using [jiti](https://github.com/unjs/jiti), so TypeScript works without compilation. The import from `@mariozechner/pi-coding-agent/hooks` resolves to the globally installed package automatically.
## Events ## Events
@ -121,7 +124,7 @@ Fired on startup and when session changes.
```typescript ```typescript
pi.on("session", async (event, ctx) => { pi.on("session", async (event, ctx) => {
// event.entries: SessionEntry[] - all session entries // event.entries: SessionEntry[] - all session entries
// event.sessionFile: string | null - current session file // event.sessionFile: string | null - current session file (null with --no-session)
// event.previousSessionFile: string | null - previous session file // event.previousSessionFile: string | null - previous session file
// event.reason: "start" | "switch" | "clear" // event.reason: "start" | "switch" | "clear"
}); });
@ -171,24 +174,24 @@ pi.on("turn_start", async (event, ctx) => {
pi.on("turn_end", async (event, ctx) => { pi.on("turn_end", async (event, ctx) => {
// event.turnIndex: number // event.turnIndex: number
// event.message: AppMessage - assistant's response // event.message: AppMessage - assistant's response
// event.toolResults: AppMessage[] // event.toolResults: ToolResultMessage[] - tool results from this turn
}); });
``` ```
### tool_call ### tool_call
Fired before tool executes. **Can block.** Fired before tool executes. **Can block.** No timeout (user prompts can take any time).
```typescript ```typescript
pi.on("tool_call", async (event, ctx) => { pi.on("tool_call", async (event, ctx) => {
// event.toolName: "bash" | "read" | "write" | "edit" | "ls" | "find" | "grep" // event.toolName: string (built-in or custom tool name)
// event.toolCallId: string // event.toolCallId: string
// event.input: Record<string, unknown> // event.input: Record<string, unknown>
return { block: true, reason: "..." }; // or undefined to allow return { block: true, reason: "..." }; // or undefined to allow
}); });
``` ```
Tool inputs: Built-in tool inputs:
- `bash`: `{ command, timeout? }` - `bash`: `{ command, timeout? }`
- `read`: `{ path, offset?, limit? }` - `read`: `{ path, offset?, limit? }`
- `write`: `{ path, content }` - `write`: `{ path, content }`
@ -197,6 +200,8 @@ Tool inputs:
- `find`: `{ pattern, path?, limit? }` - `find`: `{ pattern, path?, limit? }`
- `grep`: `{ pattern, path?, glob?, ignoreCase?, literal?, context?, limit? }` - `grep`: `{ pattern, path?, glob?, ignoreCase?, literal?, context?, limit? }`
Custom tools are also intercepted with their own names and input schemas.
### tool_result ### tool_result
Fired after tool executes. **Can modify result.** Fired after tool executes. **Can modify result.**
@ -274,7 +279,7 @@ console.log(`Working in: ${ctx.cwd}`);
### ctx.sessionFile ### ctx.sessionFile
Path to the session file, or `null` if running with `--no-session`. Path to the current session file, or `null` when running with `--no-session` (ephemeral mode).
```typescript ```typescript
if (ctx.sessionFile) { if (ctx.sessionFile) {
@ -490,7 +495,8 @@ In print mode, `select()` returns `null`, `confirm()` returns `false`, and `inpu
## Error Handling ## Error Handling
- If a hook throws an error, it's logged and the agent continues - If a hook throws an error, it's logged and the agent continues
- If a `tool_call` hook errors or times out, the tool is **blocked** (fail-safe) - If a `tool_call` hook throws an error, the tool is **blocked** (fail-safe)
- Other events have a timeout (default 30s); timeout errors are logged but don't block
- Hook errors are displayed in the UI with the hook path and error message - Hook errors are displayed in the UI with the hook path and error message
## Debugging ## Debugging
@ -563,9 +569,9 @@ class HookRunner {
Key behaviors: Key behaviors:
- `emit()` has a timeout (default 30s) for safety - `emit()` has a timeout (default 30s) for safety
- `emitToolCall()` has **no timeout** (user prompts can take any amount of time) - `emitToolCall()` has **no timeout** (user prompts can take any time)
- Errors in `emit()` are caught and reported via `onError()` - Errors in `emit()` are caught, logged via `onError()`, and execution continues
- Errors in `emitToolCall()` propagate (causing tool to be blocked) - Errors in `emitToolCall()` propagate, causing the tool to be blocked (fail-safe)
## Event Flow ## Event Flow

View file

@ -1,72 +1,190 @@
# Skills # Skills
Skills are instruction files that the agent loads on-demand for specific tasks. Skills are self-contained capability packages that the agent loads on-demand. A skill provides specialized workflows, setup instructions, helper scripts, and reference documentation for specific tasks.
## Skill Locations **Example use cases:**
- Web search and content extraction (Brave Search API)
- Browser automation via Chrome DevTools Protocol
- Google Calendar, Gmail, Drive integration
- PDF/DOCX processing and creation
- Speech-to-text transcription
- YouTube transcript extraction
Skills are discovered from these locations (in order of priority, later wins on name collision): See [Skill Repositories](#skill-repositories) for ready-to-use skills.
1. `~/.codex/skills/**/SKILL.md` (Codex CLI user skills, recursive) ## When to Use Skills
2. `~/.claude/skills/*/SKILL.md` (Claude Code user skills)
3. `<cwd>/.claude/skills/*/SKILL.md` (Claude Code project skills)
4. `~/.pi/agent/skills/**/SKILL.md` (Pi user skills, recursive)
5. `<cwd>/.pi/skills/**/SKILL.md` (Pi project skills, recursive)
Skill names and descriptions are listed in the system prompt. When a task matches a skill's description, the agent uses the `read` tool to load it. | Need | Solution |
|------|----------|
| Always-needed context (conventions, commands) | AGENTS.md |
| User triggers a specific prompt template | Slash command |
| Additional tool directly callable by the LLM (like read/write/edit/bash) | Custom tool |
| On-demand capability package (workflows, scripts, setup) | Skill |
## Creating Skills Skills are loaded when:
- The agent decides the task matches a skill's description
- The user explicitly asks to use a skill (e.g., "use the pdf skill to extract tables")
A skill is a markdown file with YAML frontmatter containing a `description` field: **Good skill examples:**
- Browser automation with helper scripts and CDP workflow
- Google Calendar CLI with setup instructions and usage patterns
- PDF processing with multiple tools and extraction patterns
- Speech-to-text transcription with API setup
**Not a good fit for skills:**
- "Always use TypeScript strict mode" → put in AGENTS.md
- "Review my code" → make a slash command
- Need user confirmation dialogs or custom TUI rendering → make a custom tool
## Skill Structure
A skill is a directory with a `SKILL.md` file. Everything else is freeform. Example structure:
```
my-skill/
├── SKILL.md # Required: frontmatter + instructions
├── scripts/ # Helper scripts (bash, python, node)
│ └── process.sh
├── references/ # Detailed docs loaded on-demand
│ └── api-reference.md
└── assets/ # Templates, images, etc.
└── template.json
```
### SKILL.md Format
```markdown ```markdown
--- ---
description: Extract text and tables from PDF files name: my-skill
description: What this skill does and when to use it. Be specific.
--- ---
# PDF Processing Instructions # My Skill
1. Use `pdftotext` to extract plain text ## Setup
2. For tables, use `tabula-py` or similar
3. Always verify extraction quality
Scripts are in: {baseDir}/scripts/ Run once before first use:
\`\`\`bash
cd {baseDir}
npm install
\`\`\`
## Usage
\`\`\`bash
{baseDir}/scripts/process.sh <input>
\`\`\`
## Workflow
1. First step
2. Second step
3. Third step
``` ```
### Frontmatter Fields ### Frontmatter Fields
| Field | Required | Description | | Field | Required | Description |
|-------|----------|-------------| |-------|----------|-------------|
| `description` | Yes | Short description for skill selection | | `description` | Yes | What the skill does and when to use it |
| `name` | No | Override skill name (defaults to filename or directory name) | | `name` | No | Override skill name (defaults to directory name) |
The parser only supports single-line `key: value` syntax. Multiline YAML blocks are not supported. The `description` is critical. It's shown in the system prompt and determines when the agent loads the skill. Be specific about both what it does and when to use it.
### Variables ### The `{baseDir}` Placeholder
Use `{baseDir}` as a placeholder for the skill's directory. The agent is told each skill's base directory and will substitute it when following the instructions. Use `{baseDir}` to reference files in the skill's directory. The agent sees each skill's base directory and substitutes it when following instructions:
### Subdirectories ```markdown
Helper scripts: {baseDir}/scripts/
Config template: {baseDir}/assets/config.json
```
Pi and Codex skills in subdirectories use colon-separated names: ## Skill Locations
Skills are discovered from these locations (later wins on name collision):
1. `~/.codex/skills/**/SKILL.md` (Codex CLI, recursive)
2. `~/.claude/skills/*/SKILL.md` (Claude Code user, one level)
3. `<cwd>/.claude/skills/*/SKILL.md` (Claude Code project, one level)
4. `~/.pi/agent/skills/**/SKILL.md` (Pi user, recursive)
5. `<cwd>/.pi/skills/**/SKILL.md` (Pi project, recursive)
### Subdirectory Naming
Pi skills in subdirectories use colon-separated names:
- `~/.pi/agent/skills/db/migrate/SKILL.md``db:migrate` - `~/.pi/agent/skills/db/migrate/SKILL.md``db:migrate`
- `<cwd>/.pi/skills/aws/s3/upload/SKILL.md``aws:s3:upload` - `<cwd>/.pi/skills/aws/s3/upload/SKILL.md``aws:s3:upload`
## Claude Code Compatibility ## How Skills Work
Pi reads Claude Code skills from `~/.claude/skills/*/SKILL.md`. The `allowed-tools` and `model` frontmatter fields are ignored since Pi cannot enforce them. 1. At startup, pi scans skill locations and extracts names + descriptions
2. The system prompt includes a list of available skills with their descriptions
3. When a task matches, the agent uses `read` to load the full SKILL.md
4. The agent follows the instructions, using `{baseDir}` to reference scripts/assets
## Codex CLI Compatibility This is progressive disclosure: only descriptions are always in context, full instructions load on-demand.
Pi reads Codex CLI skills from `~/.codex/skills/`. Unlike Claude Code skills (one level deep), Codex skills are scanned recursively, matching Codex CLI's behavior. Hidden files/directories (starting with `.`) and symlinks are skipped. ## Example: Web Search Skill
```
brave-search/
├── SKILL.md
├── search.js
└── content.js
```
**SKILL.md:**
```markdown
---
name: brave-search
description: Web search and content extraction via Brave Search API. Use for searching documentation, facts, or any web content.
---
# Brave Search
## Setup
\`\`\`bash
cd {baseDir}
npm install
\`\`\`
## Search
\`\`\`bash
{baseDir}/search.js "query" # Basic search
{baseDir}/search.js "query" --content # Include page content
\`\`\`
## Extract Page Content
\`\`\`bash
{baseDir}/content.js https://example.com
\`\`\`
```
## Compatibility
**Claude Code**: Pi reads skills from `~/.claude/skills/*/SKILL.md`. The `allowed-tools` and `model` frontmatter fields are ignored.
**Codex CLI**: Pi reads skills from `~/.codex/skills/` recursively. Hidden files/directories and symlinks are skipped.
## Skill Repositories
For inspiration and ready-to-use skills:
- [Anthropic Skills](https://github.com/anthropics/skills) - Official skills for document processing (docx, pdf, pptx, xlsx), web development, and more
- [Pi Skills](https://github.com/badlogic/pi-skills) - Skills for web search, browser automation, Google APIs, transcription
## Disabling Skills ## Disabling Skills
CLI flag: CLI:
```bash ```bash
pi --no-skills pi --no-skills
``` ```
Or in `~/.pi/agent/settings.json`: Settings (`~/.pi/agent/settings.json`):
```json ```json
{ {
"skills": { "skills": {
@ -74,25 +192,3 @@ Or in `~/.pi/agent/settings.json`:
} }
} }
``` ```
## Example
```markdown
---
description: Perform code review with security and performance analysis
---
# Code Review
Analyze:
## Security
- Input validation
- SQL injection
- XSS vulnerabilities
## Performance
- Algorithm complexity
- Memory usage
- Query efficiency
```

View file

@ -74,7 +74,7 @@ Future-proofing for syntax highlighting support:
| `syntaxOperator` | Operators (`+`, `-`, etc) | | `syntaxOperator` | Operators (`+`, `-`, etc) |
| `syntaxPunctuation` | Punctuation (`;`, `,`, etc) | | `syntaxPunctuation` | Punctuation (`;`, `,`, etc) |
### Thinking Level Borders (5 colors) ### Thinking Level Borders (6 colors)
Editor border colors that indicate the current thinking/reasoning level: Editor border colors that indicate the current thinking/reasoning level:
@ -84,11 +84,18 @@ Editor border colors that indicate the current thinking/reasoning level:
| `thinkingMinimal` | Border for minimal thinking | | `thinkingMinimal` | Border for minimal thinking |
| `thinkingLow` | Border for low thinking | | `thinkingLow` | Border for low thinking |
| `thinkingMedium` | Border for medium thinking | | `thinkingMedium` | Border for medium thinking |
| `thinkingHigh` | Border for high thinking (most prominent) | | `thinkingHigh` | Border for high thinking |
| `thinkingXhigh` | Border for xhigh thinking (most prominent, OpenAI codex-max only) |
These create a visual hierarchy: off → minimal → low → medium → high These create a visual hierarchy: off → minimal → low → medium → high → xhigh
**Total: 44 color tokens** (all required) ### Bash Mode (1 color)
| Token | Purpose |
|-------|---------|
| `bashMode` | Editor border color when in bash mode (! prefix) |
**Total: 46 color tokens** (all required)
## Theme Format ## Theme Format
@ -420,8 +427,8 @@ class Theme {
// Text attributes (preserve current colors) // Text attributes (preserve current colors)
bold(text: string): string bold(text: string): string
dim(text: string): string
italic(text: string): string italic(text: string): string
underline(text: string): string
} }
``` ```
@ -453,6 +460,7 @@ TUI components (like `Markdown`, `SelectList`, `Editor`) are in the `@mariozechn
export interface MarkdownTheme { export interface MarkdownTheme {
heading: (text: string) => string; heading: (text: string) => string;
link: (text: string) => string; link: (text: string) => string;
linkUrl: (text: string) => string;
code: (text: string) => string; code: (text: string) => string;
codeBlock: (text: string) => string; codeBlock: (text: string) => string;
codeBlockBorder: (text: string) => string; codeBlockBorder: (text: string) => string;
@ -460,21 +468,10 @@ export interface MarkdownTheme {
quoteBorder: (text: string) => string; quoteBorder: (text: string) => string;
hr: (text: string) => string; hr: (text: string) => string;
listBullet: (text: string) => string; listBullet: (text: string) => string;
} bold: (text: string) => string;
italic: (text: string) => string;
export class Markdown { strikethrough: (text: string) => string;
constructor( underline: (text: string) => string;
text: string,
paddingX: number,
paddingY: number,
defaultTextStyle?: DefaultTextStyle,
theme?: MarkdownTheme // Optional theme functions
)
// Usage in component
renderHeading(text: string) {
return this.theme.heading(text); // Applies color
}
} }
``` ```
@ -490,6 +487,7 @@ function getMarkdownTheme(): MarkdownTheme {
return { return {
heading: (text) => theme.fg('mdHeading', text), heading: (text) => theme.fg('mdHeading', text),
link: (text) => theme.fg('mdLink', text), link: (text) => theme.fg('mdLink', text),
linkUrl: (text) => theme.fg('mdLinkUrl', text),
code: (text) => theme.fg('mdCode', text), code: (text) => theme.fg('mdCode', text),
codeBlock: (text) => theme.fg('mdCodeBlock', text), codeBlock: (text) => theme.fg('mdCodeBlock', text),
codeBlockBorder: (text) => theme.fg('mdCodeBlockBorder', text), codeBlockBorder: (text) => theme.fg('mdCodeBlockBorder', text),
@ -497,6 +495,10 @@ function getMarkdownTheme(): MarkdownTheme {
quoteBorder: (text) => theme.fg('mdQuoteBorder', text), quoteBorder: (text) => theme.fg('mdQuoteBorder', text),
hr: (text) => theme.fg('mdHr', text), hr: (text) => theme.fg('mdHr', text),
listBullet: (text) => theme.fg('mdListBullet', text), listBullet: (text) => theme.fg('mdListBullet', text),
bold: (text) => theme.bold(text),
italic: (text) => theme.italic(text),
underline: (text) => theme.underline(text),
strikethrough: (text) => chalk.strikethrough(text),
}; };
} }
@ -530,7 +532,7 @@ theme.bg('toolSuccessBg', output)
// Combine styles // Combine styles
theme.bold(theme.fg('accent', 'Title')) theme.bold(theme.fg('accent', 'Title'))
theme.dim(theme.fg('muted', 'metadata')) theme.italic(theme.fg('muted', 'metadata'))
// Nested foreground + background // Nested foreground + background
const userMsg = theme.bg('userMessageBg', const userMsg = theme.bg('userMessageBg',

View file

@ -6,6 +6,7 @@
*/ */
import type { AppMessage, Attachment } from "@mariozechner/pi-agent-core"; import type { AppMessage, Attachment } from "@mariozechner/pi-agent-core";
import type { ToolResultMessage } from "@mariozechner/pi-ai";
import type { SessionEntry } from "../session-manager.js"; import type { SessionEntry } from "../session-manager.js";
// ============================================================================ // ============================================================================
@ -121,7 +122,7 @@ export interface TurnEndEvent {
type: "turn_end"; type: "turn_end";
turnIndex: number; turnIndex: number;
message: AppMessage; message: AppMessage;
toolResults: AppMessage[]; toolResults: ToolResultMessage[];
} }
/** /**

View file

@ -235,9 +235,9 @@ Guidelines:
${guidelines} ${guidelines}
Documentation: Documentation:
- Your own documentation (including custom model setup and theme creation) is at: ${readmePath} - Main documentation: ${readmePath}
- Additional documentation (hooks, themes, RPC, etc.) is in: ${docsPath} - Additional docs: ${docsPath}
- Read it when users ask about features, configuration, or setup, and especially if the user asks you to add a custom model or provider, create a custom theme, or write a hook.`; - When asked about: custom models/providers (README sufficient), themes (docs/theme.md), skills (docs/skills.md), hooks (docs/hooks.md), custom tools (docs/custom-tools.md), RPC (docs/rpc.md)`;
if (appendSection) { if (appendSection) {
prompt += appendSection; prompt += appendSection;