Address review feedback: use effort params, fix model names, add safety checks
This commit is contained in:
committed by
Colin McDonnell
parent
89e93d3398
commit
c6572f0987
+10
-15
@@ -5,12 +5,12 @@ import { log } from "../utils/cli.ts";
|
||||
import { addInstructions } from "./instructions.ts";
|
||||
import { agent, createAgentEnv, installFromNpmTarball } from "./shared.ts";
|
||||
|
||||
// model configuration based on effort level
|
||||
// uses model family aliases that auto-resolve to latest version
|
||||
const claudeModels: Record<Effort, { model: string; thinking: boolean }> = {
|
||||
nothink: { model: "claude-haiku-4-5", thinking: false },
|
||||
think: { model: "claude-sonnet-4-5", thinking: true },
|
||||
max: { model: "claude-opus-4-5", thinking: true },
|
||||
// effort levels for Claude Code
|
||||
// Claude Code automatically selects the best model based on effort
|
||||
const claudeEffortLevels: Record<Effort, "low" | "medium" | "high"> = {
|
||||
nothink: "low",
|
||||
think: "medium",
|
||||
max: "high",
|
||||
} as const;
|
||||
|
||||
export const claude = agent({
|
||||
@@ -30,9 +30,9 @@ export const claude = agent({
|
||||
const prompt = addInstructions({ payload, repo });
|
||||
log.group("Full prompt", () => log.info(prompt));
|
||||
|
||||
// get model configuration based on effort
|
||||
const modelConfig = claudeModels[effort];
|
||||
log.info(`Using model: ${modelConfig.model}, thinking: ${modelConfig.thinking}`);
|
||||
// get effort level - Claude Code automatically selects the best model
|
||||
const effortLevel = claudeEffortLevels[effort];
|
||||
log.info(`Using effort: ${effortLevel}`);
|
||||
|
||||
// SECURITY: For PUBLIC repos, Claude Code spawns subprocesses with full process.env, leaking API keys.
|
||||
// disable native Bash; agents use MCP bash tool which filters secrets.
|
||||
@@ -62,15 +62,10 @@ export const claude = agent({
|
||||
const queryOptions: Options = {
|
||||
...sandboxOptions,
|
||||
mcpServers,
|
||||
model: modelConfig.model,
|
||||
effort: effortLevel,
|
||||
pathToClaudeCodeExecutable: cliPath,
|
||||
env: createAgentEnv({ ANTHROPIC_API_KEY: apiKey }),
|
||||
};
|
||||
// only set maxThinkingTokens when we want to disable thinking (0)
|
||||
// omit the property to use default when thinking is enabled
|
||||
if (!modelConfig.thinking) {
|
||||
queryOptions.maxThinkingTokens = 0;
|
||||
}
|
||||
|
||||
const queryInstance = query({
|
||||
prompt,
|
||||
|
||||
+33
-25
@@ -7,12 +7,12 @@ import { log } from "../utils/cli.ts";
|
||||
import { addInstructions } from "./instructions.ts";
|
||||
import { agent, installFromNpmTarball, setupProcessAgentEnv } from "./shared.ts";
|
||||
|
||||
// model configuration based on effort level
|
||||
// uses model family aliases that auto-resolve to latest version
|
||||
const codexModels: Record<Effort, string> = {
|
||||
nothink: "gpt-4o-mini",
|
||||
think: "gpt-5.2-instant",
|
||||
max: "gpt-5.2-thinking",
|
||||
// reasoning effort configuration based on effort level
|
||||
// uses model_reasoning_effort parameter for o1 models
|
||||
const codexReasoningEffort: Record<Effort, string | undefined> = {
|
||||
nothink: "low",
|
||||
think: undefined, // use default
|
||||
max: "xhigh",
|
||||
} as const;
|
||||
|
||||
interface WriteCodexConfigParams {
|
||||
@@ -88,9 +88,13 @@ export const codex = agent({
|
||||
CODEX_HOME: codexDir, // point Codex to our config directory
|
||||
});
|
||||
|
||||
// get model based on effort level
|
||||
const model = codexModels[effort];
|
||||
log.info(`Using model: ${model}`);
|
||||
// get reasoning effort based on effort level
|
||||
const modelReasoningEffort = codexReasoningEffort[effort];
|
||||
if (modelReasoningEffort) {
|
||||
log.info(`Using model_reasoning_effort: ${modelReasoningEffort}`);
|
||||
} else {
|
||||
log.info(`Using default reasoning effort`);
|
||||
}
|
||||
|
||||
// Configure Codex
|
||||
const codexOptions: CodexOptions = {
|
||||
@@ -103,22 +107,26 @@ export const codex = agent({
|
||||
}
|
||||
|
||||
const codex = new Codex(codexOptions);
|
||||
const thread = codex.startThread(
|
||||
payload.sandbox
|
||||
? {
|
||||
model,
|
||||
approvalPolicy: "never",
|
||||
sandboxMode: "read-only",
|
||||
networkAccessEnabled: false,
|
||||
}
|
||||
: {
|
||||
model,
|
||||
approvalPolicy: "never",
|
||||
// use danger-full-access to allow git operations (workspace-write blocks .git directory writes)
|
||||
sandboxMode: "danger-full-access",
|
||||
networkAccessEnabled: true,
|
||||
}
|
||||
);
|
||||
|
||||
// Build thread options with optional model_reasoning_effort
|
||||
const baseThreadOptions = payload.sandbox
|
||||
? {
|
||||
approvalPolicy: "never" as const,
|
||||
sandboxMode: "read-only" as const,
|
||||
networkAccessEnabled: false,
|
||||
}
|
||||
: {
|
||||
approvalPolicy: "never" as const,
|
||||
// use danger-full-access to allow git operations (workspace-write blocks .git directory writes)
|
||||
sandboxMode: "danger-full-access" as const,
|
||||
networkAccessEnabled: true,
|
||||
};
|
||||
|
||||
const threadOptions = modelReasoningEffort
|
||||
? { ...baseThreadOptions, model_reasoning_effort: modelReasoningEffort }
|
||||
: baseThreadOptions;
|
||||
|
||||
const thread = codex.startThread(threadOptions);
|
||||
|
||||
try {
|
||||
const streamedTurn = await thread.runStreamed(addInstructions({ payload, repo }));
|
||||
|
||||
+4
-4
@@ -12,11 +12,11 @@ import {
|
||||
} from "./shared.ts";
|
||||
|
||||
// model configuration based on effort level
|
||||
// uses model family aliases that auto-resolve to latest version
|
||||
// auto for default, flash for fast/low-cost, pro for max capability
|
||||
const geminiModels = {
|
||||
nothink: "gemini-2.5-pro",
|
||||
think: "gemini-3-pro",
|
||||
max: "gemini-3-pro",
|
||||
nothink: "gemini-2.5-flash",
|
||||
think: "gemini-2.5-pro", // auto selection
|
||||
max: "gemini-2.5-pro",
|
||||
} as const;
|
||||
|
||||
// gemini cli event types inferred from stream-json output (NDJSON format)
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ export const opencode = agent({
|
||||
|
||||
// add API keys from apiKeys object
|
||||
for (const [key, value] of Object.entries(apiKeys || {})) {
|
||||
env[key] = value;
|
||||
env[key.toUpperCase()] = value;
|
||||
// also set GOOGLE_GENERATIVE_AI_API_KEY for Google provider compatibility
|
||||
if (key === "GEMINI_API_KEY") {
|
||||
env.GOOGLE_GENERATIVE_AI_API_KEY = value;
|
||||
|
||||
@@ -401,10 +401,10 @@ function parsePayload(inputs: Inputs): Payload {
|
||||
if (!("~pullfrog" in parsedPrompt)) {
|
||||
throw new Error();
|
||||
}
|
||||
// internal invocation: use effort from payload, fallback to input
|
||||
// internal invocation: use effort from payload, fallback to input, default to "think"
|
||||
return {
|
||||
...parsedPrompt,
|
||||
effort: parsedPrompt.effort ?? inputs.effort,
|
||||
effort: parsedPrompt.effort ?? inputs.effort ?? "think",
|
||||
} as Payload;
|
||||
} catch {
|
||||
// external invocation: use effort from input
|
||||
|
||||
Reference in New Issue
Block a user