runner.ts

 1import { Agent, ProviderTransport, type AgentEvent } from "@mariozechner/pi-agent";
 2import { type AgentTool } from "@mariozechner/pi-ai";
 3import type { RumiloConfig } from "../config/schema.js";
 4import { resolveModel } from "./model-resolver.js";
 5
 6export interface AgentRunOptions {
 7  model: string;
 8  systemPrompt: string;
 9  tools: AgentTool[];
10  onEvent?: (event: AgentEvent) => void;
11  config: RumiloConfig;
12}
13
14export interface AgentRunResult {
15  message: string;
16  usage?: unknown;
17}
18
19export async function runAgent(query: string, options: AgentRunOptions): Promise<AgentRunResult> {
20  const agent = new Agent({
21    initialState: {
22      systemPrompt: options.systemPrompt,
23      model: resolveModel(options.model, options.config),
24      tools: options.tools,
25    },
26    transport: new ProviderTransport(),
27  });
28
29  if (options.onEvent) {
30    agent.subscribe(options.onEvent);
31  }
32
33  await agent.prompt(query);
34
35  const last = agent.state.messages
36    .slice()
37    .reverse()
38    .find((msg) => msg.role === "assistant");
39
40  const text = last?.content
41    ?.filter((content) => content.type === "text")
42    .map((content) => content.text)
43    .join("")
44    .trim();
45
46  return {
47    message: text ?? "",
48    usage: (last as any)?.usage,
49  };
50}