Files
kandev/apps/web/lib/agent-executor-compat.ts
T
José Almeida 2779fb24aa feat(docker): make mock-agent runnable inside Docker for E2E
Lay the backend groundwork so the existing mock-agent can run inside
local_docker containers — needed for real-Docker E2E tests that don't
require Anthropic/OpenAI API keys.

Container builder bind-mounts a host mock-agent binary at
/usr/local/bin/mock-agent when KANDEV_MOCK_AGENT_LINUX_BINARY is set
(or build/mock-agent-linux-amd64 sits next to the kandev binary), the
same pattern already used for agentctl. MockAgent.BuildCommand always
resolves via PATH so the same command works on host (E2E PATH includes
bin/) and in containers (mounted at /usr/local/bin/mock-agent).

Mock now declares non-nil empty RemoteAuth so it counts as a
remote-capable agent. The remoteauth catalog includes specs even with
zero methods, and the frontend gating helper treats an empty-method
spec as "no credentials needed" — letting mock-agent pass the
configure-on-executor check that hides uncatalogued agents on remote
executors.

repositoryCloneURL falls back to the local origin remote URL when the
repo has no provider info, so local-only repos with a real remote
(including file:// remotes used in E2E) work on remote executors that
clone inside the container.

Makefile: build-mock-agent-linux target mirrors build-agentctl-linux.
2026-05-04 21:09:39 +01:00

53 lines
2.1 KiB
TypeScript

import type { ExecutorProfile } from "@/lib/types/http";
import type { RemoteAuthSpec } from "@/lib/api/domains/settings-api";
const REMOTE_EXECUTOR_TYPES = new Set(["local_docker", "remote_docker", "sprites"]);
export function executorRequiresAgentCredentials(executorType?: string | null): boolean {
if (!executorType) return false;
return REMOTE_EXECUTOR_TYPES.has(executorType);
}
function parseJSON<T>(raw: string | undefined, fallback: T): T {
if (!raw) return fallback;
try {
return JSON.parse(raw) as T;
} catch {
return fallback;
}
}
/**
* For local/worktree executors, agents need no extra credentials → always supported.
* For remote executors (Docker/Sprites), the executor profile must carry either:
* - a non-env auth method ID for the agent's spec in `remote_credentials`, or
* - a non-null secret keyed by an env method ID in `remote_auth_secrets`.
* Agents without a remote-auth spec (Copilot/Amp/OpenCode/TUI) cannot
* carry credentials on remote executors → blocked. A spec with zero methods
* means "no credentials needed" (mock-agent for tests) → allowed.
*
* Spec IDs are registry-type strings ("claude-acp", "codex-acp", …) which the
* frontend exposes as `AgentProfileOption.agent_name`. `agent_id` is a DB UUID
* and is unrelated to the catalog.
*/
export function isAgentConfiguredOnExecutor(
agent: { agent_name: string },
executorProfile: Pick<ExecutorProfile, "config" | "executor_type">,
authSpecs: RemoteAuthSpec[],
): boolean {
if (!executorRequiresAgentCredentials(executorProfile.executor_type)) return true;
const spec = authSpecs.find((s) => s.id === agent.agent_name);
if (!spec) return false;
if (spec.methods.length === 0) return true;
const credentials = new Set(parseJSON<string[]>(executorProfile.config?.remote_credentials, []));
if (spec.methods.some((m) => m.type !== "env" && credentials.has(m.method_id))) return true;
const secrets = parseJSON<Record<string, string | null>>(
executorProfile.config?.remote_auth_secrets,
{},
);
return spec.methods.some((m) => m.type === "env" && secrets[m.method_id]);
}