Phase 5: questions endpoint, Anthropic answer model, Answers page #7

Merged
k.renner merged 2 commits from feat/answer-model into main 2026-09-24 14:57:29 +00:00
Member

Stacked on #6 (facts). Retarget to master once that merges.

What

  • IAnswerModel port gets its first adapter: Wiki.Adapters.Anthropic (Messages API, SSE streaming, 429/529 retry, health via GET /v1/models). Registered per Wiki:AnswerModels:Models:<name>, key from Wiki__AnswerModels__Models__<name>__ApiKey.
  • QuestionUseCase (Application): ask (rank + judge) → pick paragraphs carrying probability mass → below the coverage gate emit a Gap and call no model; otherwise stream the answer model over the evidence.
  • SaveAnswerUseCase: writes output/<date>-<slug>.md in the wiki-synth shape (question, sources, confidence, answered_by, covered); numbered suffix on collision.
  • POST /api/v1/questions {question, k, model, judge, answerModel, save}. Anonymous read; save: true needs a signed-in user or an API key (the API-key scheme is authenticated explicitly on that path, since the default scheme is the proxy header).
  • Answers page (MudBlazor): streams the same use case, shows evidence cards, saves on demand, lists saved answers.

Tests

  • 60 contract tests for the Anthropic adapter (mocked SSE), 3 use-case tests (evidence→text→done, gate blocks the model, saved document shape), host endpoint test incl. 400/401/save.
  • dotnet test Wiki.slnx: 124 green.

Follow-up (homelab)

ExternalSecret for the Anthropic key (apps/ai/wiki-anthropic) and an image bump.

🤖 Generated with Claude Code

Stacked on #6 (facts). Retarget to master once that merges. ## What - `IAnswerModel` port gets its first adapter: `Wiki.Adapters.Anthropic` (Messages API, SSE streaming, 429/529 retry, health via `GET /v1/models`). Registered per `Wiki:AnswerModels:Models:<name>`, key from `Wiki__AnswerModels__Models__<name>__ApiKey`. - `QuestionUseCase` (Application): ask (rank + judge) → pick paragraphs carrying probability mass → below the coverage gate emit a **Gap** and call no model; otherwise stream the answer model over the evidence. - `SaveAnswerUseCase`: writes `output/<date>-<slug>.md` in the wiki-synth shape (question, sources, confidence, answered_by, covered); numbered suffix on collision. - `POST /api/v1/questions` `{question, k, model, judge, answerModel, save}`. Anonymous read; `save: true` needs a signed-in user or an API key (the API-key scheme is authenticated explicitly on that path, since the default scheme is the proxy header). - **Answers** page (MudBlazor): streams the same use case, shows evidence cards, saves on demand, lists saved answers. ## Tests - 60 contract tests for the Anthropic adapter (mocked SSE), 3 use-case tests (evidence→text→done, gate blocks the model, saved document shape), host endpoint test incl. 400/401/save. - `dotnet test Wiki.slnx`: 124 green. ## Follow-up (homelab) ExternalSecret for the Anthropic key (`apps/ai/wiki-anthropic`) and an image bump. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
claude-bot added 2 commits 2026-09-24 14:42:38 +00:00
Implements IAnswerModel over Anthropic's streaming Messages API: SSE
parsing (text_delta/usage/error), 429/529 retry with Retry-After or
exponential backoff, and a pure AnswerPrompt.Build for the evidence
and judgements prompt shape. Health check hits GET /v1/models.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
feat(questions): answer questions from wiki evidence with an answer model
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/push/test Pipeline was successful
e6f5c80a3a
POST /api/v1/questions runs ask (rank + judge), selects the paragraphs that
carry probability mass, and streams one answer-model call over them. Below
the coverage gate no model is called and the response names the gap. With
save: true (signed-in user or API key) the answer lands in output/ as a
synth-shaped document with sources, confidence and the answering model.

The Answers page streams the same use case and lists saved answers.
Anthropic is the first IAnswerModel adapter; the answer model is chosen per
request or from Wiki:AnswerModels:Active.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
k.renner closed this pull request 2026-09-24 14:51:06 +00:00
claude-bot reopened this pull request 2026-09-24 14:51:50 +00:00
claude-bot changed target branch from feat/facts to main 2026-09-24 14:51:50 +00:00
Author
Member

Reopened against main after #6 merged (Gitea closed the stacked PRs). #8 has this branch merged in, so merging #7 first is the clean order; merging #8 alone also carries this work.

Reopened against main after #6 merged (Gitea closed the stacked PRs). #8 has this branch merged in, so merging #7 first is the clean order; merging #8 alone also carries this work.
k.renner merged commit f6a2d875e6 into main 2026-09-24 14:57:29 +00:00
k.renner deleted branch feat/answer-model 2026-09-24 14:57:29 +00:00
Sign in to join this conversation.