memhouse 0.18.8 → 0.18.9

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mem",
3
3
  "description": "Conversation memory for AI agents over the memhouse typed ClickHouse store: recall past sessions and answer from them, run analytics, check the house, bring people in, and administer the server. Skills install as /mem:recall, /mem:sql, /mem:house, /mem:access, and /mem:admin.",
4
- "version": "0.18.8",
4
+ "version": "0.18.9",
5
5
  "author": {
6
6
  "name": "Ramazan Polat"
7
7
  },
@@ -471,10 +471,24 @@ async function getChats(opts = {}) {
471
471
  // Price the fifty rows on the page, not the twelve hundred in the house. This query
472
472
  // set was the most expensive thing the dashboard ran — 1,413,624 rows read and 272 MiB
473
473
  // per call, three endpoints calling it — and getChats used ~4% of what it asked for.
474
- const perChat = await computePerChatCosts(f, {
475
- ids: rows.map((r) => String(r.id)),
476
- users: rows.map((r) => String(r.user_id)),
477
- });
474
+ // In CHUNKS. The scope travels as `{scopeIds:Array(String)}` query parameters, and the
475
+ // driver puts query parameters in the REQUEST URI — so a page of N sessions builds a URI
476
+ // of roughly 60 bytes per id, twice (ids and users). Zeo is reached through a Cloudflare
477
+ // tunnel, which rejects a URI far below ClickHouse's own 1 MiB `http_max_uri_size`: at
478
+ // 925 sessions the request came back 500 with an EMPTY message (the driver reports a
479
+ // transport-level refusal as `new Error('')`), so `/api/chats?limit=1000` — exactly what
480
+ // the Sessions page asks for — returned 500 and the page rendered blank. 900 worked,
481
+ // 925 did not. Chunked, the URI stays small whatever the page size, and the per-chunk
482
+ // results merge because each chunk is disjoint by construction.
483
+ const COST_SCOPE_CHUNK = 250;
484
+ const perChat = [];
485
+ for (let i = 0; i < rows.length; i += COST_SCOPE_CHUNK) {
486
+ const slice = rows.slice(i, i + COST_SCOPE_CHUNK);
487
+ perChat.push(...await computePerChatCosts(f, {
488
+ ids: slice.map((r) => String(r.id)),
489
+ users: slice.map((r) => String(r.user_id)),
490
+ }));
491
+ }
478
492
  const costBySession = {};
479
493
  const topModelBySession = {};
480
494
  for (const r of perChat) {
@@ -49,7 +49,15 @@ function parseDateOpts(query) {
49
49
 
50
50
  // Route helper: async handler with the uniform 500 shape.
51
51
  const route = (fn) => async (req, res) => {
52
- try { await fn(req, res); } catch (err) { res.status(500).json({ error: err.message }); }
52
+ try { await fn(req, res); } catch (err) {
53
+ // `{"error":""}` and nothing in the log was the whole diagnosis for a 500 that made the
54
+ // Sessions page render blank: the ClickHouse driver reports a transport-level refusal as
55
+ // `new Error('')` — no message, no code, no own keys. An empty error is a dead end for
56
+ // whoever is looking, so say what we do know: the class of failure and the route.
57
+ const why = (err && err.message) || (err && err.code) || `${err && err.constructor ? err.constructor.name : 'Error'} with no message — often the server or a proxy in front of it refusing the request (URI too long, body too large, timeout)`;
58
+ console.error(`[memhouse] ${req.method} ${req.originalUrl} failed: ${why}`);
59
+ res.status(500).json({ error: String(why) });
60
+ }
53
61
  };
54
62
 
55
63
  app.get('/api/ping', (req, res) => res.json({ app: 'agentlytics', pid: process.pid }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memhouse",
3
- "version": "0.18.8",
3
+ "version": "0.18.9",
4
4
  "description": "memhouse \u2014 agent conversation memory across 17 editors: parse-on-client shippers, a typed ClickHouse store with one set of rooms per member, kernel-agency install, and the agentlytics dashboard",
5
5
  "main": "bin/memhouse.js",
6
6
  "bin": {