feat: allow before_agent_start hook to override model selection#17614
feat: allow before_agent_start hook to override model selection#17614plc wants to merge 3 commits intoopenclaw:mainfrom
Conversation
Add an optional `model` field to `PluginHookBeforeAgentStartResult` so plugins can dynamically select the model for an agent run based on prompt complexity, session context, or cost optimisation rules. The model override runs early in `runEmbeddedPiAgent` (before auth profile and context window resolution) so the full model pipeline flows naturally with the overridden provider/model. Safety: - Ignored when user has set a manual model override (authProfileIdSource === 'user') - Failed resolution falls back to original model with a warning log - Fully backward-compatible: existing plugins continue to work unchanged - Model aliases supported via existing resolveModelRefFromString The hook also continues to run in attempt.ts for systemPrompt/prependContext; only the model field is extracted in the early pass. Use case: plugin-based model routers that classify prompt complexity and route to the optimal model tier (e.g. Haiku for acks, Sonnet for general chat, Opus for complex reasoning).
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b0a7722873
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- Add null check for resolveModelRefFromString result (Greptile feedback) - Check modelSource/providerSource in addition to authProfileIdSource to properly detect user model overrides (Codex P1) - Add fallback to original model when hook-provided model can't be resolved (Codex P1) - Fix formatting with oxfmt
Those properties don't exist on RunEmbeddedPiAgentParams yet. Kept authProfileIdSource check and added TODO comment about future enhancement to track /model directive source.
|
This pull request has been automatically marked as stale due to inactivity. |
|
This would be huge for local LLM routing. Running Qwen 3.5 via Ollama alongside Claude Max — a |
|
This pull request has been automatically marked as stale due to inactivity. |
|
Closing due to inactivity. |
Summary
Add an optional
modelfield toPluginHookBeforeAgentStartResultso plugins can override the model for an agent run.This builds on #14873 (which exposes model/tools/sender context to the hook) by letting plugins write back a model override. This enables plugin-based model routers.
Motivation
Plugins like cost-optimising model routers need to select models per-request based on prompt complexity, session context, and cost. Currently the only way to do this is with an external HTTP proxy (e.g. ClawRoute), which has no access to OpenClaw session context.
With this change, a plugin can:
Use cases
Changes
3 files, +46/-2 lines:
src/plugins/types.ts: Addmodel?: stringtoPluginHookBeforeAgentStartResultwith JSDocsrc/plugins/hooks.ts: Addmodelto the merge function inrunBeforeAgentStart(last plugin wins)src/agents/pi-embedded-runner/run.ts: Run the hook early inrunEmbeddedPiAgent(before auth/context-window resolution) to extract the model override. The hook continues to run later inattempt.tsforsystemPromptandprependContext.Design decisions
User overrides take precedence: If
authProfileIdSource === 'user'(e.g./modelcommand), the hook model is skipped entirely.Fail-open: If the hook throws or returns an unresolvable model, the original model is used with a warning log.
Early execution: The hook runs before
resolveModel()so auth profiles, context window checks, and failover all work naturally with the overridden provider/model.Aliases supported: Uses existing
resolveModelRefFromString, so model aliases work.Backward-compatible:
modelis optional; existing plugins are unaffected.Testing notes
{ model: 'anthropic/claude-haiku-3-5' }→ model changes, auth resolves for new provider{ model: 'nonexistent/model' }→resolveModelfails, original model used{}orundefined→ no change (existing behaviour)/model opusoverride → hook is skipped entirelysystemPromptmerge)Greptile Summary
Adds plugin-based model override capability via
before_agent_starthook. The hook runs early in the agent lifecycle (before auth resolution) to allow plugins to select models based on prompt complexity, session context, and cost optimization.Key changes:
modelfield toPluginHookBeforeAgentStartResultinsrc/plugins/types.ts:338src/plugins/hooks.ts:203src/agents/pi-embedded-runner/run.ts:222-252with proper fallback handlingStrengths:
resolveModelRefFromStringresult (addresses previous review feedback)Known limitation:
/modelcommand is not detected (onlyauthProfileIdSourceis checked). This is documented in the code comments atsrc/agents/pi-embedded-runner/run.ts:216-217as a future enhancement. Plugins could potentially override user's/modelselections.Confidence Score: 4/5
/modelcommand overrides) is documented and acknowledged as a future enhancement. The code follows existing patterns and is backward compatible.Last reviewed commit: 25cf41f