paperclip: add sharedBankName config for cross-agent memory sharing#1589
paperclip: add sharedBankName config for cross-agent memory sharing#1589SeBru1 wants to merge 1 commit into
Conversation
Adds an optional `sharedBankName` string to the paperclip plugin's
instance config. When set, every agent in the company reads/writes
the same Hindsight bank — overriding `bankGranularity` and the
default `paperclip::{companyId}::{agentId}` derivation.
Why
---
The default `bankGranularity: ["company", "agent"]` isolates each
agent's memory. For multi-agent cohorts that need to collaborate on
a shared pool of project context (e.g. a CEO/CTO/Staff/QA/Researcher
team working a single backlog), there's no first-class way to point
them at a single bank without redefining identity.
What
----
- `src/bank.ts`: extend `BankConfig` with `sharedBankName?: string`;
`deriveBankId` returns the trimmed value verbatim when set, falls
through to the existing granularity logic otherwise.
- `src/manifest.ts`: surface `sharedBankName` in `instanceConfigSchema`
so it's configurable from Settings → Plugins → Hindsight Memory.
- `src/worker.ts`: add the field to the internal `PluginConfig` type.
- `tests/plugin.spec.ts`: add unit tests for the override behavior
(trimming, empty/whitespace fallthrough) and an integration-level
test that verifies recall is routed to the shared bank URL when
configured.
- README: document the field and add a "Shared bank for cross-agent
collaboration" section.
Backwards compatible
--------------------
The field is optional. Existing installs (no `sharedBankName` set)
keep the existing `paperclip::{companyId}::{agentId}` derivation
unchanged. All 19 tests pass (3 pre-existing bank tests + 3 new bank
tests + 1 new worker-routing test + the rest of the suite).
|
@SeBru1 thanks! Clean PR and the cross-agent collaboration case is legit. LGTM |
|
@SeBru1 — could you rename sharedBankName → bankId and add a dynamicBankId: boolean to match the pattern the other plugins use? same behavior, but a user moving between paperclip/ claude-code / openclaw would see the same field names mean the same thing. otherwise the implementation looks clean. |
Add bankId and dynamicBankId config fields matching the pattern used by openclaw, claude-code, and opencode. When bankId is set and dynamicBankId is not true, all agents share the same bank — useful for multi-agent cohorts that need collaborative memory. - bank.ts: static override check before dynamic derivation - manifest.ts: add dynamicBankId (boolean) and bankId (string) fields - worker.ts: add fields to PluginConfig type - tests: 5 new tests (static override, trimming, whitespace fallthrough, dynamicBankId=true bypass, integration routing) Inspired by #1589 — thanks @SeBru1 for the original concept. Closes #1589.
|
@SeBru1 thanks for this — the shared-bank use case is exactly right, and the implementation was clean. we've folded it into #1761 with the naming change i mentioned (sharedBankName → bankId/dynamicBankId to match the convention across openclaw, claude-code, and opencode). you're credited in both the commit and the PR description. if you spot anything off in #1761, feel free to comment there. |
…1761) * feat(paperclip): add per-user memory isolation via bankGranularity Add 'user' as a bankGranularity option so each user gets their own isolated memory bank. User identity is extracted from the specific issue being worked on (via originId email or creatorEmail), not from an arbitrary issue list query. - bank.ts: add userId to BankContext, extractUserFromIssue() helper - worker.ts: pass userId through all 4 bank-derivation sites, cache userId in plugin state so tool calls derive the same bank ID - manifest.ts: add 'user' to bankGranularity enum - tests: 6 new tests covering derivation, extraction, and integration Inspired by #1561 — thanks @amirhmoradi for the original concept and initial implementation. * feat(paperclip): add bankId/dynamicBankId for static shared banks Add bankId and dynamicBankId config fields matching the pattern used by openclaw, claude-code, and opencode. When bankId is set and dynamicBankId is not true, all agents share the same bank — useful for multi-agent cohorts that need collaborative memory. - bank.ts: static override check before dynamic derivation - manifest.ts: add dynamicBankId (boolean) and bankId (string) fields - worker.ts: add fields to PluginConfig type - tests: 5 new tests (static override, trimming, whitespace fallthrough, dynamicBankId=true bypass, integration routing) Inspired by #1589 — thanks @SeBru1 for the original concept. Closes #1589. * test(paperclip): add edge-case tests for bank feature interactions 19 additional tests covering: - Feature interaction: static bankId vs user granularity precedence - Static bankId edge cases: special chars, tabs/newlines, empty string - Dynamic derivation edge cases: empty granularity, user-only, duplicates - extractUserFromIssue: null fields, empty strings, multiple emails * style(paperclip): fix lint formatting drift
Summary
Adds an optional
sharedBankNamestring to thehindsight-integrations/paperclipplugin's instance config. When set, every agent in the company reads/writes the same Hindsight bank — overridingbankGranularityand the defaultpaperclip::{companyId}::{agentId}derivation.This is a small, additive, backwards-compatible change. No behavior changes for any existing install that doesn't set the new field.
Motivation
The current
bankGranularity: [\"company\", \"agent\"]default isolates each agent's memory. That's the right default — memory shouldn't leak across unrelated agents.But for multi-agent cohorts that need to collaborate on a shared pool of project context (e.g. a CEO/CTO/Staff/QA/Researcher team working a single backlog), there's no first-class way to point them at one bank.
Concrete use case: I run a 5-agent Paperclip company where each agent must see decisions, lessons, and project state created by the others. With current granularity, each agent talks to its own bank —
hindsight_recallreturns nothing the agent didn't write itself, and cross-agent compound knowledge never accrues.Workarounds I considered:
bankGranularity: [\"company\"]collapses to a per-company bank — but the bank ID is stillpaperclip::{companyId}, which is fine for a single deployment but not when you want a human-readable bank name shared across companies or instances.The cleanest fix is a tiny optional config override. That's this PR.
What changed
src/bank.ts: extendBankConfigwith optionalsharedBankName;deriveBankIdreturns the trimmed value verbatim when set, otherwise falls through to the existing granularity logic unchanged.src/manifest.ts: addsharedBankNametoinstanceConfigSchemaso it's configurable from Settings → Plugins → Hindsight Memory.src/worker.ts: add the field to the internalPluginConfigtype.tests/plugin.spec.ts: 4 new tests — 3 unit tests for the override semantics (trimming, empty/whitespace fallthrough, normal override) + 1 integration test that verifies recall routes to the shared bank URL.README.md: document the field and add a Shared bank for cross-agent collaboration section.Backwards compatibility
The field is optional. Existing installs without
sharedBankNamekeep the existingpaperclip::{companyId}::{agentId}derivation untouched.Test plan
npm run typecheck— cleannpm test— 19/19 tests pass (15 existing + 4 new)npm run build— clean esbuild outputsharedBankName: \"spool-farm\", recall/retain from all 5 agents now route to the singlespool-farmbank.Notes for review
Happy to adjust naming (
sharedBankNamevsbankNamevsbankOverride), schema placement, or split into smaller commits if preferred. The full change is +89/-8 across 5 files.