feat: perUserContext — per-user conversation isolation in group chats#324
Open
HuaweiREN wants to merge 13 commits into
Open
feat: perUserContext — per-user conversation isolation in group chats#324HuaweiREN wants to merge 13 commits into
HuaweiREN wants to merge 13 commits into
Conversation
* feat(installer): allow custom install directory via --dir / -Dir flag install.sh and install.ps1 previously hardcoded the install path to $HOME/metabot. Add a CLI flag (and matching PowerShell parameter) plus an interactive prompt so users can install MetaBot anywhere. - Priority: --dir / -Dir > METABOT_HOME env var > prompt > default. - Tilde expansion + absolute-path validation; refuses to clobber $HOME / system roots. - Persists METABOT_HOME to ~/.bashrc / ~/.zshrc (Linux/macOS) or user-level env (Windows) when non-default, so the mm/mb/metabot CLIs can locate the install in new shells. * fix(codex): show model metadata in cards * fix(codex): mirror skills and avoid bwrap sandbox * fix(codex): tolerate agents deployment failures * fix(codex): install bundled skills when user cache is empty * docs: explain Codex skill migration * feat(cluster): add federated identity foundation --------- Co-authored-by: Flood Sung <floodsung@xvirobotics.ai>
* feat(installer): allow custom install directory via --dir / -Dir flag install.sh and install.ps1 previously hardcoded the install path to $HOME/metabot. Add a CLI flag (and matching PowerShell parameter) plus an interactive prompt so users can install MetaBot anywhere. - Priority: --dir / -Dir > METABOT_HOME env var > prompt > default. - Tilde expansion + absolute-path validation; refuses to clobber $HOME / system roots. - Persists METABOT_HOME to ~/.bashrc / ~/.zshrc (Linux/macOS) or user-level env (Windows) when non-default, so the mm/mb/metabot CLIs can locate the install in new shells. * fix(codex): show model metadata in cards * fix(codex): mirror skills and avoid bwrap sandbox * fix(codex): tolerate agents deployment failures * fix(codex): install bundled skills when user cache is empty * docs: explain Codex skill migration * feat(memory): add namespace scoped instance token --------- Co-authored-by: Flood Sung <floodsung@xvirobotics.ai>
* feat(installer): allow custom install directory via --dir / -Dir flag install.sh and install.ps1 previously hardcoded the install path to $HOME/metabot. Add a CLI flag (and matching PowerShell parameter) plus an interactive prompt so users can install MetaBot anywhere. - Priority: --dir / -Dir > METABOT_HOME env var > prompt > default. - Tilde expansion + absolute-path validation; refuses to clobber $HOME / system roots. - Persists METABOT_HOME to ~/.bashrc / ~/.zshrc (Linux/macOS) or user-level env (Windows) when non-default, so the mm/mb/metabot CLIs can locate the install in new shells. * fix(codex): show model metadata in cards * fix(codex): mirror skills and avoid bwrap sandbox * fix(codex): tolerate agents deployment failures * fix(codex): install bundled skills when user cache is empty * docs: explain Codex skill migration * feat(skills): track owner metadata and hashes --------- Co-authored-by: Flood Sung <floodsung@xvirobotics.ai>
* feat(installer): allow custom install directory via --dir / -Dir flag install.sh and install.ps1 previously hardcoded the install path to $HOME/metabot. Add a CLI flag (and matching PowerShell parameter) plus an interactive prompt so users can install MetaBot anywhere. - Priority: --dir / -Dir > METABOT_HOME env var > prompt > default. - Tilde expansion + absolute-path validation; refuses to clobber $HOME / system roots. - Persists METABOT_HOME to ~/.bashrc / ~/.zshrc (Linux/macOS) or user-level env (Windows) when non-default, so the mm/mb/metabot CLIs can locate the install in new shells. * fix(codex): show model metadata in cards * fix(codex): mirror skills and avoid bwrap sandbox * fix(codex): tolerate agents deployment failures * fix(codex): install bundled skills when user cache is empty * docs: explain Codex skill migration * feat(cluster): bootstrap peers from cluster url --------- Co-authored-by: Flood Sung <floodsung@xvirobotics.ai>
* feat(installer): allow custom install directory via --dir / -Dir flag install.sh and install.ps1 previously hardcoded the install path to $HOME/metabot. Add a CLI flag (and matching PowerShell parameter) plus an interactive prompt so users can install MetaBot anywhere. - Priority: --dir / -Dir > METABOT_HOME env var > prompt > default. - Tilde expansion + absolute-path validation; refuses to clobber $HOME / system roots. - Persists METABOT_HOME to ~/.bashrc / ~/.zshrc (Linux/macOS) or user-level env (Windows) when non-default, so the mm/mb/metabot CLIs can locate the install in new shells. * fix(codex): show model metadata in cards * fix(codex): mirror skills and avoid bwrap sandbox * fix(codex): tolerate agents deployment failures * fix(codex): install bundled skills when user cache is empty * docs: explain Codex skill migration * docs: document federated memory and skill hub --------- Co-authored-by: Flood Sung <floodsung@xvirobotics.ai>
* feat(installer): allow custom install directory via --dir / -Dir flag install.sh and install.ps1 previously hardcoded the install path to $HOME/metabot. Add a CLI flag (and matching PowerShell parameter) plus an interactive prompt so users can install MetaBot anywhere. - Priority: --dir / -Dir > METABOT_HOME env var > prompt > default. - Tilde expansion + absolute-path validation; refuses to clobber $HOME / system roots. - Persists METABOT_HOME to ~/.bashrc / ~/.zshrc (Linux/macOS) or user-level env (Windows) when non-default, so the mm/mb/metabot CLIs can locate the install in new shells. * fix(codex): show model metadata in cards * fix(codex): mirror skills and avoid bwrap sandbox * fix(codex): tolerate agents deployment failures * fix(codex): install bundled skills when user cache is empty * docs: explain Codex skill migration * fix(cli): use instance memory token --------- Co-authored-by: Flood Sung <floodsung@xvirobotics.ai>
* feat(installer): allow custom install directory via --dir / -Dir flag install.sh and install.ps1 previously hardcoded the install path to $HOME/metabot. Add a CLI flag (and matching PowerShell parameter) plus an interactive prompt so users can install MetaBot anywhere. - Priority: --dir / -Dir > METABOT_HOME env var > prompt > default. - Tilde expansion + absolute-path validation; refuses to clobber $HOME / system roots. - Persists METABOT_HOME to ~/.bashrc / ~/.zshrc (Linux/macOS) or user-level env (Windows) when non-default, so the mm/mb/metabot CLIs can locate the install in new shells. * fix(codex): show model metadata in cards * fix(codex): mirror skills and avoid bwrap sandbox * fix(codex): tolerate agents deployment failures * fix(codex): install bundled skills when user cache is empty * docs: explain Codex skill migration * Cache peer Skill Hub artifacts --------- Co-authored-by: Flood Sung <floodsung@xvirobotics.ai>
Co-authored-by: Flood Sung <floodsung@xvirobotics.ai>
* Mirror peer MetaMemory documents * Add stable bot memory namespaces --------- Co-authored-by: Flood Sung <floodsung@xvirobotics.ai>
* Mirror peer MetaMemory documents * Add stable bot memory namespaces * Update lark CLI via metabot update --------- Co-authored-by: Flood Sung <floodsung@xvirobotics.ai>
When a bot opts in via `perUserContext: true`, conversation state (session, persistent executor, message queue, running task) is keyed by `chatId:userId` instead of `chatId`. This gives each Feishu member in a group chat their own Claude thread. Changes: - composeScopeKey / chatIdFromScopeKey / userIdFromScopeKey helpers - SessionManager, ExecutorRegistry: opaque scopeKey parameter - MessageBridge: thread scopeKey through all conversation-state Maps - CommandHandler: /reset, /stop, /status, /model scoped by caller - ExecutorRoutes: adjusted for scopeKey - Config: perUserContext bot flag wired through JSON loader - Tests: compose-key (8 tests) + per-user-context (12 tests) - Bump default executor pool cap 20 -> 50 for per-user multiplier Back-compat: default false/undefined preserves byte-for-byte identical behavior. Existing session JSON files load unchanged.
- Add perUserContext to CLAUDE.md Configuration section - Add perUserContext example to bots.example.json - Enable perUserContext: true for Baymax in bots.json
Thread msg.userId through ApiContext so the Claude executor (and the persistent variant) can mention "The current user's ID is <open_id>" in the system prompt appendix. Groundwork for per-user context keying — the userId is now reliably available on the wire end-to-end.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When a bot opts in via
perUserContext: true, conversation state (Claude session, persistent executor, message queue, running task) is keyed bychatId:userIdinstead of barechatId. Each Feishu member in a group chat gets their own independent Claude thread.Motivation
In the default MetaBot group chat mode, all members share a single Claude session. This causes:
/resetwipes User B's conversation/modelswitch affects everyoneThe
perUserContextflag solves this while preserving backward compatibility.Changes
1. Scope Key Composition (
src/session/compose-key.ts— new)composeScopeKey(chatId, userId, perUserContext)→ composite key with helperschatIdFromScopeKey()anduserIdFromScopeKey().2. Session Manager (
src/engines/claude/session-manager.ts)All methods accept opaque
scopeKey. JSON persistence unchanged — backward compatible.3. Executor Registry (
src/engines/claude/executor-registry.ts)Pool keyed by
scopeKey; cap bumped 20→50 for per-user multiplier.4. Message Bridge (
src/bridge/message-bridge.ts)All conversation-state Maps keyed by
scopeKey.isBusy(chatId)scans scopeKey prefixes.5. Command Handler (
src/bridge/command-handler.ts)/reset,/stop,/status,/modelall scoped by caller./statusshows User field.6. System Prompt (
src/engines/claude/executor.ts,persistent-executor.ts)userIdthreaded throughApiContextinto system prompt:The current user's ID is "ou_xxx".7. Config (
src/config.ts)BotConfigBase.perUserContext?: boolean— defaults to false. Wired through JSON loader.Backward Compatibility
perUserContext: false→ byte-for-byte identicalTests
tests/compose-key.test.ts: 8 teststests/per-user-context.test.ts: 12 testsFiles Changed
src/session/compose-key.ts(new)src/config.tssrc/bridge/command-handler.tssrc/bridge/message-bridge.tssrc/engines/claude/session-manager.tssrc/engines/claude/executor-registry.tssrc/engines/claude/executor.tssrc/engines/claude/persistent-executor.tssrc/api/routes/executor-routes.tstests/compose-key.test.ts(new)tests/per-user-context.test.ts(new)11 files, +716 −283