runner.ts

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