Skip to content

feat(http): support persistent sessions via X-GoClaw-User-Id header#713

Open
olbboy wants to merge 1 commit intonextlevelbuilder:mainfrom
olbboy:feat/http-persistent-sessions
Open

feat(http): support persistent sessions via X-GoClaw-User-Id header#713
olbboy wants to merge 1 commit intonextlevelbuilder:mainfrom
olbboy:feat/http-persistent-sessions

Conversation

@olbboy
Copy link
Copy Markdown

@olbboy olbboy commented Apr 5, 2026

Summary

HTTP /v1/chat/completions endpoint now supports persistent sessions when X-GoClaw-User-Id header is provided. Without the header, behavior is unchanged (stateless, random session per request).

Problem

Every HTTP API request creates a new session (random UUID in session key), even when the same user sends multiple messages. The agent always responds as if it was a new conversation — no memory of previous messages.

Root cause: Session key includes runID[:8] (random UUID per request):

// Before: always random
sessionSuffix = "http-" + userID + "-" + runID[:8]
sessionKey = SessionKey(agentID, sessionSuffix)

This is the only channel without persistent sessions — Telegram, Discord, Slack, Zalo all use stable session keys.

Solution

When X-GoClaw-User-Id is present, build a stable session key using the canonical BuildSessionKey() — same pattern as all other channels:

// After: stable per user
if userID != "" {
    sessionKey = sessions.BuildSessionKey(agentID, "http", sessions.PeerDirect, userID)
    // → "agent:{id}:http:direct:{userId}" — same format as telegram/slack/discord
} else {
    sessionKey = sessions.SessionKey(agentID, "http-"+runID[:8])
    // → unchanged stateless behavior
}

Impact

  • Backward compatible: No X-GoClaw-User-Id header → behavior unchanged
  • No key collision: http:direct: prefix is unique among all channels
  • No cross-channel interference: Telegram/Slack/Discord sessions unaffected
  • Session lifecycle: Same as Telegram — compaction, history limits, token tracking all work

Test Plan

  • HTTP with X-GoClaw-User-Id: user1 → send "I'm Alice" → send "What's my name?" → agent remembers
  • HTTP without header → each request independent (existing behavior)
  • Different userIDs → different sessions (isolation)
  • Telegram/Slack sessions unaffected
  • Concurrent requests from same user → same session

Use Case

Enables integration with Microsoft Teams (and any HTTP client) where a bridge bot sends X-GoClaw-User-Id header with the Teams user ID, maintaining conversation history across messages.

When X-GoClaw-User-Id header is provided, build a stable session key
using BuildSessionKey() — same canonical format as Telegram, Discord,
Slack channels. This allows HTTP API clients to maintain conversation
history across multiple requests.

Without the header, behavior is unchanged (random session per request).

Session key format:
  With userId: agent:{id}:http:direct:{userId}  (persistent)
  Without:     agent:{id}:http-{random}          (stateless)
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