multi-chat-context-manager
CLI tool to store and retrieve conversation contexts per channel/user.
Packaged view
This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.
Install command
npx @skill-hub/cli install openclaw-skills-multi-chat-context-manager
Repository
Skill path: skills/derick001/multi-chat-context-manager
CLI tool to store and retrieve conversation contexts per channel/user.
Open repositoryBest for
Primary workflow: Ship Full Stack.
Technical facets: Full Stack.
Target audience: everyone.
License: Unknown.
Original source
Catalog source: SkillHub Club.
Repository owner: openclaw.
This is still a mirrored public skill entry. Review the repository before installing into production workflows.
What it helps with
- Install multi-chat-context-manager into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
- Review https://github.com/openclaw/skills before adding multi-chat-context-manager to shared team environments
- Use multi-chat-context-manager for development workflows
Works across
Favorites: 0.
Sub-skills: 0.
Aggregator: No.
Original source / Raw SKILL.md
---
name: multi-chat-context-manager
description: CLI tool to store and retrieve conversation contexts per channel/user.
version: 1.0.2
author: skill-factory
metadata:
openclaw:
requires:
bins:
- python3
---
# Multi-Chat Context Manager
## What This Does
A simple CLI tool to store, retrieve, and clear conversation contexts. Contexts are saved as JSON, keyed by channel/user/thread IDs. This is a utility library, not an auto-integration plugin.
## When To Use
- You need to manually store conversation history per channel or user
- You want a simple key-value context store for your scripts
- You're building custom integrations and need context persistence
## Usage
Store a conversation:
python3 scripts/context_manager.py store --channel "telegram-123" --user "user-456" --message "Hello" --response "Hi there"
Retrieve context:
python3 scripts/context_manager.py retrieve --channel "telegram-123" --user "user-456"
Clear context:
python3 scripts/context_manager.py clear --channel "telegram-123"
List all contexts:
python3 scripts/context_manager.py list
## Examples
### Example 1: Store and retrieve
Store:
python3 scripts/context_manager.py store --channel "discord-general" --user "john" --message "What is AI?" --response "AI is artificial intelligence."
Retrieve:
python3 scripts/context_manager.py retrieve --channel "discord-general" --user "john"
Output:
{
"channel_id": "discord-general",
"user_id": "john",
"history": [{"message": "What is AI?", "response": "AI is artificial intelligence."}]
}
## Requirements
- Python 3.x
- No external dependencies
## Limitations
- This is a CLI tool, not an auto-integration plugin
- Does not automatically intercept messages from platforms
- Stores data in plaintext JSON (not encrypted)
- No file-locking for concurrent access
- You must call it manually from your scripts or workflows
---
## Skill Companion Files
> Additional files collected from the skill directory layout.
### _meta.json
```json
{
"owner": "derick001",
"slug": "multi-chat-context-manager",
"displayName": "Multi-Chat Context Manager",
"latest": {
"version": "1.0.0",
"publishedAt": 1772028252325,
"commit": "https://github.com/openclaw/skills/commit/21e1b95b54c2c81e0138642b2d044a5c3cdbf578"
},
"history": [
{
"version": "1.0.3",
"publishedAt": 1771950802864,
"commit": "https://github.com/openclaw/skills/commit/0d714e0efe7a7252d328fb0c0db97e2c3d19d87a"
}
]
}
```
### scripts/context-manager.sh
```bash
#!/usr/bin/env bash
# Multi-Chat Context Manager - Shell Wrapper
# Usage: context-manager.sh <command> [args]
# Commands: store, retrieve, clear, list
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PYTHON_SCRIPT="${SCRIPT_DIR}/context_manager.py"
# Ensure Python script exists
if [[ ! -f "$PYTHON_SCRIPT" ]]; then
echo "Error: Python script not found at $PYTHON_SCRIPT" >&2
exit 1
fi
# Parse command
COMMAND="$1"
shift
case "$COMMAND" in
store)
# Expect arguments in key=value format for simplicity
CHANNEL=""
USER=""
THREAD=""
MESSAGE=""
RESPONSE=""
MAX_HISTORY="10"
for arg in "$@"; do
case "$arg" in
channel=*) CHANNEL="${arg#*=}" ;;
user=*) USER="${arg#*=}" ;;
thread=*) THREAD="${arg#*=}" ;;
message=*) MESSAGE="${arg#*=}" ;;
response=*) RESPONSE="${arg#*=}" ;;
max_history=*) MAX_HISTORY="${arg#*=}" ;;
*) echo "Unknown argument: $arg" >&2; exit 1 ;;
esac
done
if [[ -z "$CHANNEL" || -z "$MESSAGE" || -z "$RESPONSE" ]]; then
echo "Usage: $0 store channel=<id> message=<text> response=<text> [user=<id>] [thread=<id>] [max_history=<n>]" >&2
exit 1
fi
python3 "$PYTHON_SCRIPT" store \
--channel "$CHANNEL" \
${USER:+--user "$USER"} \
${THREAD:+--thread "$THREAD"} \
--message "$MESSAGE" \
--response "$RESPONSE" \
--max-history "$MAX_HISTORY"
;;
retrieve)
CHANNEL=""
USER=""
THREAD=""
for arg in "$@"; do
case "$arg" in
channel=*) CHANNEL="${arg#*=}" ;;
user=*) USER="${arg#*=}" ;;
thread=*) THREAD="${arg#*=}" ;;
*) echo "Unknown argument: $arg" >&2; exit 1 ;;
esac
done
if [[ -z "$CHANNEL" ]]; then
echo "Usage: $0 retrieve channel=<id> [user=<id>] [thread=<id>]" >&2
exit 1
fi
python3 "$PYTHON_SCRIPT" retrieve \
--channel "$CHANNEL" \
${USER:+--user "$USER"} \
${THREAD:+--thread "$THREAD"}
;;
clear)
CHANNEL=""
USER=""
THREAD=""
for arg in "$@"; do
case "$arg" in
channel=*) CHANNEL="${arg#*=}" ;;
user=*) USER="${arg#*=}" ;;
thread=*) THREAD="${arg#*=}" ;;
*) echo "Unknown argument: $arg" >&2; exit 1 ;;
esac
done
python3 "$PYTHON_SCRIPT" clear \
${CHANNEL:+--channel "$CHANNEL"} \
${USER:+--user "$USER"} \
${THREAD:+--thread "$THREAD"}
;;
list)
python3 "$PYTHON_SCRIPT" list
;;
*)
echo "Usage: $0 {store|retrieve|clear|list} [args]" >&2
echo ""
echo "Examples:"
echo " $0 store channel=telegram-123 message=\"Hello\" response=\"Hi there\" user=user456"
echo " $0 retrieve channel=telegram-123 user=user456"
echo " $0 clear channel=telegram-123"
echo " $0 list"
exit 1
;;
esac
```
### scripts/context_manager.py
```python
#!/usr/bin/env python3
"""
Multi-Chat Context Manager
Store, retrieve, and clear conversation contexts per channel/user.
"""
import json
import os
import sys
import argparse
from pathlib import Path
DEFAULT_STORAGE_PATH = str(Path(__file__).parent.parent / 'data' / 'contexts.json')
def load_contexts():
"""Load contexts from JSON file."""
try:
with open(DEFAULT_STORAGE_PATH, 'r') as f:
return json.load(f)
except (FileNotFoundError, json.JSONDecodeError):
return {}
def save_contexts(contexts):
"""Save contexts to JSON file."""
os.makedirs(os.path.dirname(DEFAULT_STORAGE_PATH), exist_ok=True)
with open(DEFAULT_STORAGE_PATH, 'w') as f:
json.dump(contexts, f, indent=2)
def get_context_key(channel_id, user_id=None, thread_id=None):
"""Generate a unique key for a context."""
key = f"channel:{channel_id}"
if user_id:
key += f":user:{user_id}"
if thread_id:
key += f":thread:{thread_id}"
return key
def store_context(channel_id, user_id=None, thread_id=None, message=None, response=None, max_history=10):
"""Store a message/response pair in context."""
contexts = load_contexts()
key = get_context_key(channel_id, user_id, thread_id)
if key not in contexts:
contexts[key] = {
'channel_id': channel_id,
'user_id': user_id,
'thread_id': thread_id,
'history': []
}
entry = contexts[key]
if message is not None and response is not None:
entry['history'].append({
'message': message,
'response': response,
'timestamp': os.path.getmtime(__file__) # placeholder, could use datetime
})
# Keep only last N entries
if len(entry['history']) > max_history:
entry['history'] = entry['history'][-max_history:]
save_contexts(contexts)
return entry
def retrieve_context(channel_id, user_id=None, thread_id=None):
"""Retrieve context for a channel/user/thread."""
contexts = load_contexts()
key = get_context_key(channel_id, user_id, thread_id)
return contexts.get(key, {})
def clear_context(channel_id=None, user_id=None, thread_id=None):
"""Clear context(s). If no IDs provided, clear all."""
contexts = load_contexts()
if channel_id is None:
contexts.clear()
else:
key = get_context_key(channel_id, user_id, thread_id)
if key in contexts:
del contexts[key]
# Also clear any sub-contexts? For simplicity, just exact match.
save_contexts(contexts)
return {'cleared': True}
def list_contexts():
"""List all stored contexts."""
contexts = load_contexts()
return contexts
def main():
parser = argparse.ArgumentParser(description='Multi-Chat Context Manager')
subparsers = parser.add_subparsers(dest='command', required=True)
# store
store_parser = subparsers.add_parser('store', help='Store a message/response pair')
store_parser.add_argument('--channel', required=True, help='Channel ID')
store_parser.add_argument('--user', help='User ID')
store_parser.add_argument('--thread', help='Thread ID')
store_parser.add_argument('--message', required=True, help='User message')
store_parser.add_argument('--response', required=True, help='Agent response')
store_parser.add_argument('--max-history', type=int, default=10, help='Maximum history entries to keep')
# retrieve
retrieve_parser = subparsers.add_parser('retrieve', help='Retrieve context')
retrieve_parser.add_argument('--channel', required=True, help='Channel ID')
retrieve_parser.add_argument('--user', help='User ID')
retrieve_parser.add_argument('--thread', help='Thread ID')
# clear
clear_parser = subparsers.add_parser('clear', help='Clear context(s)')
clear_parser.add_argument('--channel', help='Channel ID')
clear_parser.add_argument('--user', help='User ID')
clear_parser.add_argument('--thread', help='Thread ID')
# list
subparsers.add_parser('list', help='List all contexts')
args = parser.parse_args()
if args.command == 'store':
result = store_context(
channel_id=args.channel,
user_id=args.user,
thread_id=args.thread,
message=args.message,
response=args.response,
max_history=args.max_history
)
print(json.dumps(result, indent=2))
elif args.command == 'retrieve':
result = retrieve_context(
channel_id=args.channel,
user_id=args.user,
thread_id=args.thread
)
print(json.dumps(result, indent=2))
elif args.command == 'clear':
result = clear_context(
channel_id=args.channel,
user_id=args.user,
thread_id=args.thread
)
print(json.dumps(result, indent=2))
elif args.command == 'list':
result = list_contexts()
print(json.dumps(result, indent=2))
else:
parser.print_help()
sys.exit(1)
if __name__ == '__main__':
main()
```