From 03ad69e4456a72a51c30c2b3b97ed23887c63978 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Sat, 26 Sep 2026 19:40:05 +0200 Subject: [PATCH] test adapter usage references through daemon RPC --- .../session-usage-reference.e2e.test.ts | 76 ++++++++++++++++--- .../session-usage-reference/index.server.ts | 7 +- 2 files changed, 69 insertions(+), 14 deletions(-) diff --git a/packages/server/src/server/plugins/session-usage-reference.e2e.test.ts b/packages/server/src/server/plugins/session-usage-reference.e2e.test.ts index fdf9f1c111..1c8512f805 100644 --- a/packages/server/src/server/plugins/session-usage-reference.e2e.test.ts +++ b/packages/server/src/server/plugins/session-usage-reference.e2e.test.ts @@ -1,5 +1,9 @@ import { fileURLToPath } from "node:url"; import { expect, test } from "vitest"; +import { ACPAgentSession } from "../agent/providers/acp-agent.js"; +import { ClaudeAgentClient } from "../agent/providers/claude/agent.js"; +import { CodexAppServerAgentSession } from "../agent/providers/codex-app-server-agent.js"; +import { createTestLogger } from "../../test-utils/test-logger.js"; import { DaemonClient } from "../test-utils/daemon-client.js"; import { createTestAgentClient } from "../test-utils/fake-agent-client.js"; import { createTestPaseoDaemon } from "../test-utils/paseo-daemon.js"; @@ -43,21 +47,69 @@ test("agent.get_usage_report resolves source IDs from default built-in and ACP s const directory = fileURLToPath( new URL("./test-fixtures/session-usage-reference/", import.meta.url), ); - const sources = [ - ["claude", "claude"], - ["codex", "codex"], - ["copilot", "copilot"], - ["cursor", "cursor"], - ["kimi", "kimi"], - ["generic-acp", "generic-match"], - ] as const; + const providers = ["claude", "codex", "copilot", "cursor", "kimi", "generic-acp"] as const; + const logger = createTestLogger(); + const references = new Map } | null>(); + const claude = await new ClaudeAgentClient({ + logger, + resolveBinary: async () => "/test/claude/bin", + }).createSession( + { provider: "claude", cwd: directory }, + { + env: { + HOME: directory, + CLAUDE_CONFIG_DIR: "", + ANTHROPIC_BASE_URL: "", + ANTHROPIC_API_KEY: "", + ANTHROPIC_AUTH_TOKEN: "", + }, + }, + ); + references.set("claude", (await claude.getUsageReference?.()) ?? null); + await claude.close(); + const codex = new CodexAppServerAgentSession( + { provider: "codex", cwd: directory }, + null, + logger, + () => { + throw new Error("Codex runtime should not start"); + }, + {}, + false, + false, + false, + undefined, + "interactive", + { HOME: directory, OPENAI_BASE_URL: "" }, + ); + references.set("codex", await codex.getUsageReference()); + for (const provider of providers.slice(2)) { + const session = new ACPAgentSession( + { provider, cwd: directory }, + { + provider, + logger, + defaultCommand: ["unused"], + defaultModes: [], + capabilities: { + supportsStreaming: true, + supportsSessionPersistence: true, + supportsDynamicModes: true, + supportsMcpServers: true, + supportsReasoningStream: true, + supportsToolInvocations: true, + }, + }, + ); + references.set(provider, await session.getUsageReference()); + } const agentClients = Object.fromEntries( - sources.map(([provider, source]) => { + providers.map((provider) => { const client = createTestAgentClient(provider); const createSession = client.createSession.bind(client); client.createSession = async (...args) => { const session = await createSession(...args); - session.getUsageReference = async () => ({ source, input: {} }); + session.getUsageReference = async () => references.get(provider) ?? null; return session; }; return [provider, client]; @@ -76,10 +128,10 @@ test("agent.get_usage_report resolves source IDs from default built-in and ACP s const client = new DaemonClient({ url: `ws://127.0.0.1:${daemon.port}/ws` }); try { await client.connect(); - for (const [provider, source] of sources) { + for (const provider of providers) { const agent = await client.createAgent({ provider, cwd: directory }); const result = await client.getAgentUsageReport({ agentId: agent.id }); - expect(result.entry?.sourceId, provider).toBe(source); + expect(result.entry?.sourceId, provider).toBe(provider); } } finally { await client.close(); diff --git a/packages/server/src/server/plugins/test-fixtures/session-usage-reference/index.server.ts b/packages/server/src/server/plugins/test-fixtures/session-usage-reference/index.server.ts index 00ccf7c16d..c74504a958 100644 --- a/packages/server/src/server/plugins/test-fixtures/session-usage-reference/index.server.ts +++ b/packages/server/src/server/plugins/test-fixtures/session-usage-reference/index.server.ts @@ -6,11 +6,14 @@ import { import { z } from "zod"; export default function contribute(server: PluginServerContext) { - for (const id of ["claude", "codex", "copilot", "cursor", "kimi", "generic-match"]) { + for (const id of ["claude", "codex", "copilot", "cursor", "kimi", "generic-acp"]) { + let input = z.object({}).strict(); + if (id === "claude") input = z.object({ configDir: z.string() }).strict(); + if (id === "codex") input = z.object({ codexHome: z.string() }).strict(); server.registerUsageSource({ id, label: id, - input: z.object({}).strict(), + input, fetch: async () => ({ account: { key: "default" }, status: "available",