#11155: feat(hooks): before_agent_start model/provider override (run-scoped, fail-closed)
agents
stale
size: M
Cluster:
Plugin and Hook Enhancements
## Summary
Adds an **official plugin extension point** to request a **run-scoped** model/provider override via the existing `before_agent_start` hook.
### Contract
- `PluginHookBeforeAgentStartResult` now supports:
- `providerOverride?: string`
- `modelOverride?: string`
- Overrides are **run-scoped only** (not persisted to session).
- **Fail-closed**: invalid overrides or hook errors are ignored and existing behavior remains.
- Emits `onAgentEvent` lifecycle telemetry with accepted/rejected reason.
### Files
- `src/plugins/types.ts`
- `src/plugins/hooks.ts`
- `src/agents/pi-embedded-runner/run.ts`
- `src/agents/pi-embedded-runner.live-routing-before-agent-start.test.ts`
## Why
We can already classify inbound messages in plugins, but there was no supported way to switch the model for the current run without local core patching. This enables safe, observable canaries like Tier-L routing for low-risk job classes.
## Testing
- Adds a vitest unit test that asserts the override is applied before final model resolution.
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR extends the `before_agent_start` plugin hook contract to optionally return `providerOverride`/`modelOverride`, and wires that into the embedded PI runner so plugins can request a run-scoped model/provider switch. The runner probes the requested override via `resolveModel` and emits lifecycle `onAgentEvent` telemetry indicating accepted/rejected decisions. A vitest test is added to assert the override is applied before final model resolution.
<h3>Confidence Score: 3/5</h3>
- This PR is close to mergeable but has a couple of correctness issues in hook merge semantics and override validation ordering.
- The core idea is sound and changes are localized, but (1) the merge logic currently allows lower-priority hooks to override higher-priority ones, contradicting the stated contract, and (2) override probing happens before ensuring the model registry is available, which can cause valid overrides to be incorrectly rejected in some environments. Fixing these would reduce behavioral surprises for plugin authors.
- src/plugins/hooks.ts, src/agents/pi-embedded-runner/run.ts
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#14647: feat(plugins): allow before_agent_start hook to override model (#14...
by lailoo · 2026-02-12
88.2%
#17614: feat: allow before_agent_start hook to override model selection
by plc · 2026-02-16
87.0%
#8022: feat: implement before_model_select plugin hook
by dead-pool-aka-wilson · 2026-02-03
83.1%
#14873: [Feature]: Extend before_agent_start hook context with Model, Tools...
by akv2011 · 2026-02-12
82.2%
#22624: feat(plugins): add before_context_send hook and model routing via b...
by davidrudduck · 2026-02-21
81.4%
#23559: feat(plugins): add before_context_send hook and model routing via b...
by davidrudduck · 2026-02-22
81.1%
#8178: feat: allow before_agent_start to override the prompt
by richardfogaca · 2026-02-03
78.9%
#11124: feat(plugins): add before_llm_request hook for custom LLM headers
by johnlanni · 2026-02-07
76.0%
#20418: feat(hooks): add session:pre-spawn and agent:pre-run hook events
by NOVA-Openclaw · 2026-02-18
75.9%
#14544: feat: add before_context_send plugin hook
by Windelly · 2026-02-12
75.8%