mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-21 00:32:45 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
26dd2c5a90 |
@@ -0,0 +1,54 @@
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import { createTestLogger } from "../../../../test-utils/test-logger.js";
|
||||
import { ClaudeAgentClient } from "./agent.js";
|
||||
|
||||
const hostedEnvironments = [
|
||||
{ transport: "Bedrock", env: { CLAUDE_CODE_USE_BEDROCK: "1" } },
|
||||
{ transport: "Vertex", env: { CLAUDE_CODE_USE_VERTEX: "true" } },
|
||||
];
|
||||
|
||||
test.each(hostedEnvironments)(
|
||||
"offers Auto mode on $transport while preserving its default mode",
|
||||
async ({ env }) => {
|
||||
const client = new ClaudeAgentClient({
|
||||
logger: createTestLogger(),
|
||||
runtimeSettings: { env },
|
||||
resolveVersion: async () => "2.1.263",
|
||||
discoverModels: async () => [],
|
||||
});
|
||||
|
||||
const catalog = await client.fetchCatalog({ cwd: process.cwd() });
|
||||
|
||||
expect(catalog.modes?.map((mode) => mode.id)).toContain("auto");
|
||||
expect(catalog.defaultModeId).toBe("default");
|
||||
},
|
||||
);
|
||||
|
||||
test.each(hostedEnvironments)(
|
||||
"passes an explicit Auto selection on $transport to Claude Code",
|
||||
async ({ env }) => {
|
||||
const sdkError = new Error("Claude Code rejected this request");
|
||||
let requestedMode: string | undefined;
|
||||
let requestedEnv: NodeJS.ProcessEnv | undefined;
|
||||
const client = new ClaudeAgentClient({
|
||||
logger: createTestLogger(),
|
||||
runtimeSettings: { env },
|
||||
resolveBinary: async () => "/test/claude",
|
||||
queryFactory: ({ options }) => {
|
||||
requestedMode = options.permissionMode;
|
||||
requestedEnv = options.env;
|
||||
throw sdkError;
|
||||
},
|
||||
});
|
||||
const session = await client.createSession({ provider: "claude", cwd: process.cwd() });
|
||||
|
||||
try {
|
||||
await expect(session.setMode("auto")).rejects.toBe(sdkError);
|
||||
expect(requestedMode).toBe("auto");
|
||||
expect(requestedEnv).toMatchObject(env);
|
||||
} finally {
|
||||
await session.close();
|
||||
}
|
||||
},
|
||||
);
|
||||
@@ -201,23 +201,6 @@ test("exposes and applies auto permission mode", async () => {
|
||||
}
|
||||
});
|
||||
|
||||
test("rejects auto mode when Claude Code uses Bedrock", async () => {
|
||||
const previousBedrock = process.env.CLAUDE_CODE_USE_BEDROCK;
|
||||
process.env.CLAUDE_CODE_USE_BEDROCK = "1";
|
||||
|
||||
const session = await createSession();
|
||||
|
||||
try {
|
||||
await expect(session.setMode("auto")).rejects.toThrow(
|
||||
"Claude Auto mode requires the Anthropic API and is not supported when Claude Code uses Bedrock",
|
||||
);
|
||||
expect(sdkQueryFactory).not.toHaveBeenCalled();
|
||||
} finally {
|
||||
restoreEnvValue("CLAUDE_CODE_USE_BEDROCK", previousBedrock);
|
||||
await session.close();
|
||||
}
|
||||
});
|
||||
|
||||
test.each([
|
||||
{ env: {}, expected: "auto" },
|
||||
{ env: { CLAUDE_CODE_USE_BEDROCK: "1" }, expected: "default" },
|
||||
@@ -293,40 +276,6 @@ test("allows launch env to disable inherited Bedrock transport for auto mode", a
|
||||
}
|
||||
});
|
||||
|
||||
test("fails an auto mode turn when Claude Code uses Vertex", async () => {
|
||||
const previousVertex = process.env.CLAUDE_CODE_USE_VERTEX;
|
||||
process.env.CLAUDE_CODE_USE_VERTEX = "true";
|
||||
sdkQueryFactory.mockImplementation(() => {
|
||||
throw new Error("query should not start");
|
||||
});
|
||||
const client = new ClaudeAgentClient({
|
||||
logger: createTestLogger(),
|
||||
queryFactory: sdkQueryFactory,
|
||||
resolveBinary: async () => "/test/claude/bin",
|
||||
});
|
||||
const session = await client.createSession({
|
||||
provider: "claude",
|
||||
cwd: process.cwd(),
|
||||
modeId: "auto",
|
||||
});
|
||||
|
||||
try {
|
||||
const events = await collectUntilTerminal(streamSession(session, "hello"));
|
||||
const failure = events.find(
|
||||
(event): event is Extract<AgentStreamEvent, { type: "turn_failed" }> =>
|
||||
event.type === "turn_failed",
|
||||
);
|
||||
|
||||
expect(failure?.error).toContain(
|
||||
"Claude Auto mode requires the Anthropic API and is not supported when Claude Code uses Vertex",
|
||||
);
|
||||
expect(sdkQueryFactory).not.toHaveBeenCalled();
|
||||
} finally {
|
||||
restoreEnvValue("CLAUDE_CODE_USE_VERTEX", previousVertex);
|
||||
await session.close();
|
||||
}
|
||||
});
|
||||
|
||||
test("switches an auto mode session to another mode when Claude Code uses Bedrock", async () => {
|
||||
const previousBedrock = process.env.CLAUDE_CODE_USE_BEDROCK;
|
||||
process.env.CLAUDE_CODE_USE_BEDROCK = "1";
|
||||
|
||||
@@ -947,37 +947,11 @@ function isTruthyEnvValue(value: string | undefined): boolean {
|
||||
);
|
||||
}
|
||||
|
||||
function claudeAutoModeUnavailableOn(env: NodeJS.ProcessEnv): "Bedrock" | "Vertex" | null {
|
||||
if (isTruthyEnvValue(env.CLAUDE_CODE_USE_BEDROCK)) {
|
||||
return "Bedrock";
|
||||
}
|
||||
if (isTruthyEnvValue(env.CLAUDE_CODE_USE_VERTEX)) {
|
||||
return "Vertex";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function assertClaudeModeCanRun(mode: PermissionMode, env: NodeJS.ProcessEnv): void {
|
||||
if (mode !== "auto") {
|
||||
return;
|
||||
}
|
||||
const transport = claudeAutoModeUnavailableOn(env);
|
||||
if (transport === null) {
|
||||
return;
|
||||
}
|
||||
throw new Error(
|
||||
`Claude Auto mode requires the Anthropic API and is not supported when Claude Code uses ${transport}. Select another permission mode or unset the ${transport === "Bedrock" ? "CLAUDE_CODE_USE_BEDROCK" : "CLAUDE_CODE_USE_VERTEX"} environment variable.`,
|
||||
);
|
||||
}
|
||||
|
||||
function claudeModeCatalog(env: NodeJS.ProcessEnv): {
|
||||
modes: AgentMode[];
|
||||
defaultModeId: PermissionMode;
|
||||
} {
|
||||
if (claudeAutoModeUnavailableOn(env)) {
|
||||
return { modes: DEFAULT_MODES.filter((mode) => mode.id !== "auto"), defaultModeId: "default" };
|
||||
}
|
||||
return { modes: DEFAULT_MODES, defaultModeId: "auto" };
|
||||
function claudeDefaultMode(env: NodeJS.ProcessEnv): PermissionMode {
|
||||
return isTruthyEnvValue(env.CLAUDE_CODE_USE_BEDROCK) ||
|
||||
isTruthyEnvValue(env.CLAUDE_CODE_USE_VERTEX)
|
||||
? "default"
|
||||
: "auto";
|
||||
}
|
||||
|
||||
function coerceSessionMetadata(metadata: AgentMetadata | undefined): Partial<AgentSessionConfig> {
|
||||
@@ -1642,15 +1616,15 @@ export class ClaudeAgentClient implements AgentClient {
|
||||
discoveredModelIds,
|
||||
),
|
||||
);
|
||||
const modeCatalog = claudeModeCatalog(env);
|
||||
return {
|
||||
models,
|
||||
...modeCatalog,
|
||||
modes: DEFAULT_MODES,
|
||||
defaultModeId: claudeDefaultMode(env),
|
||||
};
|
||||
}
|
||||
|
||||
async resolveDefaultModeId({ env: launchEnv }: ResolveAgentDefaultModeInput): Promise<string> {
|
||||
return claudeModeCatalog(this.buildProviderEnv(launchEnv)).defaultModeId;
|
||||
return claudeDefaultMode(this.buildProviderEnv(launchEnv));
|
||||
}
|
||||
|
||||
private buildProviderEnv(launchEnv?: Record<string, string>): NodeJS.ProcessEnv {
|
||||
@@ -2540,7 +2514,6 @@ class ClaudeAgentSession implements AgentSession {
|
||||
}
|
||||
|
||||
const normalized = isPermissionMode(modeId) ? modeId : "default";
|
||||
assertClaudeModeCanRun(normalized, this.harnessEnvironment);
|
||||
const previousMode = this.currentMode;
|
||||
const launchesQuery = !this.query || this.queryRestartNeeded;
|
||||
const activeQuery = await this.ensureQuery(normalized);
|
||||
@@ -3424,7 +3397,6 @@ class ClaudeAgentSession implements AgentSession {
|
||||
);
|
||||
const settingsOptions = this.buildSettingsOptions(providerOptions, { ultracode });
|
||||
const sdkEnv = this.harnessEnvironment;
|
||||
assertClaudeModeCanRun(permissionMode, sdkEnv);
|
||||
|
||||
const claudeBinary = await this.resolveBinary();
|
||||
this.logger.debug(
|
||||
|
||||
Reference in New Issue
Block a user