@shodocan/opencode-hindsight 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +673 -0
- package/deploy/.env.example +22 -0
- package/deploy/README.md +56 -0
- package/deploy/docker-compose.yml +24 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +490 -0
- package/dist/config.d.ts +25 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15130 -0
- package/dist/services/client.d.ts +102 -0
- package/dist/services/client.d.ts.map +1 -0
- package/dist/services/compaction.d.ts +73 -0
- package/dist/services/compaction.d.ts.map +1 -0
- package/dist/services/context.d.ts +14 -0
- package/dist/services/context.d.ts.map +1 -0
- package/dist/services/jsonc.d.ts +7 -0
- package/dist/services/jsonc.d.ts.map +1 -0
- package/dist/services/logger.d.ts +2 -0
- package/dist/services/logger.d.ts.map +1 -0
- package/dist/services/privacy.d.ts +4 -0
- package/dist/services/privacy.d.ts.map +1 -0
- package/dist/services/tags.d.ts +86 -0
- package/dist/services/tags.d.ts.map +1 -0
- package/dist/types/index.d.ts +33 -0
- package/dist/types/index.d.ts.map +1 -0
- package/package.json +64 -0
package/README.md
ADDED
|
@@ -0,0 +1,673 @@
|
|
|
1
|
+
# @shodocan/opencode-hindsight
|
|
2
|
+
|
|
3
|
+
**Shodocan OpenCode Hindsight plugin** — Agent-aware persistent memory for OpenCode AI coding assistants.
|
|
4
|
+
|
|
5
|
+
> This package is the **Shodocan** distribution of the OpenCode Hindsight plugin, published as `@shodocan/opencode-hindsight` on npm. It is **not** the vanilla Vectorize Hindsight plugin. The Hindsight server remains a separate backend that you deploy independently; this plugin is the OpenCode integration layer that connects agents to Hindsight memory.
|
|
6
|
+
|
|
7
|
+
Your agent remembers what you tell it — across sessions, across projects.
|
|
8
|
+
|
|
9
|
+
## Shodocan Changes
|
|
10
|
+
|
|
11
|
+
Compared to the vanilla `opencode-hindsight` plugin, this distribution adds:
|
|
12
|
+
|
|
13
|
+
- **Agent-aware project bank routing** — subagents and the main agent use separate project banks via `agentProjectBanks` (exact name and `*` glob patterns), so review agents and build agents keep their memories isolated.
|
|
14
|
+
- **Runtime bank aliases** — `runtimeProjectBanks` defines allowlisted per-tool-call bank aliases (`bankAlias`) so an agent can query other projects' banks in a single call without reconfiguration.
|
|
15
|
+
- **Trusted tool-context routing** — project bank precedence chain (`HINDSIGHT_PROJECT_BANK_ID` → `HINDSIGHT_BANK_ID` → `runtimeProjectBanks` alias → `agentProjectBanks` match → `projectBank` → generated bank) ensures predictable routing for every tool call.
|
|
16
|
+
- **Compaction memory routing** — when OpenCode context hits the compaction threshold, project memories are injected into the summary context and the session summary is saved as a memory, preserving context across compaction events.
|
|
17
|
+
- **Privacy-safe logging** — content wrapped in `<private>` tags is never stored in Hindsight memory; structured logging keeps plugin operations visible without leaking user data.
|
|
18
|
+
- **Offline / Chinese deployment notes** — the Quick Start section documents Huawei SWR mirror pull commands for `ghcr.io`-blocked regions and local model mounting for air-gapped deployments.
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
### 1. Deploy Hindsight Server
|
|
23
|
+
|
|
24
|
+
[Hindsight](https://github.com/vectorize-io/hindsight) is the semantic memory backend required by this plugin. You need to deploy it first.
|
|
25
|
+
|
|
26
|
+
**Using Docker Compose (recommended):**
|
|
27
|
+
This project includes a ready-to-use Docker Compose configuration in the `deploy/` directory that's pre-configured for DeepSeek integration.
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Navigate to the deploy directory
|
|
31
|
+
cd deploy/
|
|
32
|
+
|
|
33
|
+
# Create .env file with your DeepSeek API key
|
|
34
|
+
echo "HINDSIGHT_API_LLM_API_KEY=your-deepseek-api-key-here" > .env
|
|
35
|
+
|
|
36
|
+
# Start Hindsight server
|
|
37
|
+
docker compose up -d
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Configuration Notes:**
|
|
41
|
+
- The Docker Compose setup uses DeepSeek's reasoning model (`deepseek-reasoner`) by default
|
|
42
|
+
- You need a valid DeepSeek API key from [DeepSeek Platform](https://platform.deepseek.com/)
|
|
43
|
+
- The configuration includes persistent volume mounting at `~/.hindsight-docker`
|
|
44
|
+
- Server runs on port 8888 (web interface) and 9999 (additional service)
|
|
45
|
+
|
|
46
|
+
**Using Docker (simple):**
|
|
47
|
+
```bash
|
|
48
|
+
# Pull the latest Hindsight image
|
|
49
|
+
docker pull ghcr.io/vectorize-io/hindsight:latest
|
|
50
|
+
|
|
51
|
+
# Run Hindsight server on port 8888 with persistent storage
|
|
52
|
+
docker run -d \
|
|
53
|
+
--name hindsight \
|
|
54
|
+
-p 8888:8888 \
|
|
55
|
+
-v hindsight_data:/data \
|
|
56
|
+
ghcr.io/vectorize-io/hindsight:latest
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
> **For Chinese users**: If you cannot access `ghcr.io`, use the Huawei SWR mirror:
|
|
60
|
+
> ```bash
|
|
61
|
+
> docker pull swr.cn-north-4.myhuaweicloud.com/cn/hindsight:latest
|
|
62
|
+
> docker run -d \
|
|
63
|
+
> --name hindsight \
|
|
64
|
+
> -p 8888:8888 \
|
|
65
|
+
> -v hindsight_data:/data \
|
|
66
|
+
> swr.cn-north-4.myhuaweicloud.com/cn/hindsight:latest
|
|
67
|
+
> ```
|
|
68
|
+
|
|
69
|
+
**Offline / No-network access:**
|
|
70
|
+
|
|
71
|
+
When running in an environment without internet access, Hindsight will fail to download embedding and reranker models from HuggingFace. To use pre-downloaded local models:
|
|
72
|
+
|
|
73
|
+
```yaml
|
|
74
|
+
# docker-compose.yml additions
|
|
75
|
+
environment:
|
|
76
|
+
HINDSIGHT_API_EMBEDDINGS_PROVIDER: local
|
|
77
|
+
HINDSIGHT_API_EMBEDDINGS_LOCAL_MODEL: /home/hindsight/models/bge-m3
|
|
78
|
+
HINDSIGHT_API_RERANKER_PROVIDER: local
|
|
79
|
+
HINDSIGHT_API_RERANKER_LOCAL_MODEL: /home/hindsight/models/bge-reranker-v2-m3
|
|
80
|
+
volumes:
|
|
81
|
+
- /path/to/your/models/bge-m3:/home/hindsight/models/bge-m3
|
|
82
|
+
- /path/to/your/models/bge-reranker-v2-m3:/home/hindsight/models/bge-reranker-v2-m3
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Models can be pre-downloaded from [ModelScope](https://modelscope.cn) or [HuggingFace](https://huggingface.co) on a machine with internet, then mounted into the container. The default models are `BAAI/bge-small-en-v1.5` (embeddings, 384-dim) and `cross-encoder/ms-marco-MiniLM-L-6-v2` (reranker).
|
|
86
|
+
|
|
87
|
+
> **Note**: If changing the embedding model after the database is initialized, you must clear existing data first: stop the container, run `rm -rf ~/.hindsight-docker`, then restart.
|
|
88
|
+
|
|
89
|
+
**Alternative deployment methods:**
|
|
90
|
+
- **Binary release**: Download pre-built binaries from [Hindsight releases](https://github.com/vectorize-io/hindsight/releases)
|
|
91
|
+
- **From source**: Clone and build from [Hindsight repository](https://github.com/vectorize-io/hindsight)
|
|
92
|
+
|
|
93
|
+
**Verify deployment:**
|
|
94
|
+
```bash
|
|
95
|
+
curl http://localhost:8888/health
|
|
96
|
+
# Expected response: {"status":"healthy","database":"connected"}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### 2. Install the Plugin
|
|
100
|
+
|
|
101
|
+
#### From npm (recommended)
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
npm install -g @shodocan/opencode-hindsight
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Then register the plugin in your OpenCode configuration:
|
|
108
|
+
|
|
109
|
+
```json
|
|
110
|
+
{
|
|
111
|
+
"plugin": ["@shodocan/opencode-hindsight"]
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Save the file to `~/.config/opencode/opencode.json`.
|
|
116
|
+
|
|
117
|
+
#### From source (local / file:// development)
|
|
118
|
+
|
|
119
|
+
Clone the repository and build locally:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
git clone https://github.com/Shodocan/opencode-hindsight.git
|
|
123
|
+
cd opencode-hindsight
|
|
124
|
+
|
|
125
|
+
bun install
|
|
126
|
+
bun run build
|
|
127
|
+
|
|
128
|
+
# Link the plugin to OpenCode configuration using a file:// path
|
|
129
|
+
echo '{"plugin": ["file://'$(pwd)'"]}' > ~/.config/opencode/opencode.json
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
This will:
|
|
133
|
+
- Clone the plugin source code
|
|
134
|
+
- Install all required dependencies
|
|
135
|
+
- Build the plugin locally
|
|
136
|
+
- Register the plugin in your OpenCode configuration using a local file:// path
|
|
137
|
+
- Create the `/hindsight-init` command for codebase indexing
|
|
138
|
+
|
|
139
|
+
**Note**: Restart OpenCode for the changes to take effect.
|
|
140
|
+
|
|
141
|
+
### 3. Configure Connection
|
|
142
|
+
|
|
143
|
+
If your Hindsight server is not running on `localhost:8888`, configure the connection:
|
|
144
|
+
|
|
145
|
+
**Using environment variable:**
|
|
146
|
+
```bash
|
|
147
|
+
export HINDSIGHT_BASE_URL="http://localhost:8888"
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**Using configuration file:**
|
|
151
|
+
Create `~/.config/opencode/hindsight.jsonc`:
|
|
152
|
+
```jsonc
|
|
153
|
+
{
|
|
154
|
+
"baseUrl": "http://localhost:8888"
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### 4. Restart and Verify
|
|
159
|
+
|
|
160
|
+
Restart your OpenCode session and verify the plugin is loaded:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
opencode -c # Should show 'hindsight' in the available tools
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Test the plugin:**
|
|
167
|
+
After restarting OpenCode, ask the agent to save a test memory, or use the in-session `hindsight` tool if your OpenCode UI exposes tool calls directly. The `hindsight` tool is an OpenCode agent tool, not the `opencode-hindsight` terminal binary.
|
|
168
|
+
|
|
169
|
+
## Installation
|
|
170
|
+
|
|
171
|
+
> **Note**: For a complete step-by-step guide including Hindsight server deployment, see the [Quick Start](#quick-start) section above.
|
|
172
|
+
|
|
173
|
+
### From npm (Recommended)
|
|
174
|
+
|
|
175
|
+
Install the package and register it in your OpenCode configuration:
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
npm install -g @shodocan/opencode-hindsight
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Add the plugin entry to `~/.config/opencode/opencode.json`:
|
|
182
|
+
|
|
183
|
+
```json
|
|
184
|
+
{
|
|
185
|
+
"plugin": ["@shodocan/opencode-hindsight"]
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Hindsight runs locally on port 8888 by default. If you need to connect to a different server, set the base URL:
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
export HINDSIGHT_BASE_URL="http://localhost:8888"
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**Or let your agent do it** — paste this into OpenCode:
|
|
196
|
+
|
|
197
|
+
```
|
|
198
|
+
Install @shodocan/opencode-hindsight by following https://raw.githubusercontent.com/Shodocan/opencode-hindsight/main/README.md
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Local Source / File:// Development
|
|
202
|
+
|
|
203
|
+
When developing or testing the plugin locally, use a file path in your OpenCode configuration:
|
|
204
|
+
|
|
205
|
+
```json
|
|
206
|
+
{
|
|
207
|
+
"plugin": ["file:///path/to/opencode-hindsight"]
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Replace `/path/to/opencode-hindsight` with the absolute path to the plugin directory. The plugin source repository is https://github.com/Shodocan/opencode-hindsight.
|
|
212
|
+
|
|
213
|
+
### For LLM Agents
|
|
214
|
+
|
|
215
|
+
<details>
|
|
216
|
+
<summary>Instructions for LLM Agents (click to expand)</summary>
|
|
217
|
+
|
|
218
|
+
If you're an LLM agent helping set up `@shodocan/opencode-hindsight`, follow these steps:
|
|
219
|
+
|
|
220
|
+
#### Step 1: Install from npm or clone from source
|
|
221
|
+
|
|
222
|
+
**npm install (recommended):**
|
|
223
|
+
```bash
|
|
224
|
+
npm install -g @shodocan/opencode-hindsight
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
**Or clone and build:**
|
|
228
|
+
```bash
|
|
229
|
+
git clone https://github.com/Shodocan/opencode-hindsight.git
|
|
230
|
+
cd opencode-hindsight
|
|
231
|
+
bun install
|
|
232
|
+
bun run build
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
#### Step 2: Register in OpenCode configuration
|
|
236
|
+
|
|
237
|
+
**For npm install:**
|
|
238
|
+
```json
|
|
239
|
+
{
|
|
240
|
+
"plugin": ["@shodocan/opencode-hindsight"]
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
**For local source:**
|
|
245
|
+
```json
|
|
246
|
+
{
|
|
247
|
+
"plugin": ["file:///path/to/opencode-hindsight"]
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Replace `/path/to/opencode-hindsight` with the absolute path of the cloned directory.
|
|
252
|
+
|
|
253
|
+
Save to `~/.config/opencode/opencode.json`.
|
|
254
|
+
|
|
255
|
+
**Note**: OpenCode uses `.json` format for `opencode.json`. The plugin path can be a local file path if developing locally.
|
|
256
|
+
|
|
257
|
+
#### Step 3: Configure Hindsight server
|
|
258
|
+
|
|
259
|
+
Hindsight runs locally on port 8888 by default. If you need to connect to a different server, set the base URL:
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
export HINDSIGHT_BASE_URL="http://localhost:8888"
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
Or create `~/.config/opencode/hindsight.jsonc`:
|
|
266
|
+
|
|
267
|
+
```jsonc
|
|
268
|
+
{
|
|
269
|
+
"baseUrl": "http://localhost:8888" // Optional, defaults to localhost:8888
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Both `.jsonc` and `.json` formats are supported for Hindsight configuration, but OpenCode configuration uses `.json` format only.
|
|
274
|
+
|
|
275
|
+
#### Step 4: Verify setup
|
|
276
|
+
|
|
277
|
+
Tell the user to restart OpenCode and run:
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
opencode -c
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
They should see `hindsight` in the tools list. If not, check:
|
|
284
|
+
|
|
285
|
+
1. Is Hindsight server running? (default: http://localhost:8888)
|
|
286
|
+
2. Is the plugin in `opencode.json`?
|
|
287
|
+
3. Check logs: `tail ~/.opencode-hindsight.log`
|
|
288
|
+
|
|
289
|
+
#### Step 5: Initialize codebase memory (optional)
|
|
290
|
+
|
|
291
|
+
Run `/hindsight-init` to have the agent explore and memorize the codebase.
|
|
292
|
+
|
|
293
|
+
</details>
|
|
294
|
+
|
|
295
|
+
## Features
|
|
296
|
+
|
|
297
|
+
### Context Injection
|
|
298
|
+
|
|
299
|
+
Context injection happens automatically when the user sends the **first message** of a new session — not when OpenCode starts up. The mechanism works as follows:
|
|
300
|
+
|
|
301
|
+
1. **Detection**: The `chat.message` hook checks whether the current session ID has been seen before via an in-memory `injectedSessions` Set
|
|
302
|
+
2. **First message only**: If the session ID is not in the Set, it's added immediately (preventing double-injection on subsequent messages in the same session)
|
|
303
|
+
3. **Three parallel API calls** are made using the user's message as the search query:
|
|
304
|
+
- `getProfile(banks.user, userMessage)` — retrieves cross-project user profile facts via semantic search
|
|
305
|
+
- `searchMemories(userMessage, banks.user)` — retrieves relevant user-scoped memories via semantic search
|
|
306
|
+
- `listMemories(banks.project, maxProjectMemories)` — lists the latest N project memories (no relevance filtering, all have `[100%]` similarity)
|
|
307
|
+
4. **Format & Inject**: Results are formatted into the `[HINDSIGHT]` context block and prepended as a synthetic `Part` to the message parts — invisible to the user, visible only to the AI model
|
|
308
|
+
|
|
309
|
+
**Timing summary:**
|
|
310
|
+
|
|
311
|
+
| Event | When |
|
|
312
|
+
|---|---|
|
|
313
|
+
| OpenCode starts | No injection |
|
|
314
|
+
| User sends first message | Hook fires → injection happens → message processed |
|
|
315
|
+
| User sends second message | Hook fires but session already marked → skip injection |
|
|
316
|
+
|
|
317
|
+
Example of what the agent sees:
|
|
318
|
+
|
|
319
|
+
```
|
|
320
|
+
[HINDSIGHT]
|
|
321
|
+
|
|
322
|
+
User Profile:
|
|
323
|
+
- Prefers concise responses
|
|
324
|
+
- Expert in TypeScript
|
|
325
|
+
|
|
326
|
+
Project Knowledge:
|
|
327
|
+
- [100%] Uses Bun, not Node.js
|
|
328
|
+
- [100%] Build: bun run build
|
|
329
|
+
|
|
330
|
+
Relevant Memories:
|
|
331
|
+
- [82%] Build fails if .env.local missing
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
The agent uses this context automatically — no manual prompting needed.
|
|
335
|
+
|
|
336
|
+
### Keyword Detection
|
|
337
|
+
|
|
338
|
+
Say "remember", "save this", "don't forget" etc. and the agent auto-saves to memory.
|
|
339
|
+
|
|
340
|
+
```
|
|
341
|
+
You: "Remember that this project uses bun"
|
|
342
|
+
Agent: [saves to project memory]
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
Add custom triggers via `keywordPatterns` config.
|
|
346
|
+
|
|
347
|
+
### Codebase Indexing
|
|
348
|
+
|
|
349
|
+
Run `/hindsight-init` to explore and memorize your codebase structure, patterns, and conventions.
|
|
350
|
+
|
|
351
|
+
### Preemptive Compaction
|
|
352
|
+
|
|
353
|
+
When context hits 80% capacity:
|
|
354
|
+
|
|
355
|
+
1. Triggers OpenCode's summarization
|
|
356
|
+
2. Injects project memories into summary context
|
|
357
|
+
3. Saves session summary as a memory
|
|
358
|
+
|
|
359
|
+
This preserves conversation context across compaction events.
|
|
360
|
+
|
|
361
|
+
### Privacy
|
|
362
|
+
|
|
363
|
+
```
|
|
364
|
+
Secret content is <private>sk-abc123</private>
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
Content in `<private>` tags is never stored.
|
|
368
|
+
|
|
369
|
+
## Tool Usage
|
|
370
|
+
|
|
371
|
+
The `hindsight` tool is available to the agent:
|
|
372
|
+
|
|
373
|
+
| Mode | Args | Description |
|
|
374
|
+
| --------- | ---------------------------- | ----------------- |
|
|
375
|
+
| `add` | `content`, `type?`, `scope?` | Store memory (asynchronous) |
|
|
376
|
+
| `search` | `query`, `scope?` | Search memories |
|
|
377
|
+
| `profile` | `query?` | View user profile |
|
|
378
|
+
| `list` | `scope?`, `limit?` | List memories |
|
|
379
|
+
| `forget` | `memoryId`, `scope?` | Delete memory |
|
|
380
|
+
|
|
381
|
+
**Scopes:** `user` (cross-project), `project` (default)
|
|
382
|
+
|
|
383
|
+
**Types:** `project-config`, `architecture`, `error-solution`, `preference`, `learned-pattern`, `conversation`
|
|
384
|
+
|
|
385
|
+
### Important Notes:
|
|
386
|
+
- **`add` operation is asynchronous by default** to prevent timeouts during memory processing
|
|
387
|
+
- **Metadata values must be strings** — non-string values are automatically converted
|
|
388
|
+
- **Response includes `operationId`** for tracking asynchronous operations
|
|
389
|
+
- **Memory processing may take 30-60 seconds** for complex content extraction
|
|
390
|
+
|
|
391
|
+
### Example Usage
|
|
392
|
+
|
|
393
|
+
```javascript
|
|
394
|
+
// Store a project-specific configuration
|
|
395
|
+
hindsight({
|
|
396
|
+
mode: "add",
|
|
397
|
+
content: "This project uses Bun for package management and TypeScript for type safety",
|
|
398
|
+
type: "project-config",
|
|
399
|
+
scope: "project"
|
|
400
|
+
})
|
|
401
|
+
|
|
402
|
+
// Search for relevant memories
|
|
403
|
+
hindsight({
|
|
404
|
+
mode: "search",
|
|
405
|
+
query: "package manager",
|
|
406
|
+
scope: "project",
|
|
407
|
+
limit: 5
|
|
408
|
+
})
|
|
409
|
+
|
|
410
|
+
// View user profile (cross-project preferences)
|
|
411
|
+
hindsight({
|
|
412
|
+
mode: "profile"
|
|
413
|
+
})
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
## Memory Scoping
|
|
417
|
+
|
|
418
|
+
| Scope | Tag | Persists |
|
|
419
|
+
| ------- | -------------------------------------- | ------------ |
|
|
420
|
+
| User | `hindsight_user_{sha256(git email)}` | All projects |
|
|
421
|
+
| Project | `hindsight_project_{sha256(directory)}` | This project |
|
|
422
|
+
|
|
423
|
+
## Configuration
|
|
424
|
+
|
|
425
|
+
Create `~/.config/opencode/hindsight.jsonc` or `~/.config/opencode/hindsight.json`:
|
|
426
|
+
|
|
427
|
+
```jsonc
|
|
428
|
+
{
|
|
429
|
+
// Hindsight server URL (default: http://localhost:8888)
|
|
430
|
+
"baseUrl": "http://localhost:8888",
|
|
431
|
+
|
|
432
|
+
// Min similarity for memory retrieval (0-1, default: 0.6)
|
|
433
|
+
"similarityThreshold": 0.6,
|
|
434
|
+
|
|
435
|
+
// Max memories injected per request (default: 5)
|
|
436
|
+
"maxMemories": 5,
|
|
437
|
+
|
|
438
|
+
// Max project memories listed (default: 10)
|
|
439
|
+
"maxProjectMemories": 10,
|
|
440
|
+
|
|
441
|
+
// Max profile facts injected (default: 5)
|
|
442
|
+
"maxProfileItems": 5,
|
|
443
|
+
|
|
444
|
+
// Include user profile in context (default: true)
|
|
445
|
+
"injectProfile": true,
|
|
446
|
+
|
|
447
|
+
// Prefix for bank names when userBank/projectBank not set (default: "opencode")
|
|
448
|
+
"bankPrefix": "opencode",
|
|
449
|
+
|
|
450
|
+
// Optional: Set exact user bank (overrides auto-generated bank)
|
|
451
|
+
"userBank": "my-custom-user-bank",
|
|
452
|
+
|
|
453
|
+
// Optional: Set exact project bank (overrides auto-generated bank)
|
|
454
|
+
"projectBank": "my-project-bank",
|
|
455
|
+
|
|
456
|
+
// Optional: Route specific agents/subagents to project banks by exact name or glob
|
|
457
|
+
"agentProjectBanks": {
|
|
458
|
+
"review-*": "proj-review",
|
|
459
|
+
"tdd": "proj-tdd"
|
|
460
|
+
},
|
|
461
|
+
|
|
462
|
+
// Optional: Allowlisted per-tool-call project bank aliases
|
|
463
|
+
"runtimeProjectBanks": {
|
|
464
|
+
"other-repo": "proj-other-repo",
|
|
465
|
+
"review": "proj-review"
|
|
466
|
+
},
|
|
467
|
+
|
|
468
|
+
// Max tokens for recall operations (default: 4096)
|
|
469
|
+
"maxTokens": 4096,
|
|
470
|
+
|
|
471
|
+
// Budget for recall operations: 'low', 'mid', or 'high' (default: 'mid')
|
|
472
|
+
"budget": "mid",
|
|
473
|
+
|
|
474
|
+
// Extra keyword patterns for memory detection (regex)
|
|
475
|
+
"keywordPatterns": ["log\\s+this", "write\\s+down"],
|
|
476
|
+
|
|
477
|
+
// Context usage ratio that triggers compaction (0-1, default: 0.8)
|
|
478
|
+
"compactionThreshold": 0.8
|
|
479
|
+
}
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
All fields optional.
|
|
483
|
+
|
|
484
|
+
### Environment Variables
|
|
485
|
+
|
|
486
|
+
The following environment variables take precedence over configuration file settings:
|
|
487
|
+
|
|
488
|
+
- `HINDSIGHT_BASE_URL`: Hindsight server URL (e.g., `http://localhost:8888`)
|
|
489
|
+
- **Priority**: Highest — overrides config file and defaults
|
|
490
|
+
- **Use case**: Different servers for development/production, docker containers
|
|
491
|
+
|
|
492
|
+
Configuration loading order (highest to lowest priority):
|
|
493
|
+
1. Environment variables
|
|
494
|
+
2. Configuration file (`hindsight.jsonc` or `hindsight.json`)
|
|
495
|
+
3. Default values
|
|
496
|
+
|
|
497
|
+
Project bank precedence (highest to lowest):
|
|
498
|
+
|
|
499
|
+
1. `HINDSIGHT_PROJECT_BANK_ID`
|
|
500
|
+
2. `HINDSIGHT_BANK_ID`
|
|
501
|
+
3. allowlisted `bankAlias` from `runtimeProjectBanks`
|
|
502
|
+
4. matching `agentProjectBanks` exact/glob entry
|
|
503
|
+
5. `projectBank`
|
|
504
|
+
6. generated `p_<project>_<hash>` bank
|
|
505
|
+
|
|
506
|
+
### Configuration Notes:
|
|
507
|
+
- **File format**: Both `.jsonc` (with comments) and `.json` formats are supported
|
|
508
|
+
- **Memory operations are asynchronous by default** to prevent timeouts (30-60 seconds processing time)
|
|
509
|
+
- **Metadata values must be strings** — non-string values are automatically converted:
|
|
510
|
+
- Numbers and booleans: converted to string representation
|
|
511
|
+
- Objects and arrays: converted to JSON strings
|
|
512
|
+
- Null/undefined: converted to empty string
|
|
513
|
+
- **Bank names are auto-generated** using SHA-256 hashes if not explicitly specified
|
|
514
|
+
|
|
515
|
+
### Bank Selection
|
|
516
|
+
|
|
517
|
+
By default, banks are auto-generated using `bankPrefix` plus a SHA-256 hash:
|
|
518
|
+
|
|
519
|
+
- **User bank**: `{prefix}_user_{sha256(git_email)}`
|
|
520
|
+
- Uses git user.email if available, otherwise falls back to system username
|
|
521
|
+
- **Project bank**: `{prefix}_project_{sha256(project_directory)}`
|
|
522
|
+
- Uses the absolute path of the current working directory
|
|
523
|
+
|
|
524
|
+
You can override this by specifying exact bank names:
|
|
525
|
+
|
|
526
|
+
```jsonc
|
|
527
|
+
{
|
|
528
|
+
// Use a specific bank for user memories (cross-project)
|
|
529
|
+
"userBank": "my-team-workspace",
|
|
530
|
+
|
|
531
|
+
// Use a specific bank for project memories (project-specific)
|
|
532
|
+
"projectBank": "my-awesome-project",
|
|
533
|
+
}
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
This is useful when you want to:
|
|
537
|
+
|
|
538
|
+
- **Share memories across team members** (same `userBank`)
|
|
539
|
+
- **Sync memories between different machines** for the same project
|
|
540
|
+
- **Organize memories using your own naming scheme**
|
|
541
|
+
- **Integrate with existing Hindsight banks** from other tools
|
|
542
|
+
|
|
543
|
+
### Agent-Aware Project Bank Routing
|
|
544
|
+
|
|
545
|
+
Subagents can use different project banks without changing OpenCode core. Configure `agentProjectBanks` with exact names or `*` glob patterns:
|
|
546
|
+
|
|
547
|
+
```jsonc
|
|
548
|
+
{
|
|
549
|
+
"projectBank": "proj-default",
|
|
550
|
+
"agentProjectBanks": {
|
|
551
|
+
"review-*": "proj-review",
|
|
552
|
+
"agent-a": "proj-agent-a",
|
|
553
|
+
"agent-b": "proj-agent-b"
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
With this configuration:
|
|
559
|
+
|
|
560
|
+
- the main/default agent uses `proj-default`
|
|
561
|
+
- `agent-a` uses `proj-agent-a`
|
|
562
|
+
- `agent-b` uses `proj-agent-b`
|
|
563
|
+
- `review-security-skeptic`, `review-bug-hunter`, and other `review-*` agents use `proj-review`
|
|
564
|
+
|
|
565
|
+
Exact agent matches take precedence over glob patterns. If no agent mapping matches, the plugin falls back to `projectBank` or the generated project bank.
|
|
566
|
+
|
|
567
|
+
### Runtime Project Bank Aliases
|
|
568
|
+
|
|
569
|
+
For one-off tool calls, configure allowlisted aliases with `runtimeProjectBanks`:
|
|
570
|
+
|
|
571
|
+
```jsonc
|
|
572
|
+
{
|
|
573
|
+
"runtimeProjectBanks": {
|
|
574
|
+
"other-repo": "proj-other-repo"
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
Then call:
|
|
580
|
+
|
|
581
|
+
```text
|
|
582
|
+
hindsight(mode: "search", query: "auth flow", bankAlias: "other-repo")
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
`bankAlias` applies only to that tool call. Unknown aliases return an error. The tool does not accept arbitrary bank IDs from the model.
|
|
586
|
+
|
|
587
|
+
### API Compatibility
|
|
588
|
+
|
|
589
|
+
This plugin uses the official `@vectorize-io/hindsight-client` (v0.6.2) and is compatible with Hindsight API v1. Key compatibility notes:
|
|
590
|
+
|
|
591
|
+
- **Asynchronous operations**: Memory addition uses `async: true` by default to prevent timeouts
|
|
592
|
+
- **Metadata handling**: All metadata values are converted to strings to match API requirements
|
|
593
|
+
- **Response format**: Responses include `operationId` (not `id`) for tracking asynchronous operations
|
|
594
|
+
- **Timeout handling**: Operations timeout after 120 seconds to accommodate Hindsight's processing time
|
|
595
|
+
|
|
596
|
+
## Usage with Oh My OpenCode
|
|
597
|
+
|
|
598
|
+
If you're using [Oh My OpenCode](https://github.com/code-yeongyu/oh-my-opencode), disable its built-in auto-compact hook to let hindsight handle context compaction:
|
|
599
|
+
|
|
600
|
+
Add to `~/.config/opencode/oh-my-opencode.json`:
|
|
601
|
+
|
|
602
|
+
```json
|
|
603
|
+
{
|
|
604
|
+
"disabled_hooks": ["anthropic-context-window-limit-recovery"]
|
|
605
|
+
}
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
## Development
|
|
609
|
+
|
|
610
|
+
```bash
|
|
611
|
+
# Clone and setup
|
|
612
|
+
git clone https://github.com/Shodocan/opencode-hindsight.git
|
|
613
|
+
cd opencode-hindsight
|
|
614
|
+
|
|
615
|
+
# Install dependencies
|
|
616
|
+
bun install
|
|
617
|
+
|
|
618
|
+
# Build the plugin
|
|
619
|
+
bun run build
|
|
620
|
+
|
|
621
|
+
# Type checking
|
|
622
|
+
bun run typecheck
|
|
623
|
+
|
|
624
|
+
# Test with local configuration (file:// path)
|
|
625
|
+
echo '{"plugin": ["file://'$(pwd)'"]}' > ~/.config/opencode/opencode.json
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
## Troubleshooting
|
|
629
|
+
|
|
630
|
+
### Common Issues
|
|
631
|
+
|
|
632
|
+
1. **Timeout errors when adding memories**
|
|
633
|
+
- **Cause**: Hindsight server processing takes 30-60 seconds for memory extraction
|
|
634
|
+
- **Solution**: Plugin uses asynchronous operations (`async: true`) by default
|
|
635
|
+
- **Verification**: Check if response includes `operationId` instead of `id`
|
|
636
|
+
|
|
637
|
+
2. **`hindsight` tool not available**
|
|
638
|
+
- **Cause**: Plugin not loaded or configuration incorrect
|
|
639
|
+
- **Solution**:
|
|
640
|
+
- Verify plugin is in `~/.config/opencode/opencode.json`
|
|
641
|
+
- Restart OpenCode after configuration changes
|
|
642
|
+
- Check Hindsight server is running: `curl http://localhost:8888/health`
|
|
643
|
+
|
|
644
|
+
3. **Metadata not saving correctly**
|
|
645
|
+
- **Cause**: Hindsight API requires all metadata values to be strings
|
|
646
|
+
- **Solution**: Plugin automatically converts non-string values:
|
|
647
|
+
- Numbers/booleans → string representation
|
|
648
|
+
- Objects/arrays → JSON strings
|
|
649
|
+
- Null/undefined → empty strings
|
|
650
|
+
|
|
651
|
+
4. **Empty results from `list` command**
|
|
652
|
+
- **Cause**: The `listDocuments` API may not return all memories
|
|
653
|
+
- **Workaround**: Use `search` with specific queries instead
|
|
654
|
+
- **Note**: This is a limitation of the current Hindsight API implementation
|
|
655
|
+
|
|
656
|
+
5. **Memory not appearing in searches**
|
|
657
|
+
- **Cause**: Asynchronous processing may still be in progress
|
|
658
|
+
- **Solution**: Wait 1-2 minutes for memory consolidation
|
|
659
|
+
- **Verification**: Check Hindsight server logs for processing status
|
|
660
|
+
|
|
661
|
+
## Logs
|
|
662
|
+
|
|
663
|
+
```bash
|
|
664
|
+
# Plugin logs
|
|
665
|
+
tail -f ~/.opencode-hindsight.log
|
|
666
|
+
|
|
667
|
+
# Hindsight server logs (if running locally)
|
|
668
|
+
# Check your Hindsight server documentation for log location
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
## License
|
|
672
|
+
|
|
673
|
+
MIT
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Hindsight Docker Compose Configuration
|
|
2
|
+
# Copy this file to .env and set your DeepSeek API key
|
|
3
|
+
|
|
4
|
+
# DeepSeek API Configuration
|
|
5
|
+
HINDSIGHT_API_LLM_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
6
|
+
|
|
7
|
+
# Optional: Override default model if needed
|
|
8
|
+
# HINDSIGHT_API_LLM_MODEL=deepseek-reasoner
|
|
9
|
+
|
|
10
|
+
# Optional: Override base URL if using different provider
|
|
11
|
+
# HINDSIGHT_API_LLM_BASE_URL=https://api.deepseek.com/v1
|
|
12
|
+
|
|
13
|
+
# Optional: Set different provider (openai is default for OpenAI-compatible APIs)
|
|
14
|
+
# HINDSIGHT_API_LLM_PROVIDER=openai
|
|
15
|
+
|
|
16
|
+
# Embedding Model (default: BAAI/bge-small-en-v1.5, auto-downloaded from HuggingFace)
|
|
17
|
+
# To use a pre-downloaded local model, mount it via volumes and set the path:
|
|
18
|
+
# HINDSIGHT_API_EMBEDDINGS_LOCAL_MODEL=/home/hindsight/models/bge-m3
|
|
19
|
+
|
|
20
|
+
# Reranker Model (default: cross-encoder/ms-marco-MiniLM-L-6-v2, auto-downloaded from HuggingFace)
|
|
21
|
+
# To use a pre-downloaded local model, mount it via volumes and set the path:
|
|
22
|
+
# HINDSIGHT_API_RERANKER_LOCAL_MODEL=/home/hindsight/models/bge-reranker-v2-m3
|