-
Notifications
You must be signed in to change notification settings - Fork 1
add effort as an input + support parsing from payload #21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well-structured PR with clear documentation. The effort-based model selection is clean and the API key migration improves security. Found one critical issue with model names and several implementation concerns that need addressing.
agents/codex.ts
Outdated
| // uses model family aliases that auto-resolve to latest version | ||
| const codexModels: Record<Effort, string> = { | ||
| nothink: "gpt-4o-mini", | ||
| think: "gpt-5.2-instant", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical: These OpenAI model names appear to be fictional. OpenAI's actual models are gpt-4o-mini, gpt-4o, o1-mini, o1, etc. There is no gpt-5.2-instant or gpt-5.2-thinking. This will cause runtime failures when users select think or max effort levels. Replace with actual OpenAI model names.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update to use model_reasoning_effort
| model_reasoning_effort | minimal | low | medium | high | xhigh | Adjust reasoning effort for supported models (Responses API only; xhigh is model-dependent). |
|---|
"low" for "nothink"
"xhigh" for "max"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to use model_reasoning_effort parameter
agents/gemini.ts
Outdated
| // uses model family aliases that auto-resolve to latest version | ||
| const geminiModels = { | ||
| nothink: "gemini-2.5-pro", | ||
| think: "gemini-3-pro", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical: These Gemini model names don't match Google's naming conventions. Current Gemini models are gemini-2.0-flash-exp, gemini-1.5-pro, gemini-1.5-flash, etc. There is no gemini-2.5-pro or gemini-3-pro. Verify and use actual Gemini API model names or this will fail at runtime.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Deafult to auto (no specification) for "think"
Then force "flash" for nothink and "pro" for "max"
| Description | Models |
|---|---|
| Auto (Gemini 3) | Let the system choose the best Gemini 3 model for your task. |
| Auto (Gemini 2.5) | Let the system choose the best Gemini 2.5 model for your task. |
| Manual | Select a specific model. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to use flash for nothink, pro for think/max
agents/claude.ts
Outdated
| // 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 }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These model names use version suffixes like claude-haiku-4-5 that don't match Anthropic's actual model naming. Current Claude models use formats like claude-3-5-sonnet-20241022, claude-3-5-haiku-20241022, etc. Verify these are valid model identifiers or this will fail when invoking the Anthropic API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For Claude Code do not update model, the best model is already selected automatically. Use "effort" only
https://platform.claude.com/docs/en/build-with-claude/effort
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to use effort parameter only, removed model selection
main.ts
Outdated
| // internal invocation: use effort from payload, fallback to input | ||
| return { | ||
| ...parsedPrompt, | ||
| effort: parsedPrompt.effort ?? inputs.effort, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The effort fallback logic is inconsistent. For internal invocations, you use parsedPrompt.effort ?? inputs.effort, but for external invocations you use inputs.effort ?? "think". If inputs.effort is undefined in both cases, internal gets undefined while external gets "think". This could cause the agent to receive undefined for effort. Consider: effort: parsedPrompt.effort ?? inputs.effort ?? "think"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added consistent fallback to "think" for both branches
agents/opencode.ts
Outdated
| for (const [key, value] of Object.entries(apiKeys || {})) { | ||
| const upperKey = key.toUpperCase(); | ||
| env[upperKey] = value; | ||
| env[key] = value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change removes the toUpperCase() call on API key names. The previous code normalized keys to uppercase (e.g., ANTHROPIC_API_KEY), but now it preserves the original case. Since the keys in apiKeys come from agent.apiKeyNames which are already uppercase in external.ts, this should be fine. However, verify that OpenCode accepts both GEMINI_API_KEY and GOOGLE_GENERATIVE_AI_API_KEY in the exact case provided.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add this back for safety
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added back toUpperCase() for safety
colinhacks
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @pullfrog address these reviews according to my comments and update the PR
agents/codex.ts
Outdated
| // uses model family aliases that auto-resolve to latest version | ||
| const codexModels: Record<Effort, string> = { | ||
| nothink: "gpt-4o-mini", | ||
| think: "gpt-5.2-instant", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update to use model_reasoning_effort
| model_reasoning_effort | minimal | low | medium | high | xhigh | Adjust reasoning effort for supported models (Responses API only; xhigh is model-dependent). |
|---|
"low" for "nothink"
"xhigh" for "max"
agents/gemini.ts
Outdated
| // uses model family aliases that auto-resolve to latest version | ||
| const geminiModels = { | ||
| nothink: "gemini-2.5-pro", | ||
| think: "gemini-3-pro", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Deafult to auto (no specification) for "think"
Then force "flash" for nothink and "pro" for "max"
| Description | Models |
|---|---|
| Auto (Gemini 3) | Let the system choose the best Gemini 3 model for your task. |
| Auto (Gemini 2.5) | Let the system choose the best Gemini 2.5 model for your task. |
| Manual | Select a specific model. |
agents/opencode.ts
Outdated
| for (const [key, value] of Object.entries(apiKeys || {})) { | ||
| const upperKey = key.toUpperCase(); | ||
| env[upperKey] = value; | ||
| env[key] = value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add this back for safety
main.ts
Outdated
| // internal invocation: use effort from payload, fallback to input | ||
| return { | ||
| ...parsedPrompt, | ||
| effort: parsedPrompt.effort ?? inputs.effort, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix this.
agents/claude.ts
Outdated
| // 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 }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For Claude Code do not update model, the best model is already selected automatically. Use "effort" only
https://platform.claude.com/docs/en/build-with-claude/effort
|
cc @pullfrog address all my comments |
|
Addressed all 5 review comments and pushed changes. |

Effort Input & Environment-Based API Keys
This PR introduces effort-based model selection and switches API key handling from action inputs to environment variables.
Summary of Changes
1. New
effortInput ParameterAdded a new
effortinput to control model selection and thinking levels:nothinkthinkmaxaction.yml:
2. API Keys via Environment Variables (Breaking Change)
Before: API keys were passed as action inputs (snake_case):
After: API keys are passed via environment variables (SCREAMING_CASE):
This change:
promptandeffortinputs)process.env3. Effort Parsing from Payload
For internal Pullfrog invocations (via webhooks), effort can be specified in the JSON payload:
The
Payloadinterface now includes:4. Agent Model Configuration
Each agent now receives
effortin its config and selects models accordingly:Claude:
Similar configurations exist for Codex and Gemini.
5. Updated Runtime to Node 24
Files Changed
action.ymleffortinput, updated to node24external.tsEfforttype, updatedapiKeyNamesto SCREAMING_CASE, addedefforttoPayloadmain.tsInputstype, API keys read fromprocess.env, effort parsing logicentry.tsagents/claude.tsagents/codex.tsagents/gemini.tsagents/cursor.tsagents/opencode.tsagents/shared.tseffort: EfforttoAgentConfiginterfaceREADME.mdMigration Guide
Update your workflow file:
Required Workflow Updates
Every repository using Pullfrog needs its
.github/workflows/pullfrog.ymlupdated:with: anthropic_api_key:env: ANTHROPIC_API_KEY:snake_caseSCREAMING_CASEsecrets: inheritto workflow dispatch${{ github.event.inputs.prompt }}${{ inputs.prompt }}Full example of updated workflow:
Testing
All 15 agent/effort combinations tested successfully:
Cursor and OpenCode tests pass but effort does not change model selection.