Streaming Hub 0.1

Add chat history and viewer memory to an AI bot

Store recent Twitch chat, preserve per-viewer conversations, and maintain compact long-term profiles for AI replies.

Alpha
AdvancedTwitchAI ProvidersDatabaseUpdated 2026-07-23

Result

The basic AI bot can answer one !bot command at a time, but every request starts without knowledge of the surrounding chat or the viewer's previous conversations. In this guide, you will add both short-term and long-term context with Streaming Hub's Database and Context Storage actions.

The finished setup uses two automations:

  • Chat Logging to Context records every Twitch chat message and keeps a rolling recent-chat window.
  • AI Bot call reads that shared chat, preserves a separate dialogue for each viewer, and periodically condenses older dialogue into a compact viewer profile.

Three files carry the memory:

FilePurposeRetention
Chat/RecentChat.jsonlRecent messages from the entire Twitch chatLast 40 messages
Chat/{event.user.id}.jsonlDialogue between one viewer and the AI botSummarized at 15 entries, then trimmed to 5
Chat/{event.user.id}_profile.jsonlCompact long-term viewer profileRewritten after each summary

Before you start

Complete Build an AI chat bot for Twitch first. Its AI Bot call automation, Twitch connection, AI profile, Call and Store, and Send Message actions are the starting point for this guide.

Step 1. Create a Context Root

Open the Database tab and select Manage Roots. Add a new Root with these settings:

FieldValue
Display NameContext
Root Idcontext
Absolute PathA private local folder of your choice
EnabledOn

Select Validate if you want to confirm that the folder is writable, then select OK.

Create an enabled Context Root that points to a private folder on disk.

The Root defines the safe base folder. Every relative path used later is created underneath it.

Step 2. Capture every Twitch chat message

Return to Automation and create a new automation named Chat Logging to Context. Set its signal to Twitch Chat Message and choose Any for Text Match Mode.

This signal runs for each incoming Twitch chat message, regardless of its contents.

Step 3. Add the chat storage actions

Delete the default Log action, then add two Data actions in this order:

  1. Append JSONL
  2. Trim JSONL

For both actions, select the Context Root and use this Path:

Chat/RecentChat.jsonl

You do not need to create the Chat folder or file manually. Append JSONL creates both when the automation receives its first message.

Step 4. Store a structured chat record

In Append JSONL, enter this value in JSON Object:

Recent chat JSON object
{
"time": "{event.timestampUtc}",
"userId": "{event.user.id}",
"userName": "{event.user.name}",
"text": "{event.text}"
}

Each run appends one compact JSON object as a new line. JSONL is useful here because the automation can add and trim individual messages without rewriting the entire history.

Step 5. Limit the shared chat history

Create a Number variable named chat_context_length and set it to 40.

In Trim JSONL, set Keep Last to:

{vars.chat_context_length}

The automation now appends the newest message and immediately removes entries beyond the selected limit.

Store each chat message as JSONL and keep the most recent 40 entries.

Step 6. Save each viewer's conversation

Return to AI Bot call. After Send Message, add Append JSONL with these settings:

FieldValue
RootContext
PathChat/{event.user.id}.jsonl

Use this JSON Object:

Per-viewer dialogue JSON object
{
"time": "{event.timestampUtc}",
"viewer": "{event.text}",
"llm": "{runtime.ai.last.text}"
}

The viewer ID in the Path gives every viewer a separate dialogue file. Each entry stores the triggering message together with the AI reply produced during the same run.

Step 7. Attach the stored context to AI replies

Open the first Call and Store action, expand Advanced Settings, and add two Context Files:

SourceRootPath
Context Storage FileContextChat/RecentChat.jsonl
Context Storage FileContextChat/{event.user.id}.jsonl

Streaming Hub attaches these files to the model request as contextual sections of the System Prompt. The model can now see both the wider conversation and this viewer's previous exchanges.

Attach shared chat and the current viewer's dialogue before generating the reply.

Step 8. Try a simple per-viewer limit

A viewer's dialogue file will otherwise grow indefinitely. The simple solution is to add Trim JSONL after the per-viewer Append JSONL:

FieldValue
RootContext
PathChat/{event.user.id}.jsonl
Keep Last{vars.dialog_context_length}

Create a Number variable named dialog_context_length and initially set it to 10.

For easier navigation, group chat_context_length and dialog_context_length under a variable group named Chat_Context_Length.

This approach bounds the file, but it permanently discards older dialogue. The remaining steps replace it with profile summarization.

Step 9. Count dialogue before summarizing it

Disable the simple per-viewer Trim JSONL action from Step 8. Add Count JSON/JSONL after the per-viewer Append JSONL:

FieldValue
RootContext
PathChat/{event.user.id}.jsonl
FormatAuto
Count Target Pathruntime.context.last.count

This action stores the number of dialogue entries in Runtime so the automation can decide when summarization is necessary.

Step 10. Run profile maintenance at a threshold

Change dialog_context_length to 15. Add an If action after Count JSON/JSONL with this condition:

LeftOperatorRight
runtime.context.last.countGreaterOrEqual{vars.dialog_context_length}

The profile-maintenance branch runs only when the current viewer reaches 15 stored exchanges.

Count the viewer's dialogue and enter the If body when it reaches the configured threshold.

Step 11. Build the profile-maintenance branch

Inside the If body, add these actions in order:

  1. Call and Store
  2. Trim JSONL
  3. Rewrite JSON

Streaming Hub closes the branch with End If. The model first creates an updated profile, the raw dialogue is then reduced, and the profile file is finally replaced with the new JSON.

Step 12. Generate and store the viewer profile

Configure the new Call and Store action with the same AI profile used by the reply action.

Use this Prompt:

Viewer profile update prompt
Review the attached existing viewer profile and recent dialogue.

Update the viewer profile using only reliable information found in those sources. Preserve important existing information, add useful confirmed details, remove duplication, and discard minor or temporary details.

Return the complete updated profile as the required JSON object.

Use this System Prompt:

Viewer profile system prompt
You maintain a compact long-term profile of a livestream viewer.

The attached context contains:

1. The viewer's existing profile, which may be empty or missing.
2. Recent dialogue between the viewer and the assistant.

Create an updated profile by merging reliable new information from the dialogue into the existing profile.

Rules:

* Preserve important information from the existing profile unless the recent dialogue clearly corrects or contradicts it.
* Prefer stable, reusable information that may improve future conversations.
* Store confirmed facts, recurring interests, preferences, ongoing projects, communication preferences, and useful recurring context.
* Do not store greetings, jokes, isolated reactions, temporary moods, one-time questions, or details that are unlikely to matter later.
* Do not treat the assistant's statements as facts about the viewer.
* Do not invent, assume, diagnose, or infer sensitive personal information.
* Do not record passwords, contact details, addresses, financial information, or other secrets.
* When information is uncertain or mentioned only once without confirmation, omit it.
* Merge duplicate or closely related facts.
* Replace outdated information when a newer statement clearly corrects it.
* Keep descriptions neutral and concise.
* Do not preserve exact quotes unless their wording is essential.
* Keep the entire profile compact. Prefer fewer useful facts over many minor details.
* Maximum total profile length: 2000 characters.

Return only one valid JSON object. Do not use Markdown, comments, explanations, or text outside the JSON.

Use exactly this structure:

{
"summary": "A concise overview of the viewer in no more than 400 characters.",
"facts": [
"Confirmed stable fact"
],
"preferences": [
"Preference useful for future replies"
],
"interests": [
"Recurring interest, hobby, subject, or project"
],
"interactionNotes": [
"Useful communication or interaction preference"
]
}

Use empty arrays when no reliable information is available. Always return every field.

Also configure:

FieldValue
Require JSONEnabled
Target Pathruntime.ai.last.text_profile

Add these Context Files:

SourceRootPath
Context Storage FileContextChat/{event.user.id}.jsonl
Context Storage FileContextChat/{event.user.id}_profile.jsonl

Create one more Number variable named dialog_context_trim and set it to 5.

Configure the Trim JSONL inside the If body:

FieldValue
RootContext
PathChat/{event.user.id}.jsonl
Keep Last{vars.dialog_context_trim}

Configure Rewrite JSON:

FieldValue
RootContext
PathChat/{event.user.id}_profile.jsonl
JSON{runtime.ai.last.text_profile}
FormatAuto

The profile response is written as one JSON object. The dialogue file keeps only the five newest exchanges, while durable information survives in the compact profile.

Summarize at 15 entries, retain the newest 5, and rewrite the compact viewer profile.

Step 13. Use the profile in normal replies

Return to the first Call and Store action that answers the viewer. Add one more Context File:

SourceRootPath
Context Storage FileContextChat/{event.user.id}_profile.jsonl

The reply action now receives three layers of context: recent public chat, recent personal dialogue, and the viewer's compact long-term profile.

Step 14. Group the automations

Create a folder named Chatting with AI and move both automations into it:

  • AI Bot call
  • Chat Logging to Context

The folder keeps the related workflow together without changing how either signal runs. The exported download at the end of this guide contains this complete folder.

Verify the finished system

Test with a separate Twitch viewer account:

  1. Send ordinary chat messages and confirm that Chat/RecentChat.jsonl appears beneath the Context Root.
  2. Send several !bot commands and confirm that a file named with the viewer ID is created.
  3. Open the files from the Database tab and verify that the newest messages and AI replies are appended.
  4. Reach the profile threshold and confirm that the profile file is created, the dialogue is reduced to five entries, and the generated JSON contains every required field.
  5. Send another !bot command and confirm that the model can use information retained in the profile.

If it does not work

  • No files appear: validate the Context Root, confirm it is enabled, and inspect the first failing storage action in Logs.
  • Paths contain literal braces: verify the exact contract and variable syntax, including {event.user.id} and the vars. prefix for project variables.
  • Recent chat grows indefinitely: confirm that Trim JSONL runs after Append JSONL and reads {vars.chat_context_length}.
  • The If branch never runs: inspect runtime.context.last.count and verify that dialog_context_length is a Number.
  • The profile response is not valid JSON: enable Require JSON, keep the strict System Prompt, and inspect the model's raw response in Runtime and Logs.
  • The reply has no long-term memory: add the profile file to the first reply-producing Call and Store, not only to the profile-maintenance action.
  • A profile file is missing on the first run: keep the Context File's missing-data behavior set to continue; the first successful summary will create it.

Adapt it

  • Use different retention variables for busy and quiet channels.
  • Add a scheduled maintenance automation for files belonging to viewers who have not returned.
  • Store separate profiles per platform by adding a service identifier to the Path.
  • Add moderation or manual approval before using stored information in a public reply.

Related

Download the ready-made script

Import it into Streaming Hub, then follow this guide to add your own variables and connect the required services.

Download the contextual AI bot folder