feat(ai): enforce local-first routing
Keep external providers behind server consent, task, and prompt-cost gates while persisting actual provider provenance.
This commit is contained in:
@@ -65,16 +65,14 @@ and all-time totals; the workspace displays the monthly calls and estimated toke
|
||||
|
||||
## Provider abstraction
|
||||
|
||||
Generation goes through the existing `ISummarizerService` → ai-service, which routes to the active
|
||||
provider (`AI_PROVIDER`: ollama | gemini | groq) — production can offload a weak local GPU to a cloud
|
||||
provider. Each `AiInteraction` records the resolved provider for transparency, and `GET …/ai/modules`
|
||||
returns the current provider so the UI can show it.
|
||||
Generation goes through `ISummarizerService` to the ai-service. Ollama is primary; `AI_PROVIDER` names
|
||||
only the optional external fallback candidate. Fallback is sequential and requires administrator
|
||||
enablement, task approval, live Pro/user consent and the prompt cost/privacy ceiling. Each
|
||||
`AiInteraction` records the provider returned by the sidecar, plus bounded model/route metadata in
|
||||
`ResultJson.meta`; configuration alone is not treated as proof that a provider executed.
|
||||
|
||||
**Per-request user-selectable providers** (module 8's "users can choose provider") is a plumbing
|
||||
extension, not yet wired end-to-end: it needs (a) ai-service to accept a per-request `provider`
|
||||
override and (b) an API **key configured for each selectable provider**. Both are deployment/credential
|
||||
concerns (a live paid key per provider), so the code path is left as a documented extension point
|
||||
rather than shipped half-configured. The abstraction already isolates the change to one method.
|
||||
Per-request user-selectable providers remain intentionally unsupported. The server-side privacy
|
||||
policy selects a route, not the browser, and provider credentials remain deployment-only.
|
||||
|
||||
## Extension points
|
||||
|
||||
@@ -83,8 +81,8 @@ rather than shipped half-configured. The abstraction already isolates the change
|
||||
- **New cover-letter tone**: add to `CoverLetterModes` + `ModeGuidance`.
|
||||
- **Structured (JSON) results**: swap a module's prompt for JSON and parse into `ResultJson.meta`; the
|
||||
UI already renders `result.text` as markdown and can read `meta`.
|
||||
- **User-selectable provider**: thread a `provider` param through `ISummarizerService` →
|
||||
ai-service; gate on the provider having a configured key (see above).
|
||||
- **Provider policy**: add task types to the explicit server-side allowlist only after their payload,
|
||||
accounting and production checks pass; do not add browser provider overrides.
|
||||
|
||||
## Security
|
||||
|
||||
|
||||
Reference in New Issue
Block a user