M4-012: In ChatGateway.handleMessage(), call routingEngine.resolve() before
creating a new agent session when no explicit provider/model is supplied.
The routing decision's provider/model are passed to AgentService.createSession().
M4-007: Add sticky per-session /model override via ChatGateway.setModelOverride().
When active, the routing engine is bypassed entirely. CommandExecutorService
handleModel() is updated to set/clear the override. /model clear resets to
automatic routing. /model with no args shows the current override or usage hint.
M4-008: Include routingDecision in the session:info socket event.
Add RoutingDecisionInfo to SessionInfoPayload in @mosaic/types.
useSocket() tracks the routing decision in state and the BottomBar TUI component
displays a "Routed: <model> (<reason>)" line when a routing decision is present.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add routing.dto.ts with validation DTOs for create, update, and reorder operations
- Add routing.controller.ts with full CRUD: GET list, POST create, PATCH update,
DELETE remove, PATCH reorder, GET effective (merged priority view)
- Users can only create/modify/delete their own user-scoped rules; system rules are
protected with ForbiddenException
- GET /api/routing/rules/effective returns merged rule set with user rules taking
precedence over system rules at the same priority level (M4-010)
- Extend agent-config.dto.ts with capability shorthand fields: domains, preferredModel,
preferredProvider, toolSets (M4-011)
- Update agent-configs.controller.ts to merge capability fields into config.capabilities
so agent's preferred model/provider can influence routing decisions
- Register RoutingController in agent.module.ts
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>