Phase 1B — Resolved-Route Exposure¶
- Date: 2026-08-02
- Workstream(s): C (resolved-route exposure), cross-referencing Workstream B
- Dataset: 3680 call_logs rows, 2581 usage_history rows. Session tag universally NULL.
Core question: Is the resolved provider/model recorded per request?¶
Verified fact: Yes. The call_logs table has separate columns for requested_model (what the client asked for) and model + provider (what the routing engine selected). The combo framework populates both. The mapping from logical model to resolved route is stored with latency, token usage, and correlation_id for every API call. See the following sample, redacted of any prompt/response content:
requested_model = auto/cheap
model = big-pickle
provider = opencode
combo_name = auto/cheap
combo_step_id = virtual-auto-cheap-30-opencode
duration = 17063 ms
tokens_in = 28577
tokens_out = 1277
Observation: The combo step ID (virtual-auto-cheap-30-opencode) contains the provider name embedded in the step identifier. The combo_name (auto/cheap) matches the logical model the client configured.
Can a statusline consume the resolved route?¶
Option 1: SQLite (read-only)¶
Recommendation: Read SELECT model, provider, combo_name, combo_step_id, duration FROM call_logs WHERE timestamp > '<recent>' ORDER BY timestamp DESC LIMIT 1 against the volume-mounted SQLite file. This is:
- Read-only.
- Does not route traffic.
- Low-latency (<1ms per query).
- Always available as long as the Docker volume is mounted and the container is healthy.
- The volume path co-locates with the OmniRoute container; the host docker engine must be an active Docker Desktop install.
Constraint: On macOS, the SQLite file is in the Docker Desktop VM at …/volumes/omniroute-data/_data/storage.sqlite and is not directly accessible from the host filesystem. A statusline would need either docker exec omniroute sqlite3 ... (which requires Docker permissions and a running container) or docker run --rm -v omniroute-data:/data alpine sqlite3 /data/storage.sqlite ... (which requires pulling an image if not cached, but works regardless of container readiness).
Hypothesis: When the OmniRoute container is down, docker exec fails entirely. docker run --rm -v still works as long as the Docker daemon is running. A statusline could use this as a read-only fallback.
Option 2: Management API (requires management token)¶
Observation: Not available. All management endpoints returned 403 with the gateway token (AUTH_001 "Invalid management token"). A separate management token would be required to call /api/cloud/model/resolve?model=auto/cheap. No such token is currently stored in the local configuration.
Hypothesis: The OmniRoute admin panel has a management key with scope ["manage","grammars"] that would unlock all 403 endpoints. This key is not present in .claude/settings.local.json. It may be set in the OmniRoute admin UI or in the omniroute-data volume's server.env.
Option 3: Gateway token resolution via try-select (live inference)¶
Rejected for Phase 1B. Querying /v1/models returns the catalog but does not expose which provider will be selected for a given combo. Determining the route would require a chat completion, which incurs cost and is not read-only. This option is left for future phases if needed.
Session-level correlation¶
Observation: Not functional in this Installation. session_tag is NULL on all 3680 call_logs rows, and session_model_history has 0 rows. The OmniRoute inspector tool (inspector_sessions, inspector_session_requests) are also empty (0 rows each).
Hypothesis: Session tagging on this installation is not enabled or the client (Claude Code) is not producing a session label that OmniRoute stores. Without session-level correlation, a statusline can report the most recent request route / last route, but not reconstruct per-session model history from OmniRoute logs alone.
Recommendation: A statusline that reports the resolved model/provider would likely be best served by the last call_logs row based on timestamp + api_key_name filter. This fits nominalee the "auto/cheap" display name pattern — show what the most recent request concretely resolved to.
Failure and fallback behavior¶
Generic label situation¶
Verified fact: Claude Code 2.x's statusline contract (from code.claude.com/docs/en/statusline, confirmed in Workstream A) provides only model.id and model.display_name. These reflect the requested model (auto/cheap), not the resolved route. Claude currently does not surface the resolved provider in the statusline input payload — only in the live session transcript. The model.id field is set to the CANONICAL_AUTH_MODEL env var meaning; in this installation, that reads auto/cheap.
Observation: The generic auto/cheap label is not a bug. It is the configured model in .claude/settings.local.json and is what Claude Code passes to the statusline. OmniRoute resolves it to a real provider internally, but the resolution is not reflected back to Claude Code's statusline input.
Database unavailable¶
Hypothesis: If the container is stopped, the SQLite volume still exists and is readable through Docker's volume mount mechanism (e.g., docker run --rm -v omniroute-data:/data alpine sqlite3 /data/storage.sqlite ...), but the docker exec path stops working because the container is not running. Both options require Docker Desktop running on macOS.
Unavailable display¶
Recommendation: A statusline should handle these fallback cases: - Container down: display "no routes available" or similar label. - container running, no rows in call_logs: display a note that the value is unplaced or unavailable. - container running, but last call older than threshold: display "stale" alongside the last known provider. - container running, but SQLite read fails: display "unknown". - None of these should crash the statusline.
Summary of tagged findings¶
| Finding | Tag | Evidence |
|---|---|---|
call_logs.model and call_logs.provider columns capture the post-routing resolved provider/model |
Verified fact | Direct SQLite schema inspection + row samples |
| Management API endpoints are not reachable with the gateway token | Observation | All management endpoints return 403 AUTH_001 |
session_model_history is empty; session_tag on call_logs is always NULL |
Observation | 0 rows in session_model_history, 3680 NULL session_tag values on call_logs |
| A statusline can read resolved provider from SQLite | Recommendation | read-only, no live inference, no token needed |
| A separate management token would unlock the HTTP API path | Hypothesis | Management token exists in api_keys but not in local config |
| The data-flow path for resolved route info goes: OmniRoute gateway appends to SQLite → statusline reads SQLite → statusline renders provider label | Recommendation | Best current path for statusline implementation |
The model.display_name field in status line is auto/cheap (requested, not resolved) |
Observation | Per statusline schema doc, verified in Workstream A findings |