Skip to content

Instantly share code, notes, and snippets.

@vegarsti
Created March 16, 2026 10:30
Show Gist options
  • Select an option

  • Save vegarsti/b2575132d968cb6afb52bdeab5fe4112 to your computer and use it in GitHub Desktop.

Select an option

Save vegarsti/b2575132d968cb6afb52bdeab5fe4112 to your computer and use it in GitHub Desktop.
RFC 0005: Unified Session Storage — concrete record examples per trigger type

Session Storage Record Examples

Each example shows the concrete conversation_records rows written per trigger type. All examples use conv_ABC as the conversation ID.


Common: Session Root

Written once per conversation (lazily, on first trigger). All subsequent main-thread records chain off this.

thread_label: "main"
message_role: "custom"
record_type:  (inherits from trigger, e.g. "email")
parent_id:    null
data:         { "type": "session-root" }
details:      null

Email Trigger

Scenario: User sends email "hello" → agent reads memories → calls ComposeEmail → email sent.

Main thread (4 records)

#0  thread_label: "main"
    message_role: "custom"
    record_type:  "email"
    parent_id:    null
    data:         { "type": "session-root" }
    details:      null

#1  thread_label: "main"
    message_role: "user"
    record_type:  "email"
    parent_id:    → #0
    data:         {
                    "type": "incoming-email",
                    "content": [{ "type": "text", "text": "<email>...<body>hello</body>...</email>\n\n<dynamic-info>...</dynamic-info>\n\n<memories>...</memories>" }]
                  }
    details:      {
                    "type": "email",
                    "from": "Vegard <vegard@gmail.com>",
                    "fromNormalized": "vegard@gmail.com",
                    "to": ["Lefos <lefos@example.lefos.sh>"],
                    "cc": null,
                    "subject": "hello",
                    "body": "hello",
                    "timestamp": 1773405258000,
                    "owner": "external"
                  }

#2  thread_label: "main"
    message_role: "assistant"
    record_type:  "email"
    parent_id:    → #1
    data:         {
                    "content": [{
                      "type": "toolCall",
                      "id": "toolu_01Pg...",
                      "name": "ComposeEmail",
                      "arguments": {
                        "body": "Hi Vegard,\n\nAll systems go!\n\nShine bright,\nLefos",
                        "replyToEmailId": "eml_ABC"
                      }
                    }]
                  }
    details:      null

#3  thread_label: "main"
    message_role: "toolResult"
    record_type:  "email"
    parent_id:    → #2
    data:         {
                    "content": [{ "type": "text", "text": "Email sent successfully: message_id=..." }],
                    "toolCallId": "toolu_01Pg...",
                    "toolName": "ComposeEmail"
                  }
    details:      {
                    "type": "sentEmail",
                    "subject": null,
                    "to": [],
                    "body": "Hi Vegard,\n\nAll systems go!\n\nShine bright,\nLefos",
                    "timestamp": 1773405302058,
                    "from": "lefos@example.lefos.sh",
                    "emailId": "eml_XYZ",
                    "participants": ["lefos@example.lefos.sh", "vegard@gmail.com"]
                  }

Branch branch:eml_ABC (6 records — the full agent loop)

#1  thread_label: "branch:eml_ABC"
    message_role: "user"
    parent_id:    → main #1 (incoming email summary)
    data:         { "content": [{ "type": "text", "text": "<email>...<body>hello</body>...</email>..." }] }
    details:      { "type": "email", "from": "...", ... }

#2  thread_label: "branch:eml_ABC"
    message_role: "assistant"
    parent_id:    → branch #1
    data:         { "content": [{ "type": "toolCall", "name": "ReadFile", "id": "toolu_01UJ...", "arguments": { "path": "/pylib/memories/MEMORIES.md" } }] }

#3  thread_label: "branch:eml_ABC"
    message_role: "toolResult"
    parent_id:    → branch #2
    data:         { "content": [{ "type": "text", "text": "## Preferences\n\n- User prefers..." }], "toolCallId": "toolu_01UJ...", "toolName": "ReadFile" }

#4  thread_label: "branch:eml_ABC"
    message_role: "assistant"
    parent_id:    → branch #3
    data:         { "content": [{ "type": "text", "text": "Still works!" }, { "type": "toolCall", "name": "ComposeEmail", ... }] }

#5  thread_label: "branch:eml_ABC"
    message_role: "toolResult"
    parent_id:    → branch #4
    data:         { "content": [{ "type": "text", "text": "Email sent successfully: ..." }], "toolCallId": "toolu_01Pg...", "toolName": "ComposeEmail" }
    details:      { "type": "sentEmail", "body": "Hi Vegard,...", ... }

#6  thread_label: "branch:eml_ABC"
    message_role: "assistant"
    parent_id:    → branch #5
    data:         { "content": [{ "type": "text", "text": "(Email sent — ready for your next message!)" }] }
    details:      { "type": "internal" }

Email Trigger — No Reply

Scenario: Agent decides no reply is needed.

Main thread (3 records)

#0  (session-root, same as above)

#1  thread_label: "main"
    message_role: "user"
    data:         { "type": "incoming-email", "content": [...] }
    details:      { "type": "email", ... }

#2  thread_label: "main"
    message_role: "custom"
    parent_id:    → #1
    data:         { "type": "no-reply" }
    details:      null

Branch still contains the full agent loop (tool calls, thinking, etc.)


Chat Trigger

Scenario: User sends "what's the weather?" → agent calls WebSearch → responds with text.

Main thread (3 records)

#0  (session-root)

#1  thread_label: "main"
    message_role: "user"
    record_type:  "chat"
    parent_id:    → #0
    data:         {
                    "type": "chat-message",
                    "content": [{ "type": "text", "text": "what's the weather?" }]
                  }
    details:      null

#2  thread_label: "main"
    message_role: "assistant"
    record_type:  "chat"
    parent_id:    → #1
    data:         {
                    "content": [{ "type": "text", "text": "It's 8°C and rainy in Oslo today." }]
                  }
    details:      null

Branch branch:<sessionId> (4 records)

#1  thread_label: "branch:conv_ABC"
    message_role: "user"
    parent_id:    → main #1
    data:         { "content": [{ "type": "text", "text": "what's the weather?" }] }

#2  thread_label: "branch:conv_ABC"
    message_role: "assistant"
    parent_id:    → branch #1
    data:         { "content": [{ "type": "toolCall", "name": "WebSearch", ... }] }

#3  thread_label: "branch:conv_ABC"
    message_role: "toolResult"
    parent_id:    → branch #2
    data:         { "content": [{ "type": "text", "text": "Search results for..." }], "toolCallId": "...", "toolName": "WebSearch" }

#4  thread_label: "branch:conv_ABC"
    message_role: "assistant"
    parent_id:    → branch #3
    data:         { "content": [{ "type": "text", "text": "It's 8°C and rainy in Oslo today." }] }

Chat — Multi-turn (email then chat)

Scenario: Email arrives, agent replies, then user chats in Lefos.

Main thread (6 records)

#0  session-root

#1  incoming-email (user, type: "incoming-email")          parent → #0
#2  assistant + ComposeEmail tool call                      parent → #1
#3  toolResult (sentEmail details)                          parent → #2

#4  chat user message (user, type: "chat-message")          parent → #3
#5  assistant text response                                 parent → #4

Branches:

  • branch:eml_ABC — full email agent loop (hangs off main #1)
  • branch:conv_ABC — full chat agent loop (hangs off main #4)

The chat UI shows only #0–#5. Branch internals are hidden.


Cron Trigger

Scenario: Scheduled weather report cron fires → agent searches web → sends email.

Main thread (4 records)

#0  session-root

#1  thread_label: "main"
    message_role: "user"
    record_type:  "cron"
    parent_id:    → #0
    data:         {
                    "type": "cron-trigger",
                    "content": [{ "type": "text", "text": "<dynamic-info>The current date is 2026-03-14T08:00:04Z...</dynamic-info>\n\nYou are executing a scheduled task..." }]
                  }
    details:      { "type": "cron", "prompt": "Send a weather report for Oslo" }

#2  thread_label: "main"
    message_role: "assistant"
    record_type:  "cron"
    parent_id:    → #1
    data:         {
                    "content": [{
                      "type": "toolCall",
                      "id": "toolu_01HG...",
                      "name": "ComposeEmail",
                      "arguments": { "body": "Good morning! Here's your Oslo weather...", "to": ["vegard@gmail.com"] }
                    }]
                  }

#3  thread_label: "main"
    message_role: "toolResult"
    record_type:  "cron"
    parent_id:    → #2
    data:         {
                    "content": [{ "type": "text", "text": "Email sent: message_id=..." }],
                    "toolCallId": "toolu_01HG...",
                    "toolName": "ComposeEmail"
                  }
    details:      { "type": "sentEmail", "body": "Good morning! Here's your Oslo weather...", ... }

Branch branch:<executionId> — full agent loop (WebSearch, ReadFile, ComposeEmail, etc.)


Messenger (Telegram/Discord) Trigger

Scenario: User sends "hi" on Telegram → agent responds.

Main thread (3 records)

#0  session-root

#1  thread_label: "main"
    message_role: "user"
    record_type:  "telegram"
    parent_id:    → #0
    data:         {
                    "type": "incoming-message",
                    "content": [{ "type": "text", "text": "hi" }]
                  }
    details:      null

#2  thread_label: "main"
    message_role: "assistant"
    record_type:  "telegram"
    parent_id:    → #1
    data:         {
                    "content": [{ "type": "text", "text": "Hey! How can I help?" }]
                  }
    details:      null

Branch branch:<messageId> — full agent loop


Visual: Thread tree structure

MAIN THREAD (thread_label = "main")
│
├── #0 session-root
│
├── #1 📨 incoming-email (from: alice, subject: "hello")
│   │
│   ╰── BRANCH branch:eml_ABC
│       ├── user: full <email> XML
│       ├── assistant: ReadFile(memories)
│       ├── toolResult: memories content
│       ├── assistant: "Still works!" + ComposeEmail(...)
│       ├── toolResult: "Email sent..."
│       ╰── assistant: "(Email sent — ready!)"  [internal]
│
├── #2 🤖 assistant: ComposeEmail tool call (synthetic)
├── #3 📤 toolResult: sent email details
│
├── #4 💬 chat-message: "nice! what happens if I reply here"
│   │
│   ╰── BRANCH branch:conv_ABC
│       ├── user: "nice! what happens if I reply here"
│       ├── assistant: ReadFile(memories)
│       ├── toolResult: memories content
│       ╰── assistant: "You're chatting with me directly..."
│
├── #5 🤖 assistant: "You're chatting with me directly..."
│
⋮
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment