feat: hai board — core, dashboard, cli, engine

This commit is contained in:
Dustin Byrne
2026-03-25 18:32:10 -04:00
parent 517c963200
commit 961203692d
41 changed files with 6383 additions and 0 deletions

83
packages/engine/src/pi.ts Normal file
View File

@@ -0,0 +1,83 @@
/**
* Shared pi SDK setup for hai engine agents.
*
* Uses the user's existing pi auth (API keys / OAuth from ~/.pi/agent/auth.json).
* Provides factory functions for creating triage and executor agent sessions.
*/
import {
AuthStorage,
createAgentSession,
createCodingTools,
createReadOnlyTools,
DefaultResourceLoader,
ModelRegistry,
SessionManager,
SettingsManager,
type AgentSession,
} from "@mariozechner/pi-coding-agent";
export interface AgentResult {
session: AgentSession;
}
export interface AgentOptions {
cwd: string;
systemPrompt: string;
tools?: "coding" | "readonly";
onText?: (delta: string) => void;
onToolStart?: (name: string) => void;
onToolEnd?: (name: string, isError: boolean) => void;
}
/**
* Create a pi agent session configured for hai.
* Reuses the user's existing pi auth and model configuration.
*/
export async function createHaiAgent(options: AgentOptions): Promise<AgentResult> {
const authStorage = AuthStorage.create();
const modelRegistry = new ModelRegistry(authStorage);
const tools =
options.tools === "readonly"
? createReadOnlyTools(options.cwd)
: createCodingTools(options.cwd);
const settingsManager = SettingsManager.inMemory({
compaction: { enabled: true },
retry: { enabled: true, maxRetries: 3 },
});
const resourceLoader = new DefaultResourceLoader({
cwd: options.cwd,
settingsManager,
systemPromptOverride: () => options.systemPrompt,
appendSystemPromptOverride: () => [],
});
await resourceLoader.reload();
const { session } = await createAgentSession({
cwd: options.cwd,
authStorage,
modelRegistry,
resourceLoader,
tools,
sessionManager: SessionManager.inMemory(),
settingsManager,
});
// Wire up event listeners
session.subscribe((event) => {
if (event.type === "message_update" && event.assistantMessageEvent.type === "text_delta") {
options.onText?.(event.assistantMessageEvent.delta);
}
if (event.type === "tool_execution_start") {
options.onToolStart?.(event.toolName);
}
if (event.type === "tool_execution_end") {
options.onToolEnd?.(event.toolName, event.isError);
}
});
return { session };
}