Add listProviderModels() to DaemonClient + E2E tests

Add method to query available models for Claude and Codex providers without
requiring an active agent. E2E tests verify both providers return model lists
with expected structure (id, label, provider).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Mohamed Boudra
2025-12-25 18:20:37 +07:00
parent b32ad5ef13
commit 8a614aac58
2 changed files with 92 additions and 0 deletions

View File

@@ -1454,4 +1454,54 @@ describe("daemon E2E", () => {
60000 // 1 minute timeout
);
});
describe("listProviderModels", () => {
test(
"returns model list for Codex provider",
async () => {
// List models for Codex provider - no agent needed
const result = await ctx.client.listProviderModels("codex");
// Verify response structure
expect(result.provider).toBe("codex");
expect(result.error).toBeNull();
expect(result.fetchedAt).toBeTruthy();
// Should return at least one model
expect(result.models).toBeTruthy();
expect(result.models.length).toBeGreaterThan(0);
// Verify model structure
const model = result.models[0];
expect(model.provider).toBe("codex");
expect(model.id).toBeTruthy();
expect(model.label).toBeTruthy();
},
60000 // 1 minute timeout
);
test(
"returns model list for Claude provider",
async () => {
// List models for Claude provider - no agent needed
const result = await ctx.client.listProviderModels("claude");
// Verify response structure
expect(result.provider).toBe("claude");
expect(result.error).toBeNull();
expect(result.fetchedAt).toBeTruthy();
// Should return at least one model
expect(result.models).toBeTruthy();
expect(result.models.length).toBeGreaterThan(0);
// Verify model structure
const model = result.models[0];
expect(model.provider).toBe("claude");
expect(model.id).toBeTruthy();
expect(model.label).toBeTruthy();
},
60000 // 1 minute timeout
);
});
});

View File

@@ -8,6 +8,7 @@ import type {
PersistedAgentDescriptorPayload,
} from "../messages.js";
import type {
AgentModelDefinition,
AgentPermissionRequest,
AgentPermissionResponse,
AgentPersistenceHandle,
@@ -489,6 +490,47 @@ export class DaemonClient {
);
}
// ============================================================================
// Provider Models
// ============================================================================
async listProviderModels(
provider: AgentProvider,
options?: { cwd?: string }
): Promise<{
provider: AgentProvider;
models: AgentModelDefinition[];
fetchedAt: string;
error: string | null;
}> {
const startPosition = this.messageQueue.length;
this.send({
type: "list_provider_models_request",
provider,
cwd: options?.cwd,
});
return this.waitFor(
(msg) => {
if (
msg.type === "list_provider_models_response" &&
msg.payload.provider === provider
) {
return {
provider: msg.payload.provider,
models: msg.payload.models ?? [],
fetchedAt: msg.payload.fetchedAt,
error: msg.payload.error ?? null,
};
}
return null;
},
30000,
{ skipQueueBefore: startPosition }
);
}
// ============================================================================
// Permissions
// ============================================================================