@sesamespace/hivemind 0.5.11 → 0.5.13
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/.pnpmrc.json +1 -0
- package/DASHBOARD-PLAN.md +206 -0
- package/dist/chunk-7D4SUZUM.js +38 -0
- package/dist/chunk-7D4SUZUM.js.map +1 -0
- package/dist/{chunk-EHJS5GJT.js → chunk-IO5UVDAO.js} +2 -2
- package/dist/{chunk-7KVMNG6Q.js → chunk-IUFYZ4AJ.js} +2 -2
- package/dist/{chunk-3O2BF2TT.js → chunk-MKE2NVOC.js} +1341 -33
- package/dist/chunk-MKE2NVOC.js.map +1 -0
- package/dist/{chunk-SCRJ5CKP.js → chunk-QRXSVR64.js} +3 -3
- package/dist/{chunk-VRRUD3I5.js → chunk-YTZTXAHU.js} +2 -2
- package/dist/commands/fleet.js +4 -3
- package/dist/commands/init.js +1 -0
- package/dist/commands/service.js +1 -0
- package/dist/commands/start.js +4 -3
- package/dist/commands/upgrade.js +1 -0
- package/dist/commands/watchdog.js +4 -3
- package/dist/index.js +3 -2
- package/dist/main.js +6 -5
- package/dist/main.js.map +1 -1
- package/dist/start.js +2 -1
- package/dist/start.js.map +1 -1
- package/package.json +6 -1
- package/dist/chunk-3O2BF2TT.js.map +0 -1
- /package/dist/{chunk-EHJS5GJT.js.map → chunk-IO5UVDAO.js.map} +0 -0
- /package/dist/{chunk-7KVMNG6Q.js.map → chunk-IUFYZ4AJ.js.map} +0 -0
- /package/dist/{chunk-SCRJ5CKP.js.map → chunk-QRXSVR64.js.map} +0 -0
- /package/dist/{chunk-VRRUD3I5.js.map → chunk-YTZTXAHU.js.map} +0 -0
package/.pnpmrc.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"onlyBuiltDependencies":["better-sqlite3"]}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# Hivemind Dashboard — Implementation Plan
|
|
2
|
+
|
|
3
|
+
**Goal:** Local web dashboard for debugging memory, context routing, and LLM request formation.
|
|
4
|
+
**Access:** `http://localhost:9485` on the Mac mini (local access only for now).
|
|
5
|
+
**Priority:** LLM Request Inspector first, then Memory Browser, then Context Overview.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Phase 1: LLM Request Logger + Inspector UI
|
|
10
|
+
|
|
11
|
+
### Backend: Request Logging
|
|
12
|
+
|
|
13
|
+
**Where:** Instrument `buildMessages()` in `prompt.ts` and `processMessage()` in `agent.ts`.
|
|
14
|
+
|
|
15
|
+
Each logged request captures:
|
|
16
|
+
```typescript
|
|
17
|
+
interface RequestLog {
|
|
18
|
+
id: string; // uuid
|
|
19
|
+
timestamp: string; // ISO-8601
|
|
20
|
+
// Routing
|
|
21
|
+
context: string; // which context was used
|
|
22
|
+
contextSwitched: boolean; // explicit switch?
|
|
23
|
+
routingReason: string; // "pattern_match:X" | "inferred:X" | "active:X"
|
|
24
|
+
// Sender
|
|
25
|
+
channelId: string;
|
|
26
|
+
channelKind: "dm" | "group";
|
|
27
|
+
senderHandle: string;
|
|
28
|
+
rawMessage: string; // as received (with prefix)
|
|
29
|
+
// Prompt components (broken out for UI)
|
|
30
|
+
systemPrompt: {
|
|
31
|
+
identity: string; // workspace files section
|
|
32
|
+
l3Knowledge: string[]; // individual L3 entries
|
|
33
|
+
l2Episodes: Array<{
|
|
34
|
+
id: string;
|
|
35
|
+
content: string;
|
|
36
|
+
score: number;
|
|
37
|
+
timestamp: string;
|
|
38
|
+
context_name: string;
|
|
39
|
+
role: string;
|
|
40
|
+
}>;
|
|
41
|
+
contextInfo: string; // active context section
|
|
42
|
+
fullText: string; // complete system prompt as sent
|
|
43
|
+
};
|
|
44
|
+
conversationHistory: Array<{ role: string; content: string }>; // L1 turns included
|
|
45
|
+
userMessage: string; // final user message
|
|
46
|
+
// Response
|
|
47
|
+
response: {
|
|
48
|
+
content: string;
|
|
49
|
+
model: string;
|
|
50
|
+
latencyMs: number;
|
|
51
|
+
skipped: boolean; // was it __SKIP__?
|
|
52
|
+
};
|
|
53
|
+
// Config snapshot
|
|
54
|
+
config: {
|
|
55
|
+
topK: number;
|
|
56
|
+
model: string;
|
|
57
|
+
maxTokens: number;
|
|
58
|
+
temperature: number;
|
|
59
|
+
};
|
|
60
|
+
// Approximate token counts (char-based estimate: chars/4)
|
|
61
|
+
tokenEstimates: {
|
|
62
|
+
systemPrompt: number;
|
|
63
|
+
conversationHistory: number;
|
|
64
|
+
userMessage: number;
|
|
65
|
+
total: number;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Storage:** SQLite database at `data/dashboard.db`.
|
|
71
|
+
- Single `request_logs` table with JSON columns for complex fields.
|
|
72
|
+
- Auto-prune: keep last 7 days or 10,000 entries (whichever is smaller).
|
|
73
|
+
- Why SQLite over ring buffer: survives restarts, queryable, minimal overhead.
|
|
74
|
+
|
|
75
|
+
**Token estimation:** Use chars/4 approximation. Good enough for relative sizing. Avoid tokenizer dependency.
|
|
76
|
+
|
|
77
|
+
**Logging approach:** Eager logging. Serialize at request time. The overhead is minimal (~1ms for JSON.stringify) compared to LLM latency (~1-10s). Capturing the exact state at request time is more valuable than lazy reconstruction.
|
|
78
|
+
|
|
79
|
+
### Backend: Dashboard HTTP Server
|
|
80
|
+
|
|
81
|
+
**Where:** New file `packages/runtime/src/dashboard.ts`.
|
|
82
|
+
|
|
83
|
+
Extend the existing health server (or create a sibling on port 9485):
|
|
84
|
+
- `GET /` — serve the SPA (single HTML file)
|
|
85
|
+
- `GET /api/requests` — list recent requests (paginated, filterable)
|
|
86
|
+
- `GET /api/requests/:id` — single request detail
|
|
87
|
+
- `GET /api/contexts` — proxy to memory daemon's context list
|
|
88
|
+
- `GET /api/contexts/:name/episodes` — proxy L2 episodes
|
|
89
|
+
- `GET /api/contexts/:name/l3` — proxy L3 knowledge
|
|
90
|
+
- `GET /api/stats` — memory stats (episode counts, last promotion, etc.)
|
|
91
|
+
- `DELETE /api/l3/:id` — delete a bad L3 entry (write op from day 1)
|
|
92
|
+
- `POST /api/l3/:id/edit` — edit L3 entry content
|
|
93
|
+
|
|
94
|
+
Bind to `127.0.0.1:9485` only.
|
|
95
|
+
|
|
96
|
+
### Frontend: Single-File SPA
|
|
97
|
+
|
|
98
|
+
**Why single file:** No build step, no React, no dependencies. Ship as one HTML file with embedded CSS/JS. Can always upgrade later.
|
|
99
|
+
|
|
100
|
+
**Layout:**
|
|
101
|
+
- Left sidebar: navigation (Requests, Memory, Contexts)
|
|
102
|
+
- Main area: content
|
|
103
|
+
|
|
104
|
+
**Request Inspector view:**
|
|
105
|
+
- Reverse-chronological list of requests
|
|
106
|
+
- Each row: timestamp, sender, context, model, latency, token estimate
|
|
107
|
+
- Click to expand → shows all sections:
|
|
108
|
+
- **Identity files** (collapsible, usually not interesting)
|
|
109
|
+
- **L3 Knowledge** (list of entries with metadata)
|
|
110
|
+
- **L2 Episodes** (with similarity scores, timestamps, source context)
|
|
111
|
+
- **L1 History** (conversation turns)
|
|
112
|
+
- **User Message** (raw with prefix)
|
|
113
|
+
- **Response** (with model, latency)
|
|
114
|
+
- **Config** (top_k, model, temperature)
|
|
115
|
+
- **Token breakdown** (bar chart showing proportion per section)
|
|
116
|
+
- Filters: by context, by sender, by time range
|
|
117
|
+
- Search: full-text search across messages
|
|
118
|
+
|
|
119
|
+
**Memory Browser view (Phase 2):**
|
|
120
|
+
- L2: searchable episode list, filterable by context/role/time
|
|
121
|
+
- L3: per-context knowledge entries with edit/delete buttons
|
|
122
|
+
- Promotion log (if we add logging for it)
|
|
123
|
+
|
|
124
|
+
**Context Overview (Phase 2):**
|
|
125
|
+
- List of contexts with episode counts, last active
|
|
126
|
+
- Active context highlighted
|
|
127
|
+
- Click to drill into episodes/L3
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Phase 2: Memory Browser + Context Overview
|
|
132
|
+
|
|
133
|
+
After Phase 1 is working and useful, add:
|
|
134
|
+
- Full L2 browsing with semantic search UI
|
|
135
|
+
- L3 management (view, edit, delete)
|
|
136
|
+
- Context explorer with stats
|
|
137
|
+
- Promotion history logging
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Implementation Steps (Phase 1)
|
|
142
|
+
|
|
143
|
+
### Step 1: Request logging infrastructure
|
|
144
|
+
- [ ] Create `packages/runtime/src/request-logger.ts`
|
|
145
|
+
- SQLite setup (using better-sqlite3)
|
|
146
|
+
- `logRequest()` method
|
|
147
|
+
- `getRequests()` with pagination/filters
|
|
148
|
+
- `getRequest(id)` for detail view
|
|
149
|
+
- Auto-pruning on startup
|
|
150
|
+
- [ ] Add better-sqlite3 dependency
|
|
151
|
+
|
|
152
|
+
### Step 2: Instrument the pipeline
|
|
153
|
+
- [ ] Modify `agent.ts` `processMessage()` to capture routing decision + timing
|
|
154
|
+
- [ ] Modify `prompt.ts` `buildSystemPrompt()` to return structured components (not just string)
|
|
155
|
+
- [ ] Log each request after LLM response arrives
|
|
156
|
+
- [ ] Capture config snapshot with each log entry
|
|
157
|
+
|
|
158
|
+
### Step 3: Dashboard HTTP server
|
|
159
|
+
- [ ] Create `packages/runtime/src/dashboard.ts`
|
|
160
|
+
- Express-free: use Node's built-in `http` module (like health server)
|
|
161
|
+
- Serve SPA at `/`
|
|
162
|
+
- JSON APIs for request logs and memory proxy
|
|
163
|
+
- [ ] Wire into `pipeline.ts` startup
|
|
164
|
+
|
|
165
|
+
### Step 4: Frontend SPA
|
|
166
|
+
- [ ] Single HTML file at `packages/runtime/src/dashboard.html`
|
|
167
|
+
- Vanilla JS, no framework
|
|
168
|
+
- CSS grid layout
|
|
169
|
+
- Fetch-based API calls
|
|
170
|
+
- Expandable request cards
|
|
171
|
+
- Token breakdown visualization
|
|
172
|
+
- Basic filtering
|
|
173
|
+
|
|
174
|
+
### Step 5: Memory proxy + write ops
|
|
175
|
+
- [ ] Proxy endpoints to memory daemon for L2/L3 browsing
|
|
176
|
+
- [ ] DELETE/PATCH endpoints for L3 management
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Design Decisions
|
|
181
|
+
|
|
182
|
+
| Question | Decision | Rationale |
|
|
183
|
+
|----------|----------|-----------|
|
|
184
|
+
| Storage | SQLite | Survives restarts, queryable, lightweight |
|
|
185
|
+
| Token counting | chars/4 estimate | Good enough, no tokenizer dep |
|
|
186
|
+
| Logging | Eager | Captures exact state, overhead negligible vs LLM latency |
|
|
187
|
+
| Bind address | 127.0.0.1 only | Local access, no auth needed |
|
|
188
|
+
| Framework | None (vanilla) | Single HTML file, no build step |
|
|
189
|
+
| Read-only or read-write? | Read-write from start | Ryan will want to delete bad L3 entries immediately |
|
|
190
|
+
| Persist request logs? | Yes, 7 days | Need to compare across memory config changes |
|
|
191
|
+
| Multi-agent? | Single agent for now | Don't over-engineer, but use agent name in logs |
|
|
192
|
+
| Port | 9485 | Next to health port (9484), easy to remember |
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## Sesame Command Fix (Bonus)
|
|
197
|
+
|
|
198
|
+
While we're in the code, fix the sender prefix issue:
|
|
199
|
+
- In `pipeline.ts` `startSesameLoop()`, before calling `agent.processMessage()`, strip the sender prefix for command parsing
|
|
200
|
+
- Or better: in `agent.ts` `handleSpecialCommand()`, strip known prefix patterns before regex matching
|
|
201
|
+
- This unblocks context switching, task commands, and cross-context search over Sesame
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
*Created: 2026-02-28*
|
|
206
|
+
*Status: Ready to implement*
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
8
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
9
|
+
}) : x)(function(x) {
|
|
10
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
11
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
12
|
+
});
|
|
13
|
+
var __commonJS = (cb, mod) => function __require2() {
|
|
14
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
15
|
+
};
|
|
16
|
+
var __copyProps = (to, from, except, desc) => {
|
|
17
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
18
|
+
for (let key of __getOwnPropNames(from))
|
|
19
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
20
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
21
|
+
}
|
|
22
|
+
return to;
|
|
23
|
+
};
|
|
24
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
25
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
26
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
27
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
28
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
29
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
30
|
+
mod
|
|
31
|
+
));
|
|
32
|
+
|
|
33
|
+
export {
|
|
34
|
+
__require,
|
|
35
|
+
__commonJS,
|
|
36
|
+
__toESM
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=chunk-7D4SUZUM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
PRIMARY_ROUTES,
|
|
7
7
|
SesameClient,
|
|
8
8
|
WORKER_ROUTES
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-MKE2NVOC.js";
|
|
10
10
|
|
|
11
11
|
// packages/runtime/src/watchdog.ts
|
|
12
12
|
import { execSync } from "child_process";
|
|
@@ -1048,4 +1048,4 @@ export {
|
|
|
1048
1048
|
WorkerMemorySync,
|
|
1049
1049
|
PrimaryMemorySync
|
|
1050
1050
|
};
|
|
1051
|
-
//# sourceMappingURL=chunk-
|
|
1051
|
+
//# sourceMappingURL=chunk-IO5UVDAO.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
startPipeline
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-MKE2NVOC.js";
|
|
4
4
|
|
|
5
5
|
// packages/cli/src/commands/start.ts
|
|
6
6
|
import { resolve } from "path";
|
|
@@ -66,4 +66,4 @@ Options:
|
|
|
66
66
|
export {
|
|
67
67
|
runStartCommand
|
|
68
68
|
};
|
|
69
|
-
//# sourceMappingURL=chunk-
|
|
69
|
+
//# sourceMappingURL=chunk-IUFYZ4AJ.js.map
|