chore: renamed package scope to @oh-my-pi for consistent branding
- Renamed npm package scope from @mariozechner to @oh-my-pi across all packages for consistent branding. - Removed packages/pods directory and all related pod management functionality. - Updated import paths and module declarations throughout codebase to reflect new package names. - Reformatted code with consistent trailing comma removal and ternary operator alignment.
This commit is contained in:
@@ -7,20 +7,26 @@ Example custom tools for pi-coding-agent.
|
||||
Each example uses the `subdirectory/index.ts` structure required for tool discovery.
|
||||
|
||||
### hello/
|
||||
|
||||
Minimal example showing the basic structure of a custom tool.
|
||||
|
||||
### question/
|
||||
|
||||
Demonstrates `pi.ui.select()` for asking the user questions with options.
|
||||
|
||||
### todo/
|
||||
|
||||
Full-featured example demonstrating:
|
||||
|
||||
- `onSession` for state reconstruction from session history
|
||||
- Custom `renderCall` and `renderResult`
|
||||
- Proper branching support via details storage
|
||||
- State management without external files
|
||||
|
||||
### subagent/
|
||||
|
||||
Delegate tasks to specialized subagents with isolated context windows. Includes:
|
||||
|
||||
- `index.ts` - The custom tool (single, parallel, and chain modes)
|
||||
- `agents.ts` - Agent discovery helper
|
||||
- `agents/` - Sample agent definitions (scout, planner, reviewer, worker)
|
||||
@@ -39,6 +45,7 @@ cp -r todo ~/.pi/agent/tools/
|
||||
```
|
||||
|
||||
Then in pi:
|
||||
|
||||
```
|
||||
> add a todo "test custom tools"
|
||||
> list todos
|
||||
@@ -53,37 +60,41 @@ See [docs/custom-tools.md](../../docs/custom-tools.md) for full documentation.
|
||||
### Key Points
|
||||
|
||||
**Factory pattern:**
|
||||
|
||||
```typescript
|
||||
import { Type } from "@sinclair/typebox";
|
||||
import { StringEnum } from "@mariozechner/pi-ai";
|
||||
import { Text } from "@mariozechner/pi-tui";
|
||||
import type { CustomToolFactory } from "@mariozechner/pi-coding-agent";
|
||||
import { StringEnum } from "@oh-my-pi/pi-ai";
|
||||
import { Text } from "@oh-my-pi/pi-tui";
|
||||
import type { CustomToolFactory } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
const factory: CustomToolFactory = (pi) => ({
|
||||
name: "my_tool",
|
||||
label: "My Tool",
|
||||
description: "Tool description for LLM",
|
||||
parameters: Type.Object({
|
||||
action: StringEnum(["list", "add"] as const),
|
||||
}),
|
||||
|
||||
// Called on session start/switch/branch/clear
|
||||
onSession(event) {
|
||||
// Reconstruct state from event.entries
|
||||
},
|
||||
|
||||
async execute(toolCallId, params) {
|
||||
return {
|
||||
content: [{ type: "text", text: "Result" }],
|
||||
details: { /* for rendering and state reconstruction */ },
|
||||
};
|
||||
},
|
||||
name: "my_tool",
|
||||
label: "My Tool",
|
||||
description: "Tool description for LLM",
|
||||
parameters: Type.Object({
|
||||
action: StringEnum(["list", "add"] as const),
|
||||
}),
|
||||
|
||||
// Called on session start/switch/branch/clear
|
||||
onSession(event) {
|
||||
// Reconstruct state from event.entries
|
||||
},
|
||||
|
||||
async execute(toolCallId, params) {
|
||||
return {
|
||||
content: [{ type: "text", text: "Result" }],
|
||||
details: {
|
||||
/* for rendering and state reconstruction */
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default factory;
|
||||
```
|
||||
|
||||
**Custom rendering:**
|
||||
|
||||
```typescript
|
||||
renderCall(args, theme) {
|
||||
return new Text(
|
||||
@@ -101,12 +112,13 @@ renderResult(result, { expanded, isPartial }, theme) {
|
||||
```
|
||||
|
||||
**Use StringEnum for string parameters** (required for Google API compatibility):
|
||||
|
||||
```typescript
|
||||
import { StringEnum } from "@mariozechner/pi-ai";
|
||||
import { StringEnum } from "@oh-my-pi/pi-ai";
|
||||
|
||||
// Good
|
||||
action: StringEnum(["list", "add"] as const)
|
||||
action: StringEnum(["list", "add"] as const);
|
||||
|
||||
// Bad - doesn't work with Google
|
||||
action: Type.Union([Type.Literal("list"), Type.Literal("add")])
|
||||
action: Type.Union([Type.Literal("list"), Type.Literal("add")]);
|
||||
```
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { CustomToolFactory } from "@mariozechner/pi-coding-agent";
|
||||
import type { CustomToolFactory } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
const factory: CustomToolFactory = (pi) => ({
|
||||
name: "hello",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Question Tool - Let the LLM ask the user a question with options
|
||||
*/
|
||||
|
||||
import type { CustomTool, CustomToolFactory } from "@mariozechner/pi-coding-agent";
|
||||
import type { CustomTool, CustomToolFactory } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
interface QuestionDetails {
|
||||
question: string;
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
import * as fs from "node:fs";
|
||||
import * as os from "node:os";
|
||||
import * as path from "node:path";
|
||||
import type { AgentToolResult } from "@mariozechner/pi-agent-core";
|
||||
import type { Message } from "@mariozechner/pi-ai";
|
||||
import type { CustomTool, CustomToolAPI, CustomToolFactory } from "@mariozechner/pi-coding-agent";
|
||||
import type { AgentToolResult } from "@oh-my-pi/pi-agent-core";
|
||||
import type { Message } from "@oh-my-pi/pi-ai";
|
||||
import type { CustomTool, CustomToolAPI, CustomToolFactory } from "@oh-my-pi/pi-coding-agent";
|
||||
import { type AgentConfig, type AgentScope, discoverAgents, formatAgentList } from "./agents.js";
|
||||
|
||||
const MAX_PARALLEL_TASKS = 8;
|
||||
@@ -755,7 +755,10 @@ const factory: CustomToolFactory = (pi) => {
|
||||
|
||||
if (expanded) {
|
||||
const container = new Container();
|
||||
let header = `${icon} ${theme.fg("toolTitle", theme.bold(r.agent))}${theme.fg("muted", ` (${r.agentSource})`)}`;
|
||||
let header = `${icon} ${theme.fg("toolTitle", theme.bold(r.agent))}${theme.fg(
|
||||
"muted",
|
||||
` (${r.agentSource})`,
|
||||
)}`;
|
||||
if (isError && r.stopReason) header += ` ${theme.fg("error", `[${r.stopReason}]`)}`;
|
||||
container.addChild(new Text(header, 0, 0));
|
||||
if (isError && r.errorMessage)
|
||||
|
||||
@@ -13,7 +13,7 @@ import type {
|
||||
CustomToolContext,
|
||||
CustomToolFactory,
|
||||
CustomToolSessionEvent,
|
||||
} from "@mariozechner/pi-coding-agent";
|
||||
} from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
interface Todo {
|
||||
id: number;
|
||||
@@ -188,10 +188,7 @@ const factory: CustomToolFactory = (pi) => {
|
||||
case "add": {
|
||||
const added = todoList[todoList.length - 1];
|
||||
return new Text(
|
||||
theme.fg("success", "✓ Added ") +
|
||||
theme.fg("accent", `#${added.id}`) +
|
||||
" " +
|
||||
theme.fg("muted", added.text),
|
||||
`${theme.fg("success", "✓ Added ") + theme.fg("accent", `#${added.id}`)} ${theme.fg("muted", added.text)}`,
|
||||
0,
|
||||
0,
|
||||
);
|
||||
|
||||
@@ -14,43 +14,43 @@ cp permission-gate.ts ~/.pi/agent/hooks/
|
||||
|
||||
## Examples
|
||||
|
||||
| Hook | Description |
|
||||
|------|-------------|
|
||||
| `permission-gate.ts` | Prompts for confirmation before dangerous bash commands (rm -rf, sudo, etc.) |
|
||||
| `git-checkpoint.ts` | Creates git stash checkpoints at each turn for code restoration on branch |
|
||||
| `protected-paths.ts` | Blocks writes to protected paths (.env, .git/, node_modules/) |
|
||||
| `file-trigger.ts` | Watches a trigger file and injects contents into conversation |
|
||||
| `confirm-destructive.ts` | Confirms before destructive session actions (clear, switch, branch) |
|
||||
| `dirty-repo-guard.ts` | Prevents session changes with uncommitted git changes |
|
||||
| `auto-commit-on-exit.ts` | Auto-commits on exit using last assistant message for commit message |
|
||||
| `custom-compaction.ts` | Custom compaction that summarizes entire conversation |
|
||||
| `qna.ts` | Extracts questions from last response into editor via `ctx.ui.setEditorText()` |
|
||||
| `snake.ts` | Snake game with custom UI, keyboard handling, and session persistence |
|
||||
| `status-line.ts` | Shows turn progress in footer via `ctx.ui.setStatus()` with themed colors |
|
||||
| `handoff.ts` | Transfer context to a new focused session via `/handoff <goal>` |
|
||||
| Hook | Description |
|
||||
| ------------------------ | ------------------------------------------------------------------------------ |
|
||||
| `permission-gate.ts` | Prompts for confirmation before dangerous bash commands (rm -rf, sudo, etc.) |
|
||||
| `git-checkpoint.ts` | Creates git stash checkpoints at each turn for code restoration on branch |
|
||||
| `protected-paths.ts` | Blocks writes to protected paths (.env, .git/, node_modules/) |
|
||||
| `file-trigger.ts` | Watches a trigger file and injects contents into conversation |
|
||||
| `confirm-destructive.ts` | Confirms before destructive session actions (clear, switch, branch) |
|
||||
| `dirty-repo-guard.ts` | Prevents session changes with uncommitted git changes |
|
||||
| `auto-commit-on-exit.ts` | Auto-commits on exit using last assistant message for commit message |
|
||||
| `custom-compaction.ts` | Custom compaction that summarizes entire conversation |
|
||||
| `qna.ts` | Extracts questions from last response into editor via `ctx.ui.setEditorText()` |
|
||||
| `snake.ts` | Snake game with custom UI, keyboard handling, and session persistence |
|
||||
| `status-line.ts` | Shows turn progress in footer via `ctx.ui.setStatus()` with themed colors |
|
||||
| `handoff.ts` | Transfer context to a new focused session via `/handoff <goal>` |
|
||||
|
||||
## Writing Hooks
|
||||
|
||||
See [docs/hooks.md](../../docs/hooks.md) for full documentation.
|
||||
|
||||
```typescript
|
||||
import type { HookAPI } from "@mariozechner/pi-coding-agent/hooks";
|
||||
import type { HookAPI } from "@oh-my-pi/pi-coding-agent/hooks";
|
||||
|
||||
export default function (pi: HookAPI) {
|
||||
// Subscribe to events
|
||||
pi.on("tool_call", async (event, ctx) => {
|
||||
if (event.toolName === "bash" && event.input.command?.includes("rm -rf")) {
|
||||
const ok = await ctx.ui.confirm("Dangerous!", "Allow rm -rf?");
|
||||
if (!ok) return { block: true, reason: "Blocked by user" };
|
||||
}
|
||||
});
|
||||
// Subscribe to events
|
||||
pi.on("tool_call", async (event, ctx) => {
|
||||
if (event.toolName === "bash" && event.input.command?.includes("rm -rf")) {
|
||||
const ok = await ctx.ui.confirm("Dangerous!", "Allow rm -rf?");
|
||||
if (!ok) return { block: true, reason: "Blocked by user" };
|
||||
}
|
||||
});
|
||||
|
||||
// Register custom commands
|
||||
pi.registerCommand("hello", {
|
||||
description: "Say hello",
|
||||
handler: async (args, ctx) => {
|
||||
ctx.ui.notify("Hello!", "info");
|
||||
},
|
||||
});
|
||||
// Register custom commands
|
||||
pi.registerCommand("hello", {
|
||||
description: "Say hello",
|
||||
handler: async (args, ctx) => {
|
||||
ctx.ui.notify("Hello!", "info");
|
||||
},
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Uses the last assistant message to generate a commit message.
|
||||
*/
|
||||
|
||||
import type { HookAPI } from "@mariozechner/pi-coding-agent";
|
||||
import type { HookAPI } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
export default function (pi: HookAPI) {
|
||||
pi.on("session_shutdown", async (_event, ctx) => {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Demonstrates how to cancel session events using the before_* events.
|
||||
*/
|
||||
|
||||
import type { HookAPI, SessionBeforeSwitchEvent, SessionMessageEntry } from "@mariozechner/pi-coding-agent";
|
||||
import type { HookAPI, SessionBeforeSwitchEvent, SessionMessageEntry } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
export default function (pi: HookAPI) {
|
||||
pi.on("session_before_switch", async (event: SessionBeforeSwitchEvent, ctx) => {
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
* pi --hook examples/hooks/custom-compaction.ts
|
||||
*/
|
||||
|
||||
import { complete, getModel } from "@mariozechner/pi-ai";
|
||||
import type { HookAPI } from "@mariozechner/pi-coding-agent";
|
||||
import { convertToLlm, serializeConversation } from "@mariozechner/pi-coding-agent";
|
||||
import { complete, getModel } from "@oh-my-pi/pi-ai";
|
||||
import type { HookAPI } from "@oh-my-pi/pi-coding-agent";
|
||||
import { convertToLlm, serializeConversation } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
export default function (pi: HookAPI) {
|
||||
pi.on("session_before_compact", async (event, ctx) => {
|
||||
@@ -42,7 +42,9 @@ export default function (pi: HookAPI) {
|
||||
const allMessages = [...messagesToSummarize, ...turnPrefixMessages];
|
||||
|
||||
ctx.ui.notify(
|
||||
`Custom compaction: summarizing ${allMessages.length} messages (${tokensBefore.toLocaleString()} tokens) with ${model.id}...`,
|
||||
`Custom compaction: summarizing ${allMessages.length} messages (${tokensBefore.toLocaleString()} tokens) with ${
|
||||
model.id
|
||||
}...`,
|
||||
"info",
|
||||
);
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Useful to ensure work is committed before switching context.
|
||||
*/
|
||||
|
||||
import type { HookAPI, HookContext } from "@mariozechner/pi-coding-agent";
|
||||
import type { HookAPI, HookContext } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
async function checkDirtyRepo(pi: HookAPI, ctx: HookContext, action: string): Promise<{ cancel: boolean } | undefined> {
|
||||
// Check for uncommitted changes
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*/
|
||||
|
||||
import * as fs from "node:fs";
|
||||
import type { HookAPI } from "@mariozechner/pi-coding-agent";
|
||||
import type { HookAPI } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
export default function (pi: HookAPI) {
|
||||
pi.on("session_start", async (_event, ctx) => {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* When branching, offers to restore code to that point in history.
|
||||
*/
|
||||
|
||||
import type { HookAPI } from "@mariozechner/pi-coding-agent";
|
||||
import type { HookAPI } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
export default function (pi: HookAPI) {
|
||||
const checkpoints = new Map<string, string>();
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
* The generated prompt appears as a draft in the editor for review/editing.
|
||||
*/
|
||||
|
||||
import { complete, type Message } from "@mariozechner/pi-ai";
|
||||
import type { HookAPI, SessionEntry } from "@mariozechner/pi-coding-agent";
|
||||
import { BorderedLoader, convertToLlm, serializeConversation } from "@mariozechner/pi-coding-agent";
|
||||
import { complete, type Message } from "@oh-my-pi/pi-ai";
|
||||
import type { HookAPI, SessionEntry } from "@oh-my-pi/pi-coding-agent";
|
||||
import { BorderedLoader, convertToLlm, serializeConversation } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
const SYSTEM_PROMPT = `You are a context transfer assistant. Given a conversation history and the user's goal for a new thread, generate a focused prompt that:
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Patterns checked: rm -rf, sudo, chmod/chown 777
|
||||
*/
|
||||
|
||||
import type { HookAPI } from "@mariozechner/pi-coding-agent";
|
||||
import type { HookAPI } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
export default function (pi: HookAPI) {
|
||||
const dangerousPatterns = [/\brm\s+(-rf?|--recursive)/i, /\bsudo\b/i, /\b(chmod|chown)\b.*777/i];
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Useful for preventing accidental modifications to sensitive files.
|
||||
*/
|
||||
|
||||
import type { HookAPI } from "@mariozechner/pi-coding-agent";
|
||||
import type { HookAPI } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
export default function (pi: HookAPI) {
|
||||
const protectedPaths = [".env", ".git/", "node_modules/"];
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
* 3. Loads the result into the editor for user to fill in answers
|
||||
*/
|
||||
|
||||
import { complete, type UserMessage } from "@mariozechner/pi-ai";
|
||||
import type { HookAPI } from "@mariozechner/pi-coding-agent";
|
||||
import { BorderedLoader } from "@mariozechner/pi-coding-agent";
|
||||
import { complete, type UserMessage } from "@oh-my-pi/pi-ai";
|
||||
import type { HookAPI } from "@oh-my-pi/pi-coding-agent";
|
||||
import { BorderedLoader } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
const SYSTEM_PROMPT = `You are a question extractor. Given text from a conversation, extract any questions that need answering and format them for the user to fill in.
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
* Snake game hook - play snake with /snake command
|
||||
*/
|
||||
|
||||
import type { HookAPI } from "@mariozechner/pi-coding-agent";
|
||||
import { isArrowDown, isArrowLeft, isArrowRight, isArrowUp, isEscape, visibleWidth } from "@mariozechner/pi-tui";
|
||||
import type { HookAPI } from "@oh-my-pi/pi-coding-agent";
|
||||
import { isArrowDown, isArrowLeft, isArrowRight, isArrowUp, isEscape, visibleWidth } from "@oh-my-pi/pi-tui";
|
||||
|
||||
const GAME_WIDTH = 40;
|
||||
const GAME_HEIGHT = 15;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Shows turn progress with themed colors.
|
||||
*/
|
||||
|
||||
import type { HookAPI } from "@mariozechner/pi-coding-agent";
|
||||
import type { HookAPI } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
export default function (pi: HookAPI) {
|
||||
let turnCount = 0;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* from cwd and ~/.pi/agent. Model chosen from settings or first available.
|
||||
*/
|
||||
|
||||
import { createAgentSession } from "@mariozechner/pi-coding-agent";
|
||||
import { createAgentSession } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
const { session } = await createAgentSession();
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
* Shows how to select a specific model and thinking level.
|
||||
*/
|
||||
|
||||
import { getModel } from "@mariozechner/pi-ai";
|
||||
import { createAgentSession, discoverAuthStorage, discoverModels } from "@mariozechner/pi-coding-agent";
|
||||
import { getModel } from "@oh-my-pi/pi-ai";
|
||||
import { createAgentSession, discoverAuthStorage, discoverModels } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
// Set up auth storage and model registry
|
||||
const authStorage = discoverAuthStorage();
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Shows how to replace or modify the default system prompt.
|
||||
*/
|
||||
|
||||
import { createAgentSession, SessionManager } from "@mariozechner/pi-coding-agent";
|
||||
import { createAgentSession, SessionManager } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
// Option 1: Replace prompt entirely
|
||||
const { session: session1 } = await createAgentSession({
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Discover, filter, merge, or replace them.
|
||||
*/
|
||||
|
||||
import { createAgentSession, discoverSkills, SessionManager, type Skill } from "@mariozechner/pi-coding-agent";
|
||||
import { createAgentSession, discoverSkills, SessionManager, type Skill } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
// Discover all skills from cwd/.pi/skills, ~/.pi/agent/skills, etc.
|
||||
const allSkills = discoverSkills();
|
||||
|
||||
@@ -20,7 +20,7 @@ import {
|
||||
readOnlyTools, // read, grep, find, ls - uses process.cwd()
|
||||
readTool,
|
||||
SessionManager,
|
||||
} from "@mariozechner/pi-coding-agent";
|
||||
} from "@oh-my-pi/pi-coding-agent";
|
||||
import { Type } from "@sinclair/typebox";
|
||||
|
||||
// Read-only mode (no edit/write) - uses process.cwd()
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Hooks intercept agent events for logging, blocking, or modification.
|
||||
*/
|
||||
|
||||
import { createAgentSession, type HookFactory, SessionManager } from "@mariozechner/pi-coding-agent";
|
||||
import { createAgentSession, type HookFactory, SessionManager } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
// Logging hook
|
||||
const loggingHook: HookFactory = (api) => {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Context files provide project-specific instructions loaded into the system prompt.
|
||||
*/
|
||||
|
||||
import { createAgentSession, discoverContextFiles, SessionManager } from "@mariozechner/pi-coding-agent";
|
||||
import { createAgentSession, discoverContextFiles, SessionManager } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
// Discover AGENTS.md files walking up from cwd
|
||||
const discovered = discoverContextFiles();
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
discoverSlashCommands,
|
||||
type FileSlashCommand,
|
||||
SessionManager,
|
||||
} from "@mariozechner/pi-coding-agent";
|
||||
} from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
// Discover commands from cwd/.pi/commands/ and ~/.pi/agent/commands/
|
||||
const discovered = discoverSlashCommands();
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
discoverModels,
|
||||
ModelRegistry,
|
||||
SessionManager,
|
||||
} from "@mariozechner/pi-coding-agent";
|
||||
} from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
// Default: discoverAuthStorage() uses ~/.pi/agent/auth.json
|
||||
// discoverModels() loads built-in + custom models from ~/.pi/agent/models.json
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Override settings using SettingsManager.
|
||||
*/
|
||||
|
||||
import { createAgentSession, loadSettings, SessionManager, SettingsManager } from "@mariozechner/pi-coding-agent";
|
||||
import { createAgentSession, loadSettings, SessionManager, SettingsManager } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
// Load current settings (merged global + project)
|
||||
const settings = loadSettings();
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Control session persistence: in-memory, new file, continue, or open specific.
|
||||
*/
|
||||
|
||||
import { createAgentSession, SessionManager } from "@mariozechner/pi-coding-agent";
|
||||
import { createAgentSession, SessionManager } from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
// In-memory (no persistence)
|
||||
const { session: inMemory } = await createAgentSession({
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* paths relative to your cwd.
|
||||
*/
|
||||
|
||||
import { getModel } from "@mariozechner/pi-ai";
|
||||
import { getModel } from "@oh-my-pi/pi-ai";
|
||||
import {
|
||||
AuthStorage,
|
||||
type CustomTool,
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
ModelRegistry,
|
||||
SessionManager,
|
||||
SettingsManager,
|
||||
} from "@mariozechner/pi-coding-agent";
|
||||
} from "@oh-my-pi/pi-coding-agent";
|
||||
import { Type } from "@sinclair/typebox";
|
||||
|
||||
// Custom auth storage location
|
||||
|
||||
@@ -4,20 +4,20 @@ Programmatic usage of pi-coding-agent via `createAgentSession()`.
|
||||
|
||||
## Examples
|
||||
|
||||
| File | Description |
|
||||
|------|-------------|
|
||||
| `01-minimal.ts` | Simplest usage with all defaults |
|
||||
| `02-custom-model.ts` | Select model and thinking level |
|
||||
| `03-custom-prompt.ts` | Replace or modify system prompt |
|
||||
| `04-skills.ts` | Discover, filter, or replace skills |
|
||||
| `05-tools.ts` | Built-in tools, custom tools |
|
||||
| `06-hooks.ts` | Logging, blocking, result modification |
|
||||
| `07-context-files.ts` | AGENTS.md context files |
|
||||
| `08-slash-commands.ts` | File-based slash commands |
|
||||
| `09-api-keys-and-oauth.ts` | API key resolution, OAuth config |
|
||||
| `10-settings.ts` | Override compaction, retry, terminal settings |
|
||||
| `11-sessions.ts` | In-memory, persistent, continue, list sessions |
|
||||
| `12-full-control.ts` | Replace everything, no discovery |
|
||||
| File | Description |
|
||||
| -------------------------- | ---------------------------------------------- |
|
||||
| `01-minimal.ts` | Simplest usage with all defaults |
|
||||
| `02-custom-model.ts` | Select model and thinking level |
|
||||
| `03-custom-prompt.ts` | Replace or modify system prompt |
|
||||
| `04-skills.ts` | Discover, filter, or replace skills |
|
||||
| `05-tools.ts` | Built-in tools, custom tools |
|
||||
| `06-hooks.ts` | Logging, blocking, result modification |
|
||||
| `07-context-files.ts` | AGENTS.md context files |
|
||||
| `08-slash-commands.ts` | File-based slash commands |
|
||||
| `09-api-keys-and-oauth.ts` | API key resolution, OAuth config |
|
||||
| `10-settings.ts` | Override compaction, retry, terminal settings |
|
||||
| `11-sessions.ts` | In-memory, persistent, continue, list sessions |
|
||||
| `12-full-control.ts` | Replace everything, no discovery |
|
||||
|
||||
## Running
|
||||
|
||||
@@ -29,25 +29,28 @@ npx tsx examples/sdk/01-minimal.ts
|
||||
## Quick Reference
|
||||
|
||||
```typescript
|
||||
import { getModel } from "@mariozechner/pi-ai";
|
||||
import { getModel } from "@oh-my-pi/pi-ai";
|
||||
import {
|
||||
AuthStorage,
|
||||
createAgentSession,
|
||||
discoverAuthStorage,
|
||||
discoverModels,
|
||||
discoverSkills,
|
||||
discoverHooks,
|
||||
discoverCustomTools,
|
||||
discoverContextFiles,
|
||||
discoverSlashCommands,
|
||||
loadSettings,
|
||||
buildSystemPrompt,
|
||||
ModelRegistry,
|
||||
SessionManager,
|
||||
codingTools,
|
||||
readOnlyTools,
|
||||
readTool, bashTool, editTool, writeTool,
|
||||
} from "@mariozechner/pi-coding-agent";
|
||||
AuthStorage,
|
||||
createAgentSession,
|
||||
discoverAuthStorage,
|
||||
discoverModels,
|
||||
discoverSkills,
|
||||
discoverHooks,
|
||||
discoverCustomTools,
|
||||
discoverContextFiles,
|
||||
discoverSlashCommands,
|
||||
loadSettings,
|
||||
buildSystemPrompt,
|
||||
ModelRegistry,
|
||||
SessionManager,
|
||||
codingTools,
|
||||
readOnlyTools,
|
||||
readTool,
|
||||
bashTool,
|
||||
editTool,
|
||||
writeTool,
|
||||
} from "@oh-my-pi/pi-coding-agent";
|
||||
|
||||
// Auth and models setup
|
||||
const authStorage = discoverAuthStorage();
|
||||
@@ -62,9 +65,9 @@ const { session } = await createAgentSession({ model, thinkingLevel: "high", aut
|
||||
|
||||
// Modify prompt
|
||||
const { session } = await createAgentSession({
|
||||
systemPrompt: (defaultPrompt) => defaultPrompt + "\n\nBe concise.",
|
||||
authStorage,
|
||||
modelRegistry,
|
||||
systemPrompt: (defaultPrompt) => defaultPrompt + "\n\nBe concise.",
|
||||
authStorage,
|
||||
modelRegistry,
|
||||
});
|
||||
|
||||
// Read-only
|
||||
@@ -72,9 +75,9 @@ const { session } = await createAgentSession({ tools: readOnlyTools, authStorage
|
||||
|
||||
// In-memory
|
||||
const { session } = await createAgentSession({
|
||||
sessionManager: SessionManager.inMemory(),
|
||||
authStorage,
|
||||
modelRegistry,
|
||||
sessionManager: SessionManager.inMemory(),
|
||||
authStorage,
|
||||
modelRegistry,
|
||||
});
|
||||
|
||||
// Full control
|
||||
@@ -83,69 +86,69 @@ customAuth.setRuntimeApiKey("anthropic", process.env.MY_KEY!);
|
||||
const customRegistry = new ModelRegistry(customAuth);
|
||||
|
||||
const { session } = await createAgentSession({
|
||||
model,
|
||||
authStorage: customAuth,
|
||||
modelRegistry: customRegistry,
|
||||
systemPrompt: "You are helpful.",
|
||||
tools: [readTool, bashTool],
|
||||
customTools: [{ tool: myTool }],
|
||||
hooks: [{ factory: myHook }],
|
||||
skills: [],
|
||||
contextFiles: [],
|
||||
slashCommands: [],
|
||||
sessionManager: SessionManager.inMemory(),
|
||||
model,
|
||||
authStorage: customAuth,
|
||||
modelRegistry: customRegistry,
|
||||
systemPrompt: "You are helpful.",
|
||||
tools: [readTool, bashTool],
|
||||
customTools: [{ tool: myTool }],
|
||||
hooks: [{ factory: myHook }],
|
||||
skills: [],
|
||||
contextFiles: [],
|
||||
slashCommands: [],
|
||||
sessionManager: SessionManager.inMemory(),
|
||||
});
|
||||
|
||||
// Run prompts
|
||||
session.subscribe((event) => {
|
||||
if (event.type === "message_update" && event.assistantMessageEvent.type === "text_delta") {
|
||||
process.stdout.write(event.assistantMessageEvent.delta);
|
||||
}
|
||||
if (event.type === "message_update" && event.assistantMessageEvent.type === "text_delta") {
|
||||
process.stdout.write(event.assistantMessageEvent.delta);
|
||||
}
|
||||
});
|
||||
await session.prompt("Hello");
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
| Option | Default | Description |
|
||||
|--------|---------|-------------|
|
||||
| `authStorage` | `discoverAuthStorage()` | Credential storage |
|
||||
| `modelRegistry` | `discoverModels(authStorage)` | Model registry |
|
||||
| `cwd` | `process.cwd()` | Working directory |
|
||||
| `agentDir` | `~/.pi/agent` | Config directory |
|
||||
| `model` | From settings/first available | Model to use |
|
||||
| `thinkingLevel` | From settings/"off" | off, low, medium, high |
|
||||
| `systemPrompt` | Discovered | String or `(default) => modified` |
|
||||
| `tools` | `codingTools` | Built-in tools |
|
||||
| `customTools` | Discovered | Replaces discovery |
|
||||
| `additionalCustomToolPaths` | `[]` | Merge with discovery |
|
||||
| `hooks` | Discovered | Replaces discovery |
|
||||
| `additionalHookPaths` | `[]` | Merge with discovery |
|
||||
| `skills` | Discovered | Skills for prompt |
|
||||
| `contextFiles` | Discovered | AGENTS.md files |
|
||||
| `slashCommands` | Discovered | File commands |
|
||||
| `sessionManager` | `SessionManager.create(cwd)` | Persistence |
|
||||
| `settingsManager` | From agentDir | Settings overrides |
|
||||
| Option | Default | Description |
|
||||
| --------------------------- | ----------------------------- | --------------------------------- |
|
||||
| `authStorage` | `discoverAuthStorage()` | Credential storage |
|
||||
| `modelRegistry` | `discoverModels(authStorage)` | Model registry |
|
||||
| `cwd` | `process.cwd()` | Working directory |
|
||||
| `agentDir` | `~/.pi/agent` | Config directory |
|
||||
| `model` | From settings/first available | Model to use |
|
||||
| `thinkingLevel` | From settings/"off" | off, low, medium, high |
|
||||
| `systemPrompt` | Discovered | String or `(default) => modified` |
|
||||
| `tools` | `codingTools` | Built-in tools |
|
||||
| `customTools` | Discovered | Replaces discovery |
|
||||
| `additionalCustomToolPaths` | `[]` | Merge with discovery |
|
||||
| `hooks` | Discovered | Replaces discovery |
|
||||
| `additionalHookPaths` | `[]` | Merge with discovery |
|
||||
| `skills` | Discovered | Skills for prompt |
|
||||
| `contextFiles` | Discovered | AGENTS.md files |
|
||||
| `slashCommands` | Discovered | File commands |
|
||||
| `sessionManager` | `SessionManager.create(cwd)` | Persistence |
|
||||
| `settingsManager` | From agentDir | Settings overrides |
|
||||
|
||||
## Events
|
||||
|
||||
```typescript
|
||||
session.subscribe((event) => {
|
||||
switch (event.type) {
|
||||
case "message_update":
|
||||
if (event.assistantMessageEvent.type === "text_delta") {
|
||||
process.stdout.write(event.assistantMessageEvent.delta);
|
||||
}
|
||||
break;
|
||||
case "tool_execution_start":
|
||||
console.log(`Tool: ${event.toolName}`);
|
||||
break;
|
||||
case "tool_execution_end":
|
||||
console.log(`Result: ${event.result}`);
|
||||
break;
|
||||
case "agent_end":
|
||||
console.log("Done");
|
||||
break;
|
||||
}
|
||||
switch (event.type) {
|
||||
case "message_update":
|
||||
if (event.assistantMessageEvent.type === "text_delta") {
|
||||
process.stdout.write(event.assistantMessageEvent.delta);
|
||||
}
|
||||
break;
|
||||
case "tool_execution_start":
|
||||
console.log(`Tool: ${event.toolName}`);
|
||||
break;
|
||||
case "tool_execution_end":
|
||||
console.log(`Result: ${event.result}`);
|
||||
break;
|
||||
case "agent_end":
|
||||
console.log("Done");
|
||||
break;
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user