Skip to content

Remove the chat surface from the AI service - #218

Merged
daniilperkin merged 4 commits into
devfrom
refactor/207-remove-chat
Oct 6, 2026
Merged

daniilperkin merged 4 commits into
devfrom
refactor/207-remove-chat

Conversation

@daniilperkin

Copy link
Copy Markdown
Contributor

The AI-service leg of retiring the chat surface: /api/v1/chat, ChatAgent, ChatOrchestrator and the chat CLI are removed in one piece. The buddy is untouched — same retrieval stack, same BuddyStreamEvent contract.

Closes #207. Part of the coordinated retirement across the repos — sprintstart-frontend#206 retires /chat in the UI and SprintStartProject/sprintstart-backend#283 deletes the chat tables — so this should not merge ahead of those.

What goes

  • POST /api/v1/chat and the SSE streaming path behind it
  • ChatAgent, ChatOrchestrator and their prompts
  • scripts/chat_cli.py and the sprintstart chat command
  • ChatRequest / HistoryEntry and the legacy prompt/context field acceptance
  • chat-only docstrings across the service

What stays, and why

Tests

  • golden retrieval + image ingest integration tests re-pointed to rag.retriever.retrieve
  • source-exclusion regression moved to the buddy route, +1 case (a disabled connector cannot reach the buddy's context)
  • removed with their subjects: tests/api/test_chat.py, tests/agents/test_chat_agent.py, tests/agents/test_orchestrator.py

Gates

  • uv run ruff format --check . — clean
  • uv run ruff check . — clean
  • uv run python -m pyright src/ — 0 errors, 0 warnings
  • uv run python -m pytest — 1037 passed, 7 skipped

The chat surface is retired on the frontend (sprintstart-frontend#206) — /chat
redirects to the buddy and nothing calls /api/v1/chat any more — so the
service side goes in one piece rather than as a route that outlives the UI
that stopped asking for it.

What goes: the /api/v1/chat route with its SSE path, ChatAgent and
ChatOrchestrator, the chat CLI (scripts/chat_cli.py, `sprintstart chat`)
that was their only non-HTTP caller, ChatRequest/HistoryEntry and the
legacy-field validator in schemas.py (the `prompt`/`context` acceptance
existed for pre-rename clients), and the chat-only docstrings that
referenced any of it.

What stays, and why: the buddy runs on the same retrieval stack and the
same SSE event shapes, so `agents/__init__.py` stays as the package root,
`ChatFilters` still describes the buddy request's filters, and
BuddyStreamEvent is untouched. The shared `chat_stream` client primitive
keeps its tests — only its docstrings stopped claiming a chat agent.

The README is deliberately left alone: it has an open rewrite (#216), and
folding prose about the service's entry points into a removal would make
both harder to review.
The golden-retrieval and image-ingest integration tests spoke HTTP to
/api/v1/chat because that was the one entry point exercising the full
stack. With the endpoint gone, the same coverage calls the retrieval layer
directly (rag.retriever.retrieve) — the pipeline the buddy itself runs —
so the assertions still watch real behaviour instead of a second, thinner
client path.

The source-exclusion regression test moves to the buddy route, which is
where exclusions are applied now, and gains a case proving a disabled
connector's material cannot reach the buddy's context. The chat route's
own test file and the agent/orchestrator unit tests go with the code they
tested; the dependency-graph test keeps its subject and drops the chat
route from its docstring.
@daniilperkin

Copy link
Copy Markdown
Contributor Author

A note for whoever merges or rebases this after the README work: PR #216 (docs/rewrite-readme) is still open, and its branch's README plus docs/api.md still describe /api/v1/chat and a "Chat stream events" section. This PR deliberately leaves the README alone — the sweep belongs in #216 or a follow-up once it lands.

Two caveats from the implementation run, for the merge window:

  • The two integration tests re-pointed here (golden retrieval, image ingest) could not run end-to-end in the implementation environment — Ollama is unreachable there, so they skip. They collect cleanly and the call pattern (rag.retriever.retrieve, filename mapping, min_score floor) was smoke-verified with the project's stubs; a real-Ollama run before merge is advisable.
  • One pre-existing flake was observed once in five full-suite runs: tests/store/test_chroma_store.py::test_chroma_query_applies_exclusions_before_the_top_k_cutoff (approximate HNSW search + selective where; untouched by this change, passes standalone and in all subsequent runs). Flagging so CI noise isn't attributed to this PR.

- Drop rag.prompt.build_messages, dead since the /chat route went
- Re-word stale chat references in the CLI client, chroma_store and tests
- Rename test_empty_source_systems_mean_all_as_they_did_for_chat
@daniilperkin
daniilperkin marked this pull request as ready for review October 6, 2026 20:51
@daniilperkin
daniilperkin requested a review from kiranfin October 6, 2026 20:53
- Add route-level tests that another project's chunks and chunks with no project are neither seen by the model nor cited (search_docs + grep, with and without filters), and that an empty project_ids admits nothing
- Drop the chat() helper from tests/api/test_client.py, the last caller of /api/v1/chat

@kiranfin kiranfin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review

The removal itself is clean: chat route, agent, orchestrator, factory, CLI, ChatRequest/HistoryEntry and build_messages are gone with no dangling imports, the buddy path is untouched, and the gates reproduce locally (ruff format/check clean, pyright src/ 0 errors, pytest 1043 passed / 7 skipped). Re-pointing the golden and image integration tests also fixes something the description doesn't mention: they were posting to /chat without a projectId, so they could only ever have 422'd. The new source-exclusion test does its job: dropping exclusions=source_state.get_exclusions() from the buddy route makes it fail. What's left is about tests that were deleted along with test_chat.py without being moved over, and about the documentation scope from #207.

🟡 Worth a look

  1. Deferring the README to #216 leaves the documented API wrong after both PRs merge — README.md:80, README.md:91-110
    #207's scope explicitly includes updating README.md together with AGENTS.md. This PR leaves it to #216, but #216's current head (a235e12) still documents the removed surface: uv run python scripts/sprintstart.py chat (README:71), a "Chat agent" node in the architecture diagram (README:86), "Chat and the buddy are agentic" (README:98), agents/ chat agent and its tools (README:125), and in docs/api.md the POST /chat row (:26) plus a whole "Chat stream events" section (:63-65). So whichever PR merges second, the published docs will describe an endpoint and a CLI command that no longer exist. Either remove the /api/v1/chat row, the "Chat SSE stream" section and /chat from the projectId list here, or get an explicit commitment on #216 (a checkbox or comment) that its rebase drops them, and link it from this PR.
  2. ChatFilters request validation lost its only tests, even though the schema stays — src/api/schemas.py:262-286, src/api/schemas.py:1411
    The description says the deleted tests went "with their subjects", but ChatFilters is kept and is now validated only through BuddyAgentRequest.filters. test_chat_accepts_a_bitbucket_source_filter, test_chat_accepts_a_notion_source_filter and test_chat_still_rejects_an_unknown_source_filter (GITLAB → 422) were the only tests of that contract at the request boundary, and nothing in tests/ references ChatFilters or a rejected source system anymore. The per-source exclusion combined with narrowing (test_chat_applies_source_exclusions_with_retrieval_filters, which uses set_sources_enabled) is also only covered below the route now. Moving these to /onboarding/buddy/agent is cheap.
  3. The re-pointed golden/image tests run unscoped retrieval, which no production caller does — tests/rag/test_golden.py:36-63, :81-83, :106, tests/api/test_ingest_image.py:127-132
    The corpus is ingested without project_ids and queried with retrieve(..., filters=None), so matches_retrieval_filters returns True without checking anything. The docstring says this is "the pipeline the buddy itself runs", but under the buddy's fail-closed project_ids scope this corpus would be invisible, and the buddy also adds drop_test_material and its own _TOP_K/_MIN_SCORE (src/onboarding/buddy_agent.py:75-78, :207). As written, the golden suite can pass while the buddy finds nothing for the same questions. Ingesting with a project_ids value and retrieving with RetrievalFilters(project_ids=frozenset({...})) would make these tests check what production actually does. Otherwise, please change the docstring so it doesn't claim parity.

🟢 Nits / cleanup

  • Chat references that still describe the deleted agent in the present tense: src/onboarding/buddy_agent.py:7-8 ("They are the chat agent's own tools … loses nothing chat had"), :193 ("as the chat agent does"), :265-268 ("Chat's retrieve … what chat had"), src/rag/retriever.py:7 ("every caller (chat, agent tools, and onboarding)"), and tests/agents/test_evidence.py:3.
  • agents.tools.base.Invocation (src/agents/tools/base.py:20-23) was only ever emitted by ChatAgent.run. It's now dead and only re-exported from src/agents/tools/__init__.py. Removing it fits "No dead imports of chat_agent / orchestrator".
  • test_a_disabled_connector_is_neither_searched_nor_cited only checks citations. The response messages include the tool result the model saw, so also asserting that no message mentions excluded.md would back up the "cannot reach the buddy's context" claim in the description, not just "not cited".

Overall, the deletion is careful and the service builds cleanly without the chat surface. None of the points above blocks the code: 1 needs either a fix here or a recorded commitment on #216, and 2–3 can be addressed here or explicitly accepted as follow-ups. Approving on the condition that merge order is respected: sprintstart-backend dev still calls /api/v1/chat from ChatAiClient.kt:71, and pushes to dev publish the image, so this should only be merged after sprintstart-backend#283 and sprintstart-frontend#318 have landed.

@daniilperkin
daniilperkin merged commit 5acd4cb into dev Oct 6, 2026
4 checks passed
@daniilperkin
daniilperkin deleted the refactor/207-remove-chat branch October 6, 2026 21:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants