feat: continue conversation history for ticketless Slack threads#223
Conversation
There was a problem hiding this comment.
Code Review
This pull request enables conversation memory persistence for ticketless Slack threads. Previously, session history was only loaded and saved for ticketed threads. Now, working memory (gollem.History) is persisted per Session (keyed by SessionID) for both ticketed and ticketless threads, allowing conversation context to carry over between turns even when no ticket exists. This change is implemented across the aster and bluebell chat strategies, and corresponding unit tests have been added to verify the behavior. I have no feedback to provide.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Summary
Ticketless Slack threads (an
@warrenmention on a thread that has not been escalated into a ticket) previously lost their AI working memory between turns — the agent appeared to "forget" everything on each new mention.The infrastructure for cross-turn continuation already existed: every ticketless thread is assigned a deterministic Session ID (
slack_ticketless_<hash(channel,thread)>) byResolveSlackSession, and session history is stored keyed by SessionID (v1/sessions/<id>/history.json), independent of any ticket. The only thing preventing continuation was anif !ticketlessguard on both the load and save paths.This PR removes those guards so that working memory is persisted and restored per thread regardless of ticket association.
Changes
pkg/usecase/chat.go—buildChatContextnow loads session history whenever a Session was resolved (if sess != nil), not only for ticketed threads. This is strategy-agnostic, so bothasterandbluebellbenefit.pkg/usecase/chat/bluebell/bluebell.go— the two terminalsaveSessionHistorycalls now run for ticketless threads too (saveSessionHistoryis keyed by SessionID and is a no-op when no Session was resolved).pkg/usecase/chat/aster/aster.go— same change for the default strategy.saveLatestHistory(the ticketID-keyedlatest.jsoncrash-recovery snapshot) remains gated on!ticketless: it requires a ticket and is not used for cross-turn continuation.Scope / impact
Tests
TestBluebellChat_TicketlessSavesSessionHistory/TestAsterChat_TicketlessSavesSessionHistory— ticketless + Session persists history under the SessionID.TestChatFromSlack_TicketlessContinuesConversation— end-to-end viaChatFromSlack: the deterministic Session is reused across mentions and saved history is restored intochatCtx.Historyon the next turn.go vet,golangci-lint,gosec, and the fullgo test ./...suite all pass.Docs
doc/strategy/README.mdgains a "Conversation Memory" section documenting SessionID-keyed working memory and ticketless continuation.