Skip to content

Multi-turn conversation context (stateless history) #148

Description

@rghvgrv

Parent

#145 — Ask Splitzy: personal spending chatbot (self-hosted LLM)

What to build

Multi-turn conversation support: the client sends a bounded window of recent turns with each request, the server trims and threads that history through both the router (so relative references like "and last month?" resolve correctly) and the synthesis step, without persisting any chat state server-side.

Implementation Steps

  1. Request contract — Extend ChatRequest in backend/splitzy-dotnet/DTO/ChatDTO.cs (from Chat foundation: streaming balance intent + router skeleton #146) to { List<ChatTurn> Messages; string NewMessage }, reusing the existing ChatTurn { Role, Content } shape.
  2. History trimming — In backend/splitzy-dotnet/Controllers/ChatController.cs, trim Messages to LlmSettings.MaxHistoryTurns (from Chat foundation: streaming balance intent + router skeleton #146's config) before passing to the orchestrator. No server-side persistence of any kind.
  3. Router context — Update ChatOrchestrator.AskAsync (and IChatOrchestrator) signature to accept the trimmed history and pass it into the router prompt call, so the router can resolve relative time/category references ("and last month?") against the prior turn's resolved params rather than re-deriving them from scratch.
  4. Synthesis context — Pass the trimmed history into ILlmClient.StreamAsync (already accepts IReadOnlyList<ChatTurn> per Chat foundation: streaming balance intent + router skeleton #146) so the final answer reads as a natural continuation of the conversation.
  5. Tests — Extend backend/spllitzy-dotnet-tests/ChatControllerTests.cs: a two-turn scenario where turn 1 asks "how much did I spend on groceries this month" and turn 2 asks "and last month?", asserting the second response resolves to the correct prior month's Food category total.

Agent Routing

agent_routing:
  complexity_hint: medium
  required_capability: balanced
  parallel_safe: false
  cost_preference: balanced
  speed_preference: balanced
  ownership_scope:
    - backend/splitzy-dotnet/DTO/ChatDTO.cs
    - backend/splitzy-dotnet/Controllers/ChatController.cs
    - backend/splitzy-dotnet/Services/Chat/
    - backend/spllitzy-dotnet-tests/
  verification:
    - dotnet test backend/spllitzy-dotnet-tests
    - Manual Swagger two-request sequence exercising a follow-up question

Technical Context Snapshot

Current stack in scope

Dependencies in scope

  • Reuse only, no new packages.
  • New dependency additions allowed for this slice: no.

Architecture alignment

  • Server remains stateless for chat — no new tables, no session store. History lives only in the request payload, matching the resolved requirement that chat state is never persisted server-side.
  • create-git-issue provides routing hints only; it must not assign concrete agent/model names.
  • run-with-it remains the final runtime routing authority.

Integration touchpoints

Acceptance criteria

  • A follow-up question referencing a prior turn ("and last month?") resolves against that turn's context and returns the correct figure.
  • History longer than MaxHistoryTurns is trimmed server-side before reaching the LLM.
  • No chat messages are persisted to the database at any point.

Blocked by

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestready-for-agentImplementation-ready slice for an AFK/agent to pick up

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions