Repository navigation
Closed
Labels
app/corePackage: core (pkgs/ or apps/ in this repo)Package: core (pkgs/ or apps/ in this repo)effort/mMedium: expected under 1 day of workMedium: expected under 1 day of workkind/featureNew feature or capability requestNew feature or capability requestmeta/enrichedIntake review done: acceptance criteria, links, and normalized labels addedIntake review done: acceptance criteria, links, and normalized labels addedpriority/normalOrdinary priority (the default)Ordinary priority (the default)source/humanFiled directly by a humanFiled directly by a human
Description
Support per-element (per-target) context limits in model routes
Today limit: { context } exists only at the route level (landed with the route context-limit feature). A pool whose members need different context ceilings must be expressed by nesting whole routes.
Motivating case (live config, 2026-10-27 redesign)
The small pool needs three elements with two different ceilings:
haiku-plan#highat ≤100kluna-plan#xhighat ≤100khaiku-plan#highat ≤200k
Because per-target limits don't exist, this ships as a nested small-100k sub-route (100k cap) inside small (200k cap) — an extra route id, and the intent ("these elements, these ceilings") is split across two definitions.
Request
Allow limit on individual route targets, composing with the route-level limit:
{ "model": "opencode-route/haiku-plan#high", "limit": { "context": 100000 } }Semantics to define:
- A target is eligible only when the request context fits BOTH the route limit (if any) and the target limit (if any).
- Over-limit targets are skipped like other ineligible targets (quota-demoted, disabled, window-closed), with the exclusion visible in the resolved-route dump with its reason.
- Nested-route references carrying their own limits keep working unchanged.
Done when
small can be written as one flat route with per-element limits, the dump shows per-element ceilings and skip reasons, and tests cover mixed-ceiling pools.
Acceptance criteria
-
smallcan be written as one flat route with per-elementlimit: { context }on individual targets — no nestedsmall-100ksub-route needed (the body's "Done when", restated here as the criteria section). - A target is eligible only when the request context fits BOTH the route-level limit (if any) and the target limit (if any); over-limit targets are skipped like other ineligible targets.
- The resolved-route dump shows per-element ceilings and the skip reason for each over-limit target.
- Nested-route references carrying their own limits keep working unchanged, and tests cover mixed-ceiling pools.
Metadata
Metadata
Assignees
Labels
app/corePackage: core (pkgs/ or apps/ in this repo)Package: core (pkgs/ or apps/ in this repo)effort/mMedium: expected under 1 day of workMedium: expected under 1 day of workkind/featureNew feature or capability requestNew feature or capability requestmeta/enrichedIntake review done: acceptance criteria, links, and normalized labels addedIntake review done: acceptance criteria, links, and normalized labels addedpriority/normalOrdinary priority (the default)Ordinary priority (the default)source/humanFiled directly by a humanFiled directly by a human
Activity
dezren39 commentedon Oct 28, 2026
Intake review
smallpool, nestedsmall-100ksub-route workaround).## Acceptance criteriasection restating it has been appended (original body preserved verbatim above it).smallroute to the flat form as the end-to-end proof.kind/feature,priority/normal,effort/m,source/human(author dezren39),status/needs-triage,meta/enriched.46 remaining items
dezren39 commentedon Oct 29, 2026
Lane A resumed task 2913 at awaiting_ci on PR #811 head 2bfb0a6.
CI classification: unit (linux), typecheck, affected, compliance and e2e all pass. basic unit (windows) failed on two tests outside this PR's diff (routes/schema/core only):
upgrade command > is registered in root help(30s timeout) andsubagent observer lifetime > notifies an idle parent exactly once(timing) — the standing windows timing-flake family. Failed jobs of run 40862768919 re-run.Codex gate: all 3 P2 findings dispositioned on their threads — each is already fixed in head 2bfb0a6 (model-resolver.ts:508 last-resort over-limit filter; model-routes.ts:451-462 duplicate-target ceiling merge; generated client types.ts:763 carries
limit?: { context: number }).Task PARKED for the rerun: merge PR #811 (merge commit) once the windows rerun is green, then close out #710 and complete task 2913.
dezren39 commentedon Oct 29, 2026
Triage verdict: CONFIRMED
Verified against current main
a9452a1546(2026-10-28):packages/schema/src/config/model-routes.ts:19-47—TargetObjectcarriesmodel,defaultVariant,variants,until,cache_format,window— nolimitfield, so the requested{ "model": ..., "limit": { "context": 100000 } }target form cannot be expressed at all today.:259-268—limit: { context }exists only onRoute(route-level), described as capping "the context limit the route presents, below every target's own limit".packages/core/src/config/plugin/model-routes.ts:24-35—SourceModelcarries no per-target limit;expand()propagates none; the presented context at:118-119is onlymin(route.limit.context, min leaf context). A grep for context eligibility inmodel-route.ts/model-route-expansion.tsfinds no per-target context check.So the nested
small-100ksub-route workaround in the live config is currently the only way to express mixed ceilings — exactly as filed.Routing: scoped follow-up fix packet enqueued as task 2913 (kind
small_fix, queuerepo-health-opencode-pilot): add per-targetlimittoTargetObject, thread it throughexpand()/SourceModel, compose eligibility with the existing gate/quota/cooldown exclusions with the limit as the recorded skip reason, surface per-element ceilings + skip reasons in the resolved-route dump / route_stats, keep nested-route limits unchanged, and cover mixed-ceiling pools (incl. the flatsmall100k/100k/200k case) with tests.dezren39 commentedon Oct 29, 2026
🤖 Agent note · picked up, revalidated, CI rerun triggered — parked awaiting CI
repo-worker-opencode), OpenChamber scheduled lanequeue/2913-710-per-target-limits, head2bfb0a6686(includes theorigin/mainmerge at 2026-10-29T11:03Z)mergeable=MERGEABLE(mergeStateStatus=BLOCKEDonly because one required check is not green). Issue feat(routes): per-element (per-target) context limits #710 is OPEN with no hard-stop labels; PR feat(core): per-target context limits for model routes #811 is OPEN, not draft, no superseding PR.fail, but the job itself concluded cancelled at 12:51Z after 25 minutes — it never reported a test failure, so this is a cancellation artifact, not a code defect.~/git/fleet/2913-710-per-target-limitsis clean at2bfb0a6686matching origin.