feat: add Pi Coding Agent backend runtime, update dashboard UI

This commit is contained in:
Tanmay Karande
2026-03-03 00:24:19 -05:00
parent 453389f55c
commit 4c3a58b680
21 changed files with 4955 additions and 192 deletions

View File

@@ -3,6 +3,7 @@ import { ClaudeCodeBackend } from "../../src/backends/claude-backend.js";
import { CodexBackend } from "../../src/backends/codex-backend.js";
import { GeminiBackend } from "../../src/backends/gemini-backend.js";
import { OpenCodeBackend } from "../../src/backends/opencode-backend.js";
import { PiBackend } from "../../src/backends/pi-backend.js";
import { createBackend } from "../../src/backends/registry.js";
import { AgentRuntime, mapBackendEventResult } from "../../src/agent-runtime.js";
import { SessionManager } from "../../src/session-manager.js";
@@ -21,7 +22,7 @@ const defaultConfig: BackendAdapterConfig = {
// ─── 11.1 validate() method tests ───────────────────────────────────────────
describe("11.1 Backend validate() method", () => {
const backends = ["claude", "codex", "gemini", "opencode"] as const;
const backends = ["claude", "codex", "gemini", "opencode", "pi"] as const;
for (const name of backends) {
describe(`${name} backend`, () => {
@@ -57,7 +58,7 @@ describe("11.2 Timeout behavior", () => {
// Create a helper script path that sleeps for 30 seconds
const nodeExe = process.execPath;
const backends = ["claude", "codex", "gemini", "opencode"] as const;
const backends = ["claude", "codex", "gemini", "opencode", "pi"] as const;
for (const name of backends) {
it(`${name} backend should return timeout error when process exceeds queryTimeoutMs`, async () => {
@@ -445,12 +446,19 @@ describe("11.5 Unsupported option warning for ALLOWED_TOOLS", () => {
expect(args.join(" ")).not.toContain("--allowedTools");
});
it("Pi backend should NOT include any allowedTools flags", () => {
const backend = new PiBackend(toolFilteringConfig);
const args = backend.buildArgs("prompt", "system prompt");
expect(args.join(" ")).not.toContain("allowedTools");
expect(args.join(" ")).not.toContain("--allowedTools");
});
it("should log a warning when ALLOWED_TOOLS is set for a non-Claude backend", () => {
const warnSpy = vi.spyOn(logger, "warn").mockImplementation(() => undefined as any);
// Simulate the check that should happen at startup:
// When the backend doesn't support tool filtering but allowedTools is configured
const backendsWithoutToolFiltering = ["codex", "gemini", "opencode"] as const;
const backendsWithoutToolFiltering = ["codex", "gemini", "opencode", "pi"] as const;
const allowedTools = ["Read", "Write", "Bash"];
for (const name of backendsWithoutToolFiltering) {
@@ -464,7 +472,7 @@ describe("11.5 Unsupported option warning for ALLOWED_TOOLS", () => {
}
}
expect(warnSpy).toHaveBeenCalledTimes(3);
expect(warnSpy).toHaveBeenCalledTimes(4);
for (const name of backendsWithoutToolFiltering) {
expect(warnSpy).toHaveBeenCalledWith(
{ backend: name, allowedTools },