chore: drop non-code junk (pi-mono-reference, runtime state, root duplicates)
Remove files that should never have been tracked: - pi-mono-reference/: 688-file copy of an upstream monorepo, zero imports, used only as offline human reference - build/electron-builder.runtime.json: environment-specific build artifact with hardcoded local paths - state/cancel-signal-state.json: runtime state written by the app - prompt.txt, logo.svg (root): exact duplicates of the canonical copies under .planning/archive/ and assets/ Add state/ to .gitignore so future runtime state stays out.
This commit is contained in:
1 parent
34ca5b77f1
commit
1f7230fe87
691 files changed
+3
-190434
No files matched your search
@@ -1,22 +0,0 @@
|
||||
/**
|
||||
* Minimal SDK Usage
|
||||
*
|
||||
* Uses all defaults: discovers skills, extensions, tools, context files
|
||||
* from cwd and ~/.pi/agent. Model chosen from settings or first available.
|
||||
*/
|
||||
|
||||
import { createAgentSession } from "@mariozechner/pi-coding-agent";
|
||||
|
||||
const { session } = await createAgentSession();
|
||||
|
||||
session.subscribe((event) => {
|
||||
if (event.type === "message_update" && event.assistantMessageEvent.type === "text_delta") {
|
||||
process.stdout.write(event.assistantMessageEvent.delta);
|
||||
}
|
||||
});
|
||||
|
||||
await session.prompt("What files are in the current directory?");
|
||||
session.state.messages.forEach((msg) => {
|
||||
console.log(msg);
|
||||
});
|
||||
console.log();
|
||||
@@ -1,49 +0,0 @@
|
||||
/**
|
||||
* Custom Model Selection
|
||||
*
|
||||
* Shows how to select a specific model and thinking level.
|
||||
*/
|
||||
|
||||
import { getModel } from "@mariozechner/pi-ai";
|
||||
import { AuthStorage, createAgentSession, ModelRegistry } from "@mariozechner/pi-coding-agent";
|
||||
|
||||
// Set up auth storage and model registry
|
||||
const authStorage = AuthStorage.create();
|
||||
const modelRegistry = ModelRegistry.create(authStorage);
|
||||
|
||||
// Option 1: Find a specific built-in model by provider/id
|
||||
const opus = getModel("anthropic", "claude-opus-4-5");
|
||||
if (opus) {
|
||||
console.log(`Found model: ${opus.provider}/${opus.id}`);
|
||||
}
|
||||
|
||||
// Option 2: Find model via registry (includes custom models from models.json)
|
||||
const customModel = modelRegistry.find("my-provider", "my-model");
|
||||
if (customModel) {
|
||||
console.log(`Found custom model: ${customModel.provider}/${customModel.id}`);
|
||||
}
|
||||
|
||||
// Option 3: Pick from available models (have valid API keys)
|
||||
const available = await modelRegistry.getAvailable();
|
||||
console.log(
|
||||
"Available models:",
|
||||
available.map((m) => `${m.provider}/${m.id}`),
|
||||
);
|
||||
|
||||
if (available.length > 0) {
|
||||
const { session } = await createAgentSession({
|
||||
model: available[0],
|
||||
thinkingLevel: "medium", // off, low, medium, high
|
||||
authStorage,
|
||||
modelRegistry,
|
||||
});
|
||||
|
||||
session.subscribe((event) => {
|
||||
if (event.type === "message_update" && event.assistantMessageEvent.type === "text_delta") {
|
||||
process.stdout.write(event.assistantMessageEvent.delta);
|
||||
}
|
||||
});
|
||||
|
||||
await session.prompt("Say hello in one sentence.");
|
||||
console.log();
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/**
|
||||
* Custom System Prompt
|
||||
*
|
||||
* Shows how to replace or modify the default system prompt.
|
||||
*/
|
||||
|
||||
import { createAgentSession, DefaultResourceLoader, SessionManager } from "@mariozechner/pi-coding-agent";
|
||||
|
||||
// Option 1: Replace prompt entirely
|
||||
const loader1 = new DefaultResourceLoader({
|
||||
systemPromptOverride: () => `You are a helpful assistant that speaks like a pirate.
|
||||
Always end responses with "Arrr!"`,
|
||||
// Needed to avoid DefaultResourceLoader appending APPEND_SYSTEM.md from ~/.pi/agent or <cwd>/.pi.
|
||||
appendSystemPromptOverride: () => [],
|
||||
});
|
||||
await loader1.reload();
|
||||
|
||||
const { session: session1 } = await createAgentSession({
|
||||
resourceLoader: loader1,
|
||||
sessionManager: SessionManager.inMemory(),
|
||||
});
|
||||
|
||||
session1.subscribe((event) => {
|
||||
if (event.type === "message_update" && event.assistantMessageEvent.type === "text_delta") {
|
||||
process.stdout.write(event.assistantMessageEvent.delta);
|
||||
}
|
||||
});
|
||||
|
||||
console.log("=== Replace prompt ===");
|
||||
await session1.prompt("What is 2 + 2?");
|
||||
console.log("\n");
|
||||
|
||||
// Option 2: Append instructions to the default prompt
|
||||
const loader2 = new DefaultResourceLoader({
|
||||
appendSystemPromptOverride: (base) => [
|
||||
...base,
|
||||
"## Additional Instructions\n- Always be concise\n- Use bullet points when listing things",
|
||||
],
|
||||
});
|
||||
await loader2.reload();
|
||||
|
||||
const { session: session2 } = await createAgentSession({
|
||||
resourceLoader: loader2,
|
||||
sessionManager: SessionManager.inMemory(),
|
||||
});
|
||||
|
||||
session2.subscribe((event) => {
|
||||
if (event.type === "message_update" && event.assistantMessageEvent.type === "text_delta") {
|
||||
process.stdout.write(event.assistantMessageEvent.delta);
|
||||
}
|
||||
});
|
||||
|
||||
console.log("=== Modify prompt ===");
|
||||
await session2.prompt("List 3 benefits of TypeScript.");
|
||||
console.log();
|
||||
@@ -1,52 +0,0 @@
|
||||
/**
|
||||
* Skills Configuration
|
||||
*
|
||||
* Skills provide specialized instructions loaded into the system prompt.
|
||||
* Discover, filter, merge, or replace them.
|
||||
*/
|
||||
|
||||
import {
|
||||
createAgentSession,
|
||||
createSyntheticSourceInfo,
|
||||
DefaultResourceLoader,
|
||||
SessionManager,
|
||||
type Skill,
|
||||
} from "@mariozechner/pi-coding-agent";
|
||||
|
||||
// Or define custom skills inline
|
||||
const customSkill: Skill = {
|
||||
name: "my-skill",
|
||||
description: "Custom project instructions",
|
||||
filePath: "/virtual/SKILL.md",
|
||||
baseDir: "/virtual",
|
||||
sourceInfo: createSyntheticSourceInfo("/virtual/SKILL.md", { source: "sdk" }),
|
||||
disableModelInvocation: false,
|
||||
};
|
||||
|
||||
const loader = new DefaultResourceLoader({
|
||||
skillsOverride: (current) => {
|
||||
const filteredSkills = current.skills.filter((s) => s.name.includes("browser") || s.name.includes("search"));
|
||||
return {
|
||||
skills: [...filteredSkills, customSkill],
|
||||
diagnostics: current.diagnostics,
|
||||
};
|
||||
},
|
||||
});
|
||||
await loader.reload();
|
||||
|
||||
// Discover all skills from cwd/.pi/skills, ~/.pi/agent/skills, etc.
|
||||
const { skills: allSkills, diagnostics } = loader.getSkills();
|
||||
console.log(
|
||||
"Discovered skills:",
|
||||
allSkills.map((s) => s.name),
|
||||
);
|
||||
if (diagnostics.length > 0) {
|
||||
console.log("Warnings:", diagnostics);
|
||||
}
|
||||
|
||||
await createAgentSession({
|
||||
resourceLoader: loader,
|
||||
sessionManager: SessionManager.inMemory(),
|
||||
});
|
||||
|
||||
console.log("Session created with filtered skills");
|
||||
@@ -1,56 +0,0 @@
|
||||
/**
|
||||
* Tools Configuration
|
||||
*
|
||||
* Use built-in tool sets or individual tools.
|
||||
*
|
||||
* IMPORTANT: When using a custom `cwd`, you must use the tool factory functions
|
||||
* (createCodingTools, createReadOnlyTools, createReadTool, etc.) to ensure
|
||||
* tools resolve paths relative to your cwd, not process.cwd().
|
||||
*
|
||||
* For custom tools, see 06-extensions.ts - custom tools are now registered
|
||||
* via the extensions system using pi.registerTool().
|
||||
*/
|
||||
|
||||
import {
|
||||
bashTool,
|
||||
createAgentSession,
|
||||
createBashTool,
|
||||
createCodingTools,
|
||||
createGrepTool,
|
||||
createReadTool,
|
||||
grepTool,
|
||||
readOnlyTools,
|
||||
readTool,
|
||||
SessionManager,
|
||||
} from "@mariozechner/pi-coding-agent";
|
||||
|
||||
// Read-only mode (no edit/write) - uses process.cwd()
|
||||
await createAgentSession({
|
||||
tools: readOnlyTools,
|
||||
sessionManager: SessionManager.inMemory(),
|
||||
});
|
||||
console.log("Read-only session created");
|
||||
|
||||
// Custom tool selection - uses process.cwd()
|
||||
await createAgentSession({
|
||||
tools: [readTool, bashTool, grepTool],
|
||||
sessionManager: SessionManager.inMemory(),
|
||||
});
|
||||
console.log("Custom tools session created");
|
||||
|
||||
// With custom cwd - MUST use factory functions!
|
||||
const customCwd = "/path/to/project";
|
||||
await createAgentSession({
|
||||
cwd: customCwd,
|
||||
tools: createCodingTools(customCwd), // Tools resolve paths relative to customCwd
|
||||
sessionManager: SessionManager.inMemory(),
|
||||
});
|
||||
console.log("Custom cwd session created");
|
||||
|
||||
// Or pick specific tools for custom cwd
|
||||
await createAgentSession({
|
||||
cwd: customCwd,
|
||||
tools: [createReadTool(customCwd), createBashTool(customCwd), createGrepTool(customCwd)],
|
||||
sessionManager: SessionManager.inMemory(),
|
||||
});
|
||||
console.log("Specific tools with custom cwd session created");
|
||||
@@ -1,88 +0,0 @@
|
||||
/**
|
||||
* Extensions Configuration
|
||||
*
|
||||
* Extensions intercept agent events and can register custom tools.
|
||||
* They provide a unified system for extensions, custom tools, commands, and more.
|
||||
*
|
||||
* By default, extension files are discovered from:
|
||||
* - ~/.pi/agent/extensions/
|
||||
* - <cwd>/.pi/extensions/
|
||||
* - Paths specified in settings.json "extensions" array
|
||||
*
|
||||
* An extension is a TypeScript file that exports a default function:
|
||||
* export default function (pi: ExtensionAPI) { ... }
|
||||
*/
|
||||
|
||||
import { createAgentSession, DefaultResourceLoader, SessionManager } from "@mariozechner/pi-coding-agent";
|
||||
|
||||
// Extensions are discovered automatically from standard locations.
|
||||
// You can also add paths via settings.json or DefaultResourceLoader options.
|
||||
|
||||
const resourceLoader = new DefaultResourceLoader({
|
||||
additionalExtensionPaths: ["./my-logging-extension.ts", "./my-safety-extension.ts"],
|
||||
extensionFactories: [
|
||||
(pi) => {
|
||||
pi.on("agent_start", () => {
|
||||
console.log("[Inline Extension] Agent starting");
|
||||
});
|
||||
},
|
||||
],
|
||||
});
|
||||
await resourceLoader.reload();
|
||||
|
||||
const { session } = await createAgentSession({
|
||||
resourceLoader,
|
||||
sessionManager: SessionManager.inMemory(),
|
||||
});
|
||||
|
||||
session.subscribe((event) => {
|
||||
if (event.type === "message_update" && event.assistantMessageEvent.type === "text_delta") {
|
||||
process.stdout.write(event.assistantMessageEvent.delta);
|
||||
}
|
||||
});
|
||||
|
||||
await session.prompt("List files in the current directory.");
|
||||
console.log();
|
||||
|
||||
// Example extension file (./my-logging-extension.ts):
|
||||
/*
|
||||
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
||||
|
||||
export default function (pi: ExtensionAPI) {
|
||||
pi.on("agent_start", async () => {
|
||||
console.log("[Extension] Agent starting");
|
||||
});
|
||||
|
||||
pi.on("tool_call", async (event) => {
|
||||
console.log(\`[Extension] Tool: \${event.toolName}\`);
|
||||
// Return { block: true, reason: "..." } to block execution
|
||||
return undefined;
|
||||
});
|
||||
|
||||
pi.on("agent_end", async (event) => {
|
||||
console.log(\`[Extension] Done, \${event.messages.length} messages\`);
|
||||
});
|
||||
|
||||
// Register a custom tool
|
||||
pi.registerTool({
|
||||
name: "my_tool",
|
||||
label: "My Tool",
|
||||
description: "Does something useful",
|
||||
parameters: Type.Object({
|
||||
input: Type.String(),
|
||||
}),
|
||||
execute: async (_toolCallId, params, _signal, _onUpdate, _ctx) => ({
|
||||
content: [{ type: "text", text: \`Processed: \${params.input}\` }],
|
||||
details: {},
|
||||
}),
|
||||
});
|
||||
|
||||
// Register a command
|
||||
pi.registerCommand("mycommand", {
|
||||
description: "Do something",
|
||||
handler: async (args, ctx) => {
|
||||
ctx.ui.notify(\`Command executed with: \${args}\`);
|
||||
},
|
||||
});
|
||||
}
|
||||
*/
|
||||
@@ -1,40 +0,0 @@
|
||||
/**
|
||||
* Context Files (AGENTS.md)
|
||||
*
|
||||
* Context files provide project-specific instructions loaded into the system prompt.
|
||||
*/
|
||||
|
||||
import { createAgentSession, DefaultResourceLoader, SessionManager } from "@mariozechner/pi-coding-agent";
|
||||
|
||||
// Disable context files entirely by returning an empty list in agentsFilesOverride.
|
||||
const loader = new DefaultResourceLoader({
|
||||
agentsFilesOverride: (current) => ({
|
||||
agentsFiles: [
|
||||
...current.agentsFiles,
|
||||
{
|
||||
path: "/virtual/AGENTS.md",
|
||||
content: `# Project Guidelines
|
||||
|
||||
## Code Style
|
||||
- Use TypeScript strict mode
|
||||
- No any types
|
||||
- Prefer const over let`,
|
||||
},
|
||||
],
|
||||
}),
|
||||
});
|
||||
await loader.reload();
|
||||
|
||||
// Discover AGENTS.md files walking up from cwd
|
||||
const discovered = loader.getAgentsFiles().agentsFiles;
|
||||
console.log("Discovered context files:");
|
||||
for (const file of discovered) {
|
||||
console.log(` - ${file.path} (${file.content.length} chars)`);
|
||||
}
|
||||
|
||||
await createAgentSession({
|
||||
resourceLoader: loader,
|
||||
sessionManager: SessionManager.inMemory(),
|
||||
});
|
||||
|
||||
console.log(`Session created with ${discovered.length + 1} context files`);
|
||||
@@ -1,48 +0,0 @@
|
||||
/**
|
||||
* Prompt Templates
|
||||
*
|
||||
* File-based templates that inject content when invoked with /templatename.
|
||||
*/
|
||||
|
||||
import {
|
||||
createAgentSession,
|
||||
createSyntheticSourceInfo,
|
||||
DefaultResourceLoader,
|
||||
type PromptTemplate,
|
||||
SessionManager,
|
||||
} from "@mariozechner/pi-coding-agent";
|
||||
|
||||
// Define custom templates
|
||||
const deployTemplate: PromptTemplate = {
|
||||
name: "deploy",
|
||||
description: "Deploy the application",
|
||||
filePath: "/virtual/prompts/deploy.md",
|
||||
sourceInfo: createSyntheticSourceInfo("/virtual/prompts/deploy.md", { source: "sdk" }),
|
||||
content: `# Deploy Instructions
|
||||
|
||||
1. Build: npm run build
|
||||
2. Test: npm test
|
||||
3. Deploy: npm run deploy`,
|
||||
};
|
||||
|
||||
const loader = new DefaultResourceLoader({
|
||||
promptsOverride: (current) => ({
|
||||
prompts: [...current.prompts, deployTemplate],
|
||||
diagnostics: current.diagnostics,
|
||||
}),
|
||||
});
|
||||
await loader.reload();
|
||||
|
||||
// Discover templates from cwd/.pi/prompts/ and ~/.pi/agent/prompts/
|
||||
const discovered = loader.getPrompts().prompts;
|
||||
console.log("Discovered prompt templates:");
|
||||
for (const template of discovered) {
|
||||
console.log(` /${template.name}: ${template.description}`);
|
||||
}
|
||||
|
||||
await createAgentSession({
|
||||
resourceLoader: loader,
|
||||
sessionManager: SessionManager.inMemory(),
|
||||
});
|
||||
|
||||
console.log(`Session created with ${discovered.length + 1} prompt templates`);
|
||||
@@ -1,48 +0,0 @@
|
||||
/**
|
||||
* API Keys and OAuth
|
||||
*
|
||||
* Configure API key resolution via AuthStorage and ModelRegistry.
|
||||
*/
|
||||
|
||||
import { AuthStorage, createAgentSession, ModelRegistry, SessionManager } from "@mariozechner/pi-coding-agent";
|
||||
|
||||
// Default: AuthStorage uses ~/.pi/agent/auth.json
|
||||
// ModelRegistry loads built-in + custom models from ~/.pi/agent/models.json
|
||||
const authStorage = AuthStorage.create();
|
||||
const modelRegistry = ModelRegistry.create(authStorage);
|
||||
|
||||
await createAgentSession({
|
||||
sessionManager: SessionManager.inMemory(),
|
||||
authStorage,
|
||||
modelRegistry,
|
||||
});
|
||||
console.log("Session with default auth storage and model registry");
|
||||
|
||||
// Custom auth storage location
|
||||
const customAuthStorage = AuthStorage.create("/tmp/my-app/auth.json");
|
||||
const customModelRegistry = ModelRegistry.create(customAuthStorage, "/tmp/my-app/models.json");
|
||||
|
||||
await createAgentSession({
|
||||
sessionManager: SessionManager.inMemory(),
|
||||
authStorage: customAuthStorage,
|
||||
modelRegistry: customModelRegistry,
|
||||
});
|
||||
console.log("Session with custom auth storage location");
|
||||
|
||||
// Runtime API key override (not persisted to disk)
|
||||
authStorage.setRuntimeApiKey("anthropic", "sk-my-temp-key");
|
||||
await createAgentSession({
|
||||
sessionManager: SessionManager.inMemory(),
|
||||
authStorage,
|
||||
modelRegistry,
|
||||
});
|
||||
console.log("Session with runtime API key override");
|
||||
|
||||
// No models.json - only built-in models
|
||||
const simpleRegistry = ModelRegistry.inMemory(authStorage);
|
||||
await createAgentSession({
|
||||
sessionManager: SessionManager.inMemory(),
|
||||
authStorage,
|
||||
modelRegistry: simpleRegistry,
|
||||
});
|
||||
console.log("Session with only built-in models");
|
||||
@@ -1,51 +0,0 @@
|
||||
/**
|
||||
* Settings Configuration
|
||||
*
|
||||
* Override settings using SettingsManager.
|
||||
*/
|
||||
|
||||
import { createAgentSession, SessionManager, SettingsManager } from "@mariozechner/pi-coding-agent";
|
||||
|
||||
// Load current settings (merged global + project)
|
||||
const settingsManagerFromDisk = SettingsManager.create();
|
||||
console.log("Current settings:", JSON.stringify(settingsManagerFromDisk.getGlobalSettings(), null, 2));
|
||||
|
||||
// Override specific settings
|
||||
const settingsManager = SettingsManager.create();
|
||||
settingsManager.applyOverrides({
|
||||
compaction: { enabled: false },
|
||||
retry: { enabled: true, maxRetries: 5, baseDelayMs: 1000 },
|
||||
});
|
||||
|
||||
await createAgentSession({
|
||||
settingsManager,
|
||||
sessionManager: SessionManager.inMemory(),
|
||||
});
|
||||
|
||||
console.log("Session created with custom settings");
|
||||
|
||||
// Setters update memory immediately and queue persistence writes.
|
||||
// Call flush() when you need a durability boundary.
|
||||
settingsManager.setDefaultThinkingLevel("low");
|
||||
await settingsManager.flush();
|
||||
|
||||
// Surface settings I/O errors at the app layer.
|
||||
const settingsErrors = settingsManager.drainErrors();
|
||||
if (settingsErrors.length > 0) {
|
||||
for (const { scope, error } of settingsErrors) {
|
||||
console.warn(`Warning (${scope} settings): ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// For testing without file I/O:
|
||||
const inMemorySettings = SettingsManager.inMemory({
|
||||
compaction: { enabled: false },
|
||||
retry: { enabled: false },
|
||||
});
|
||||
|
||||
await createAgentSession({
|
||||
settingsManager: inMemorySettings,
|
||||
sessionManager: SessionManager.inMemory(),
|
||||
});
|
||||
|
||||
console.log("Test session created with in-memory settings");
|
||||
@@ -1,48 +0,0 @@
|
||||
/**
|
||||
* Session Management
|
||||
*
|
||||
* Control session persistence: in-memory, new file, continue, or open specific.
|
||||
*/
|
||||
|
||||
import { createAgentSession, SessionManager } from "@mariozechner/pi-coding-agent";
|
||||
|
||||
// In-memory (no persistence)
|
||||
const { session: inMemory } = await createAgentSession({
|
||||
sessionManager: SessionManager.inMemory(),
|
||||
});
|
||||
console.log("In-memory session:", inMemory.sessionFile ?? "(none)");
|
||||
|
||||
// New persistent session
|
||||
const { session: newSession } = await createAgentSession({
|
||||
sessionManager: SessionManager.create(process.cwd()),
|
||||
});
|
||||
console.log("New session file:", newSession.sessionFile);
|
||||
|
||||
// Continue most recent session (or create new if none)
|
||||
const { session: continued, modelFallbackMessage } = await createAgentSession({
|
||||
sessionManager: SessionManager.continueRecent(process.cwd()),
|
||||
});
|
||||
if (modelFallbackMessage) console.log("Note:", modelFallbackMessage);
|
||||
console.log("Continued session:", continued.sessionFile);
|
||||
|
||||
// List and open specific session
|
||||
const sessions = await SessionManager.list(process.cwd());
|
||||
console.log(`\nFound ${sessions.length} sessions:`);
|
||||
for (const info of sessions.slice(0, 3)) {
|
||||
console.log(` ${info.id.slice(0, 8)}... - "${info.firstMessage.slice(0, 30)}..."`);
|
||||
}
|
||||
|
||||
if (sessions.length > 0) {
|
||||
const { session: opened } = await createAgentSession({
|
||||
sessionManager: SessionManager.open(sessions[0].path),
|
||||
});
|
||||
console.log(`\nOpened: ${opened.sessionId}`);
|
||||
}
|
||||
|
||||
// Custom session directory (no cwd encoding)
|
||||
// const customDir = "/path/to/my-sessions";
|
||||
// const { session } = await createAgentSession({
|
||||
// sessionManager: SessionManager.create(process.cwd(), customDir),
|
||||
// });
|
||||
// SessionManager.list(process.cwd(), customDir);
|
||||
// SessionManager.continueRecent(process.cwd(), customDir);
|
||||
@@ -1,81 +0,0 @@
|
||||
/**
|
||||
* Full Control
|
||||
*
|
||||
* Replace everything - no discovery, explicit configuration.
|
||||
*
|
||||
* IMPORTANT: When providing `tools` with a custom `cwd`, use the tool factory
|
||||
* functions (createReadTool, createBashTool, etc.) to ensure tools resolve
|
||||
* paths relative to your cwd.
|
||||
*/
|
||||
|
||||
import { getModel } from "@mariozechner/pi-ai";
|
||||
import {
|
||||
AuthStorage,
|
||||
createAgentSession,
|
||||
createBashTool,
|
||||
createExtensionRuntime,
|
||||
createReadTool,
|
||||
ModelRegistry,
|
||||
type ResourceLoader,
|
||||
SessionManager,
|
||||
SettingsManager,
|
||||
} from "@mariozechner/pi-coding-agent";
|
||||
|
||||
// Custom auth storage location
|
||||
const authStorage = AuthStorage.create("/tmp/my-agent/auth.json");
|
||||
|
||||
// Runtime API key override (not persisted)
|
||||
if (process.env.MY_ANTHROPIC_KEY) {
|
||||
authStorage.setRuntimeApiKey("anthropic", process.env.MY_ANTHROPIC_KEY);
|
||||
}
|
||||
|
||||
// Model registry with no custom models.json
|
||||
const modelRegistry = ModelRegistry.inMemory(authStorage);
|
||||
|
||||
const model = getModel("anthropic", "claude-sonnet-4-20250514");
|
||||
if (!model) throw new Error("Model not found");
|
||||
|
||||
// In-memory settings with overrides
|
||||
const settingsManager = SettingsManager.inMemory({
|
||||
compaction: { enabled: false },
|
||||
retry: { enabled: true, maxRetries: 2 },
|
||||
});
|
||||
|
||||
// When using a custom cwd with explicit tools, use the factory functions
|
||||
const cwd = process.cwd();
|
||||
|
||||
const resourceLoader: ResourceLoader = {
|
||||
getExtensions: () => ({ extensions: [], errors: [], runtime: createExtensionRuntime() }),
|
||||
getSkills: () => ({ skills: [], diagnostics: [] }),
|
||||
getPrompts: () => ({ prompts: [], diagnostics: [] }),
|
||||
getThemes: () => ({ themes: [], diagnostics: [] }),
|
||||
getAgentsFiles: () => ({ agentsFiles: [] }),
|
||||
getSystemPrompt: () => `You are a minimal assistant.
|
||||
Available: read, bash. Be concise.`,
|
||||
getAppendSystemPrompt: () => [],
|
||||
extendResources: () => {},
|
||||
reload: async () => {},
|
||||
};
|
||||
|
||||
const { session } = await createAgentSession({
|
||||
cwd,
|
||||
agentDir: "/tmp/my-agent",
|
||||
model,
|
||||
thinkingLevel: "off",
|
||||
authStorage,
|
||||
modelRegistry,
|
||||
resourceLoader,
|
||||
// Use factory functions with the same cwd to ensure path resolution works correctly
|
||||
tools: [createReadTool(cwd), createBashTool(cwd)],
|
||||
sessionManager: SessionManager.inMemory(),
|
||||
settingsManager,
|
||||
});
|
||||
|
||||
session.subscribe((event) => {
|
||||
if (event.type === "message_update" && event.assistantMessageEvent.type === "text_delta") {
|
||||
process.stdout.write(event.assistantMessageEvent.delta);
|
||||
}
|
||||
});
|
||||
|
||||
await session.prompt("List files in the current directory.");
|
||||
console.log();
|
||||
@@ -1,67 +0,0 @@
|
||||
/**
|
||||
* Session runtime
|
||||
*
|
||||
* Use AgentSessionRuntime when you need to replace the active AgentSession,
|
||||
* for example for new-session, resume, fork, or import flows.
|
||||
*
|
||||
* The important pattern is: after the runtime replaces the active session,
|
||||
* rebind any session-local subscriptions and extension bindings to `runtime.session`.
|
||||
*/
|
||||
|
||||
import {
|
||||
type CreateAgentSessionRuntimeFactory,
|
||||
createAgentSessionFromServices,
|
||||
createAgentSessionRuntime,
|
||||
createAgentSessionServices,
|
||||
getAgentDir,
|
||||
SessionManager,
|
||||
} from "@mariozechner/pi-coding-agent";
|
||||
|
||||
const createRuntime: CreateAgentSessionRuntimeFactory = async ({ cwd, sessionManager, sessionStartEvent }) => {
|
||||
const services = await createAgentSessionServices({ cwd });
|
||||
return {
|
||||
...(await createAgentSessionFromServices({
|
||||
services,
|
||||
sessionManager,
|
||||
sessionStartEvent,
|
||||
})),
|
||||
services,
|
||||
diagnostics: services.diagnostics,
|
||||
};
|
||||
};
|
||||
const runtime = await createAgentSessionRuntime(createRuntime, {
|
||||
cwd: process.cwd(),
|
||||
agentDir: getAgentDir(),
|
||||
sessionManager: SessionManager.create(process.cwd()),
|
||||
});
|
||||
|
||||
let unsubscribe: (() => void) | undefined;
|
||||
|
||||
async function bindSession() {
|
||||
unsubscribe?.();
|
||||
const session = runtime.session;
|
||||
await session.bindExtensions({});
|
||||
unsubscribe = session.subscribe((event) => {
|
||||
if (event.type === "queue_update") {
|
||||
console.log("Queued:", event.steering.length + event.followUp.length);
|
||||
}
|
||||
});
|
||||
return session;
|
||||
}
|
||||
|
||||
let session = await bindSession();
|
||||
const originalSessionFile = session.sessionFile;
|
||||
console.log("Initial session:", originalSessionFile);
|
||||
|
||||
await runtime.newSession();
|
||||
session = await bindSession();
|
||||
console.log("After newSession():", session.sessionFile);
|
||||
|
||||
if (originalSessionFile) {
|
||||
await runtime.switchSession(originalSessionFile);
|
||||
session = await bindSession();
|
||||
console.log("After switchSession():", session.sessionFile);
|
||||
}
|
||||
|
||||
unsubscribe?.();
|
||||
await runtime.dispose();
|
||||
Reference in new issue
Block a user