Repository navigation
feat(eu): route AI through OpenRouter's EU endpoint and turn chat back on - #1052
Confidence 3/5 · Quality 100/100 · No issues found
| Confidence | Quality | Open findings | Commit |
|---|---|---|---|
| 3/5 · needs attention | 100/100 · excellent | none | 76d64e9 |
Why 3/5: I verified the EU endpoint/model plumbing in apps/ai/src/platform/Llm.ts and its env wiring, but the truncated web hunks (dashboard-layout.tsx, chat.tsx, region.ts) and the EU behaviour of the non-chat consumers of DecisionModel were not fully read.
Warning
This review ended early; what follows is what it established.
The EU instance now routes every OpenRouter call to https://eu.openrouter.ai/api/v1 when MAPLE_REGION=eu and switches its chat, triage and review defaults to openai/gpt-6-luna, which has an EU provider; Jev's decision model has none, so resolveDecisionModel returns undefined there and the triage route fails closed. The web change undoes #997's instance guard, re-enabling the global chat sheet, the ⌘K action, widget "fix with AI" and the header button everywhere. As written it looks safe: the region flag is derived into the AI worker's env, the model ids and limits are registered, and the new EU path is covered by tests.
layerLlmnow builds itsOpenRouterClientagainstopenRouterApiUrl(env), picking the EU in-region endpoint fromMAPLE_REGION(Llm.ts:505, 72-75)resolveTriageModelandresolveReviewModelfall back toEU_DEFAULT_OPENROUTER_MODEL/EU_DEFAULT_REVIEW_MODELin the EU, andMODEL_LIMITSgainsopenai/gpt-6-luna(Llm.ts:208-210, 408-409)resolveDecisionModelreturns undefined in the EU unlessMAPLE_DECISION_MODELis set, sotriage.http.tsanswersIncidentTriageModelErrorinstead of calling a model with no EU provider- Web chat is re-enabled on all instances:
aiChatEnabledis deleted fromlib/region.tsand its guards are removed from the chat sheet, command palette, widget actions and dashboard layout
What was checked
MAPLE_REGIONactually reaches the AI worker'sLlmEnv: it is derived inselfObservabilityEnv(packages/infra/src/env.ts:222) and that env is merged into the worker's bindings (apps/ai/src/worker.ts:104)- The EU branch of
resolveTriageModelis the only caller of the new default and keepsMAPLE_TRIAGE_MODEL_OPENROUTERas the override (apps/ai/src/platform/Llm.ts:408) - Removing
aiChatEnabledfromlib/region.tsleaves no dangling references — a repo-wide grep for the symbol returns nothing at the head SHA - The EU routing and model-id assertions are exercised by the new tests (
https://eu.openrouter.ai/api/v1/chat/completions,openai/gpt-6-luna)
Observability coverage: 1 of 1 changes observable
| Change | Kind | Observable | Evidence |
|---|---|---|---|
| OpenRouter chat/completions call routed by region | outbound HTTP call | yes | Existing client instrumentation: instrumentedModel wraps every model layer with LanguageModel spans and provider attribution (apps/ai/src/platform/Llm.ts:343-352), so the EU URL swap is visible on the same spans as before |
Updated on every push. Resolve a thread or reply "won't fix" to dismiss a finding, or mention @maple to ask about one. Confidence is the reviewer's judgement of merge risk, capped at 2 by a critical finding and 3 by a warning. Quality: 100, minus 25 per critical finding, 10 per warning and 2 per note still open.