@schlessera/brain-ui-server 0.17.0 → 0.19.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.
Files changed (112) hide show
  1. package/README.md +1 -0
  2. package/dist/activity/digest.d.ts +29 -0
  3. package/dist/activity/digest.d.ts.map +1 -0
  4. package/dist/activity/digest.js +61 -0
  5. package/dist/activity/digest.js.map +1 -0
  6. package/dist/activity/notify.d.ts +62 -0
  7. package/dist/activity/notify.d.ts.map +1 -0
  8. package/dist/activity/notify.js +171 -0
  9. package/dist/activity/notify.js.map +1 -0
  10. package/dist/activity/push-sender.d.ts +63 -0
  11. package/dist/activity/push-sender.d.ts.map +1 -0
  12. package/dist/activity/push-sender.js +131 -0
  13. package/dist/activity/push-sender.js.map +1 -0
  14. package/dist/activity/query.d.ts +16 -0
  15. package/dist/activity/query.d.ts.map +1 -0
  16. package/dist/activity/query.js +128 -0
  17. package/dist/activity/query.js.map +1 -0
  18. package/dist/activity/recorder.d.ts +48 -0
  19. package/dist/activity/recorder.d.ts.map +1 -0
  20. package/dist/activity/recorder.js +205 -0
  21. package/dist/activity/recorder.js.map +1 -0
  22. package/dist/activity/runtime.d.ts +31 -0
  23. package/dist/activity/runtime.d.ts.map +1 -0
  24. package/dist/activity/runtime.js +109 -0
  25. package/dist/activity/runtime.js.map +1 -0
  26. package/dist/activity/span-sink.d.ts +22 -0
  27. package/dist/activity/span-sink.d.ts.map +1 -0
  28. package/dist/activity/span-sink.js +138 -0
  29. package/dist/activity/span-sink.js.map +1 -0
  30. package/dist/activity/store.d.ts +207 -0
  31. package/dist/activity/store.d.ts.map +1 -0
  32. package/dist/activity/store.js +440 -0
  33. package/dist/activity/store.js.map +1 -0
  34. package/dist/activity/stream.d.ts +45 -0
  35. package/dist/activity/stream.d.ts.map +1 -0
  36. package/dist/activity/stream.js +312 -0
  37. package/dist/activity/stream.js.map +1 -0
  38. package/dist/app.d.ts.map +1 -1
  39. package/dist/app.js +20 -1
  40. package/dist/app.js.map +1 -1
  41. package/dist/config/env.d.ts +5 -0
  42. package/dist/config/env.d.ts.map +1 -1
  43. package/dist/config/env.js +12 -0
  44. package/dist/config/env.js.map +1 -1
  45. package/dist/cron/scheduler.d.ts.map +1 -1
  46. package/dist/cron/scheduler.js +20 -5
  47. package/dist/cron/scheduler.js.map +1 -1
  48. package/dist/db/client.d.ts.map +1 -1
  49. package/dist/db/client.js +32 -6
  50. package/dist/db/client.js.map +1 -1
  51. package/dist/index.d.ts +4 -0
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js +7 -0
  54. package/dist/index.js.map +1 -1
  55. package/dist/routes/activity.d.ts +20 -0
  56. package/dist/routes/activity.d.ts.map +1 -0
  57. package/dist/routes/activity.js +300 -0
  58. package/dist/routes/activity.js.map +1 -0
  59. package/dist/routes/push.d.ts +6 -0
  60. package/dist/routes/push.d.ts.map +1 -0
  61. package/dist/routes/push.js +73 -0
  62. package/dist/routes/push.js.map +1 -0
  63. package/dist/routes/sessions.d.ts.map +1 -1
  64. package/dist/routes/sessions.js +20 -4
  65. package/dist/routes/sessions.js.map +1 -1
  66. package/dist/ws/bridge.d.ts +2 -1
  67. package/dist/ws/bridge.d.ts.map +1 -1
  68. package/dist/ws/bridge.js +45 -3
  69. package/dist/ws/bridge.js.map +1 -1
  70. package/dist/ws/connection.d.ts.map +1 -1
  71. package/dist/ws/connection.js +41 -5
  72. package/dist/ws/connection.js.map +1 -1
  73. package/dist/ws/dispatch.d.ts.map +1 -1
  74. package/dist/ws/dispatch.js +11 -0
  75. package/dist/ws/dispatch.js.map +1 -1
  76. package/dist/ws/host.d.ts +16 -0
  77. package/dist/ws/host.d.ts.map +1 -1
  78. package/dist/ws/host.js +2 -0
  79. package/dist/ws/host.js.map +1 -1
  80. package/dist/ws/run-session.d.ts.map +1 -1
  81. package/dist/ws/run-session.js +25 -1
  82. package/dist/ws/run-session.js.map +1 -1
  83. package/dist/ws/turns.d.ts +22 -2
  84. package/dist/ws/turns.d.ts.map +1 -1
  85. package/dist/ws/turns.js +13 -0
  86. package/dist/ws/turns.js.map +1 -1
  87. package/migrations/007_activity.sql +114 -0
  88. package/migrations/008_push_subscriptions.sql +24 -0
  89. package/package.json +5 -3
  90. package/src/activity/digest.ts +92 -0
  91. package/src/activity/notify.ts +285 -0
  92. package/src/activity/push-sender.ts +215 -0
  93. package/src/activity/query.ts +160 -0
  94. package/src/activity/recorder.ts +261 -0
  95. package/src/activity/runtime.ts +141 -0
  96. package/src/activity/span-sink.ts +152 -0
  97. package/src/activity/store.ts +774 -0
  98. package/src/activity/stream.ts +366 -0
  99. package/src/app.ts +21 -1
  100. package/src/config/env.ts +19 -0
  101. package/src/cron/scheduler.ts +28 -8
  102. package/src/db/client.ts +31 -6
  103. package/src/index.ts +22 -0
  104. package/src/routes/activity.ts +363 -0
  105. package/src/routes/push.ts +90 -0
  106. package/src/routes/sessions.ts +24 -4
  107. package/src/ws/bridge.ts +47 -3
  108. package/src/ws/connection.ts +57 -5
  109. package/src/ws/dispatch.ts +13 -0
  110. package/src/ws/host.ts +18 -0
  111. package/src/ws/run-session.ts +32 -1
  112. package/src/ws/turns.ts +29 -1
package/dist/db/client.js CHANGED
@@ -5,6 +5,12 @@ export function createUiDb(dbPath, options = {}) {
5
5
  const db = new Database(dbPath, { create: true });
6
6
  db.exec("PRAGMA journal_mode = WAL");
7
7
  db.exec("PRAGMA foreign_keys = ON");
8
+ // Two processes write this database (the server and the cron wrapper). The
9
+ // timeout makes a writer wait for a held lock instead of failing on it.
10
+ // It does NOT rescue a deferred transaction that loses the snapshot-upgrade
11
+ // race (that still throws SQLITE_BUSY) — which is why activity writes use
12
+ // immediate transactions; see src/activity/store.ts.
13
+ db.exec("PRAGMA busy_timeout = 5000");
8
14
  runMigrations(db, options.log);
9
15
  return db;
10
16
  }
@@ -40,12 +46,32 @@ function runMigrations(database, log) {
40
46
  continue;
41
47
  log?.emit({ severityText: "INFO", body: "applying migration", attributes: { file } });
42
48
  const sql = readFileSync(join(migrationsDir, file), "utf-8");
43
- database.transaction(() => {
44
- database.exec(sql);
45
- database
46
- .prepare("INSERT INTO _migrations (filename, applied_at) VALUES (?, ?)")
47
- .run(file, Date.now());
48
- })();
49
+ try {
50
+ database.transaction(() => {
51
+ database.exec(sql);
52
+ database
53
+ .prepare("INSERT INTO _migrations (filename, applied_at) VALUES (?, ?)")
54
+ .run(file, Date.now());
55
+ })();
56
+ }
57
+ catch (err) {
58
+ // Two processes racing a first boot: the loser's transaction fails on
59
+ // the UNIQUE _migrations.filename insert (or on DDL the winner already
60
+ // ran). If the file is now recorded as applied, treat it as such and
61
+ // move on; anything else is a real migration failure.
62
+ const nowApplied = database
63
+ .query("SELECT 1 FROM _migrations WHERE filename = ?")
64
+ .get(file);
65
+ const uniqueViolation = err instanceof Error &&
66
+ err.message.includes("UNIQUE constraint failed: _migrations.filename");
67
+ if (!nowApplied && !uniqueViolation)
68
+ throw err;
69
+ log?.emit({
70
+ severityText: "INFO",
71
+ body: "migration applied concurrently by another process; skipping",
72
+ attributes: { file },
73
+ });
74
+ }
49
75
  }
50
76
  }
51
77
  //# sourceMappingURL=client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/db/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAsB5B,MAAM,UAAU,UAAU,CAAC,MAAc,EAAE,UAA6B,EAAE;IACxE,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAClD,EAAE,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IACrC,EAAE,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IACpC,aAAa,CAAC,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IAC/B,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,aAAa,CAAC,QAAkB,EAAE,GAAY;IACrD,kCAAkC;IAClC,QAAQ,CAAC,IAAI,CAAC;;;;;;GAMb,CAAC,CAAC;IAEH,uEAAuE;IACvE,yEAAyE;IACzE,6EAA6E;IAC7E,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;IAChE,IAAI,KAAe,CAAC;IACpB,IAAI,CAAC;QACH,KAAK,GAAG,WAAW,CAAC,aAAa,CAAC;aAC/B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;aACjC,IAAI,EAAE,CAAC;IACZ,CAAC;IAAC,MAAM,CAAC;QACP,GAAG,EAAE,IAAI,CAAC,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,8CAA8C,EAAE,CAAC,CAAC;QAC1F,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,GAAG,CACrB,QAAQ;SACL,KAAK,CAAC,kCAAkC,CAAC;SACzC,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAC/B,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,SAAS;QAEhC,GAAG,EAAE,IAAI,CAAC,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,oBAAoB,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;QACtF,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;QAE7D,QAAQ,CAAC,WAAW,CAAC,GAAG,EAAE;YACxB,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACnB,QAAQ;iBACL,OAAO,CAAC,8DAA8D,CAAC;iBACvE,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAC3B,CAAC,CAAC,EAAE,CAAC;IACP,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/db/client.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -21,6 +21,10 @@ export { resolveTurnTarget } from "./ws/routing.js";
21
21
  export { createSessionCatalog, type SessionCatalog, } from "./ws/session-catalog.js";
22
22
  export { createBrainClient, type BrainClient } from "./brain/client.js";
23
23
  export { recordCronRun, type CronRunRecord } from "./cron/scheduler.js";
24
+ export { createActivityStore, SPAN_OUTCOMES, type ActivityStore, type SpanRow, type SpanEventRow, type SpanOutcome, type SpanUsage, type ActivityChange, } from "./activity/store.js";
25
+ export { createActivityStream, type ActivityStream } from "./activity/stream.js";
26
+ export { ingestSpanSink } from "./activity/span-sink.js";
27
+ export { generateActivityDigest, latestActivityDigest, DIGEST_JOB_NAME, type ActivityDigest, } from "./activity/digest.js";
24
28
  export { pruneShareStaging, shareStagingRoot } from "./share/staging.js";
25
29
  export { createObservability, createRecordingObservability, createSilentObservability, createConsoleLoggerProvider, createRecordingLoggerProvider, createSilentLoggerProvider, createInMemoryMeterProvider, SEVERITIES, severityRank, seriesKey, } from "./observability/index.js";
26
30
  export type { Observability, ObservabilityOptions, RecordingObservability, RecordingLoggerProvider, InMemoryMeterProvider, LogReader, LogWriter, MetricsReader, Severity, CapturedLog, LogQuery, MetricPoint, MetricSnapshot, } from "./observability/index.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EACL,SAAS,EACT,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,WAAW,GACjB,MAAM,UAAU,CAAC;AAIlB,OAAO,EACL,QAAQ,EACR,mBAAmB,EACnB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,WAAW,GACjB,MAAM,iBAAiB,CAAC;AAIzB,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,2BAA2B,EAC3B,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,GACzB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,eAAe,EACf,KAAK,QAAQ,EACb,KAAK,WAAW,GACjB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAI5C,OAAO,EACL,WAAW,EACX,WAAW,EACX,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAClF,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,KAAK,eAAe,GACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EACL,oBAAoB,EACpB,KAAK,cAAc,GACpB,MAAM,yBAAyB,CAAC;AAIjC,OAAO,EAAE,iBAAiB,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAKxE,OAAO,EAAE,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIxE,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAKzE,OAAO,EACL,mBAAmB,EACnB,4BAA4B,EAC5B,yBAAyB,EACzB,2BAA2B,EAC3B,6BAA6B,EAC7B,0BAA0B,EAC1B,2BAA2B,EAC3B,UAAU,EACV,YAAY,EACZ,SAAS,GACV,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,aAAa,EACb,oBAAoB,EACpB,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,EACrB,SAAS,EACT,SAAS,EACT,aAAa,EACb,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,WAAW,EACX,cAAc,GACf,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EACL,aAAa,EACb,UAAU,EACV,KAAK,eAAe,GACrB,MAAM,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EACL,SAAS,EACT,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,WAAW,GACjB,MAAM,UAAU,CAAC;AAIlB,OAAO,EACL,QAAQ,EACR,mBAAmB,EACnB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,WAAW,GACjB,MAAM,iBAAiB,CAAC;AAIzB,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,2BAA2B,EAC3B,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,GACzB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,eAAe,EACf,KAAK,QAAQ,EACb,KAAK,WAAW,GACjB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAI5C,OAAO,EACL,WAAW,EACX,WAAW,EACX,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAClF,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,KAAK,eAAe,GACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EACL,oBAAoB,EACpB,KAAK,cAAc,GACpB,MAAM,yBAAyB,CAAC;AAIjC,OAAO,EAAE,iBAAiB,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAKxE,OAAO,EAAE,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAKxE,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,KAAK,aAAa,EAClB,KAAK,OAAO,EACZ,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,cAAc,GACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,oBAAoB,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,eAAe,EACf,KAAK,cAAc,GACpB,MAAM,sBAAsB,CAAC;AAI9B,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAKzE,OAAO,EACL,mBAAmB,EACnB,4BAA4B,EAC5B,yBAAyB,EACzB,2BAA2B,EAC3B,6BAA6B,EAC7B,0BAA0B,EAC1B,2BAA2B,EAC3B,UAAU,EACV,YAAY,EACZ,SAAS,GACV,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,aAAa,EACb,oBAAoB,EACpB,sBAAsB,EACtB,uBAAuB,EACvB,qBAAqB,EACrB,SAAS,EACT,SAAS,EACT,aAAa,EACb,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,WAAW,EACX,cAAc,GACf,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EACL,aAAa,EACb,UAAU,EACV,KAAK,eAAe,GACrB,MAAM,4BAA4B,CAAC"}
package/dist/index.js CHANGED
@@ -34,6 +34,13 @@ export { createBrainClient } from "./brain/client.js";
34
34
  // an external scheduler's wrapper records each run here so /api/status's
35
35
  // `cronJobs` reflects what actually ran.
36
36
  export { recordCronRun } from "./cron/scheduler.js";
37
+ // The activity record. The cron wrapper is a second PROCESS writing spans
38
+ // into the same store (root span + heartbeat + span-sink ingest); everything
39
+ // else consumes it through the app.
40
+ export { createActivityStore, SPAN_OUTCOMES, } from "./activity/store.js";
41
+ export { createActivityStream } from "./activity/stream.js";
42
+ export { ingestSpanSink } from "./activity/span-sink.js";
43
+ export { generateActivityDigest, latestActivityDigest, DIGEST_JOB_NAME, } from "./activity/digest.js";
37
44
  // Share staging: a deployment can sweep expired staging dirs at boot; the
38
45
  // intake route also sweeps opportunistically on every share.
39
46
  export { pruneShareStaging, shareStagingRoot } from "./share/staging.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EACL,SAAS,GAIV,MAAM,UAAU,CAAC;AAElB,6EAA6E;AAC7E,8EAA8E;AAC9E,OAAO,EACL,QAAQ,EACR,mBAAmB,GAOpB,MAAM,iBAAiB,CAAC;AAEzB,4EAA4E;AAC5E,+BAA+B;AAC/B,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,2BAA2B,GAK5B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,eAAe,GAGhB,MAAM,sBAAsB,CAAC;AAE9B,gEAAgE;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE5C,uEAAuE;AACvE,qBAAqB;AACrB,OAAO,EACL,WAAW,EACX,WAAW,EACX,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,kBAAkB,CAAC;AAE1B,+CAA+C;AAC/C,OAAO,EAAE,MAAM,EAAsB,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAClF,OAAO,EACL,mBAAmB,EACnB,aAAa,GAEd,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EACL,oBAAoB,GAErB,MAAM,yBAAyB,CAAC;AAEjC,0EAA0E;AAC1E,2BAA2B;AAC3B,OAAO,EAAE,iBAAiB,EAAoB,MAAM,mBAAmB,CAAC;AAExE,8EAA8E;AAC9E,yEAAyE;AACzE,yCAAyC;AACzC,OAAO,EAAE,aAAa,EAAsB,MAAM,qBAAqB,CAAC;AAExE,0EAA0E;AAC1E,6DAA6D;AAC7D,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEzE,4EAA4E;AAC5E,+EAA+E;AAC/E,2EAA2E;AAC3E,OAAO,EACL,mBAAmB,EACnB,4BAA4B,EAC5B,yBAAyB,EACzB,2BAA2B,EAC3B,6BAA6B,EAC7B,0BAA0B,EAC1B,2BAA2B,EAC3B,UAAU,EACV,YAAY,EACZ,SAAS,GACV,MAAM,0BAA0B,CAAC;AAiBlC,wEAAwE;AACxE,OAAO,EACL,aAAa,EACb,UAAU,GAEX,MAAM,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EACL,SAAS,GAIV,MAAM,UAAU,CAAC;AAElB,6EAA6E;AAC7E,8EAA8E;AAC9E,OAAO,EACL,QAAQ,EACR,mBAAmB,GAOpB,MAAM,iBAAiB,CAAC;AAEzB,4EAA4E;AAC5E,+BAA+B;AAC/B,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,2BAA2B,GAK5B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,eAAe,GAGhB,MAAM,sBAAsB,CAAC;AAE9B,gEAAgE;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE5C,uEAAuE;AACvE,qBAAqB;AACrB,OAAO,EACL,WAAW,EACX,WAAW,EACX,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,kBAAkB,CAAC;AAE1B,+CAA+C;AAC/C,OAAO,EAAE,MAAM,EAAsB,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAClF,OAAO,EACL,mBAAmB,EACnB,aAAa,GAEd,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EACL,oBAAoB,GAErB,MAAM,yBAAyB,CAAC;AAEjC,0EAA0E;AAC1E,2BAA2B;AAC3B,OAAO,EAAE,iBAAiB,EAAoB,MAAM,mBAAmB,CAAC;AAExE,8EAA8E;AAC9E,yEAAyE;AACzE,yCAAyC;AACzC,OAAO,EAAE,aAAa,EAAsB,MAAM,qBAAqB,CAAC;AAExE,0EAA0E;AAC1E,6EAA6E;AAC7E,oCAAoC;AACpC,OAAO,EACL,mBAAmB,EACnB,aAAa,GAOd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,oBAAoB,EAAuB,MAAM,sBAAsB,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,eAAe,GAEhB,MAAM,sBAAsB,CAAC;AAE9B,0EAA0E;AAC1E,6DAA6D;AAC7D,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEzE,4EAA4E;AAC5E,+EAA+E;AAC/E,2EAA2E;AAC3E,OAAO,EACL,mBAAmB,EACnB,4BAA4B,EAC5B,yBAAyB,EACzB,2BAA2B,EAC3B,6BAA6B,EAC7B,0BAA0B,EAC1B,2BAA2B,EAC3B,UAAU,EACV,YAAY,EACZ,SAAS,GACV,MAAM,0BAA0B,CAAC;AAiBlC,wEAAwE;AACxE,OAAO,EACL,aAAa,EACb,UAAU,GAEX,MAAM,4BAA4B,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { Hono } from "hono";
2
+ import type { Database } from "bun:sqlite";
3
+ import { type ActivityStore } from "../activity/store.js";
4
+ import type { ActivityNotifier } from "../activity/notify.js";
5
+ /**
6
+ * The activity record's read API. Auth-guarded like every /api route (the
7
+ * record leaks strictly more than /api/status, which is itself deliberately
8
+ * behind the guard).
9
+ *
10
+ * Resolution rules (origin R26): a run id that ever existed resolves — to
11
+ * the full span tree while detail is retained, to its rollup ("detail
12
+ * pruned") afterwards; only never-existed ids 404. Cost/token aggregates
13
+ * read per-run rollups, which carry ROOT-span accounting only.
14
+ */
15
+ export declare function createActivityRoutes(deps: {
16
+ db: Database;
17
+ store: ActivityStore;
18
+ notifier?: ActivityNotifier;
19
+ }): Hono;
20
+ //# sourceMappingURL=activity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity.d.ts","sourceRoot":"","sources":["../../src/routes/activity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAU3C,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAS9D;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IACzC,EAAE,EAAE,QAAQ,CAAC;IACb,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B,GAAG,IAAI,CAqQP"}
@@ -0,0 +1,300 @@
1
+ import { Hono } from "hono";
2
+ import { isFailureOutcome, } from "@schlessera/brain-ui-sdk/protocol";
3
+ import { rowToRunRollup } from "../activity/store.js";
4
+ import { toWireEvent, toWireSpan } from "../activity/stream.js";
5
+ import { dismissActivityDigest, digestDismissedAt, generateActivityDigest, latestActivityDigest, } from "../activity/digest.js";
6
+ import { getSetting, setSetting } from "../db/settings.js";
7
+ /**
8
+ * The activity record's read API. Auth-guarded like every /api route (the
9
+ * record leaks strictly more than /api/status, which is itself deliberately
10
+ * behind the guard).
11
+ *
12
+ * Resolution rules (origin R26): a run id that ever existed resolves — to
13
+ * the full span tree while detail is retained, to its rollup ("detail
14
+ * pruned") afterwards; only never-existed ids 404. Cost/token aggregates
15
+ * read per-run rollups, which carry ROOT-span accounting only.
16
+ */
17
+ export function createActivityRoutes(deps) {
18
+ const { db, store, notifier } = deps;
19
+ return new Hono()
20
+ .get("/activity/digest", (c) => {
21
+ try {
22
+ // An authenticated fetch IS the app opening — the marker the next
23
+ // digest window's framing leans on.
24
+ setSetting(db, "activity.lastVisitAt", Date.now());
25
+ return c.json({
26
+ digest: latestActivityDigest(db),
27
+ dismissedAt: digestDismissedAt(db),
28
+ });
29
+ }
30
+ catch (err) {
31
+ return c.json({ error: err instanceof Error ? err.message : "Failed to load digest" }, 500);
32
+ }
33
+ })
34
+ .post("/activity/digest/dismiss", (c) => {
35
+ try {
36
+ dismissActivityDigest(db);
37
+ return c.json({ ok: true });
38
+ }
39
+ catch (err) {
40
+ return c.json({ error: err instanceof Error ? err.message : "Failed to dismiss" }, 500);
41
+ }
42
+ })
43
+ .post("/activity/digest/generate", (c) => {
44
+ // Manual trigger (the cron job calls generateActivityDigest directly
45
+ // through the script; this exists for dev and for a pull-to-refresh).
46
+ try {
47
+ return c.json({ digest: generateActivityDigest(db) });
48
+ }
49
+ catch (err) {
50
+ return c.json({ error: err instanceof Error ? err.message : "Failed to generate" }, 500);
51
+ }
52
+ })
53
+ .get("/activity/inbox", (c) => {
54
+ try {
55
+ return c.json({ intents: notifier?.inbox() ?? [] });
56
+ }
57
+ catch (err) {
58
+ return c.json({ error: err instanceof Error ? err.message : "Failed to list inbox" }, 500);
59
+ }
60
+ })
61
+ .post("/activity/inbox/ack-all", (c) => {
62
+ try {
63
+ return c.json({ acknowledged: notifier?.acknowledgeAll() ?? 0 });
64
+ }
65
+ catch (err) {
66
+ return c.json({ error: err instanceof Error ? err.message : "Failed to acknowledge" }, 500);
67
+ }
68
+ })
69
+ .post("/activity/inbox/:id/ack", (c) => {
70
+ const id = Number(c.req.param("id"));
71
+ if (!Number.isInteger(id) || id < 1)
72
+ return c.json({ error: "Bad intent id" }, 400);
73
+ try {
74
+ const ok = notifier?.acknowledge(id) ?? false;
75
+ return ok ? c.json({ ok: true }) : c.json({ error: "Unknown intent" }, 404);
76
+ }
77
+ catch (err) {
78
+ return c.json({ error: err instanceof Error ? err.message : "Failed to acknowledge" }, 500);
79
+ }
80
+ })
81
+ .get("/activity/runs", (c) => {
82
+ try {
83
+ const limit = Math.min(Math.max(Number(c.req.query("limit") ?? 50) || 50, 1), 200);
84
+ const before = Number(c.req.query("before")) || Date.now() + 1;
85
+ const origin = c.req.query("origin");
86
+ const job = c.req.query("job");
87
+ const session = c.req.query("session");
88
+ const status = c.req.query("status");
89
+ // Live first (open roots), then history from rollups. Rollups exist
90
+ // for every finished run (terminal writes upsert them), so one table
91
+ // serves the history list regardless of pruning state.
92
+ const live = store
93
+ .openRootSpans()
94
+ .filter((s) => !origin || s.origin === origin)
95
+ .filter((s) => !job || s.jobName === job)
96
+ .filter((s) => !session || s.sessionId === session)
97
+ .map((s) => ({
98
+ runId: s.runId,
99
+ origin: s.origin,
100
+ name: s.name,
101
+ sessionId: s.sessionId,
102
+ jobName: s.jobName,
103
+ startedAt: s.startedAt,
104
+ endedAt: null,
105
+ outcome: null,
106
+ running: true,
107
+ durationMs: null,
108
+ costUsd: s.usage.costUsd ?? null,
109
+ failureReason: null,
110
+ detailPruned: false,
111
+ }));
112
+ const filters = ["started_at < ?"];
113
+ const params = [before];
114
+ if (origin) {
115
+ filters.push("origin = ?");
116
+ params.push(origin);
117
+ }
118
+ if (job) {
119
+ filters.push("job_name = ?");
120
+ params.push(job);
121
+ }
122
+ if (session) {
123
+ filters.push("session_id = ?");
124
+ params.push(session);
125
+ }
126
+ if (status) {
127
+ filters.push("outcome = ?");
128
+ params.push(status);
129
+ }
130
+ if (live.length > 0) {
131
+ filters.push(`run_id NOT IN (${live.map(() => "?").join(", ")})`);
132
+ params.push(...live.map((r) => r.runId));
133
+ }
134
+ const history = db
135
+ .query(`SELECT * FROM activity_run_rollups WHERE ${filters.join(" AND ")}
136
+ ORDER BY started_at DESC LIMIT ?`)
137
+ .all(...params, limit)
138
+ .map(rowToRunRollup)
139
+ .map((r) => ({
140
+ runId: r.runId,
141
+ origin: r.origin,
142
+ name: r.name,
143
+ sessionId: r.sessionId,
144
+ jobName: r.jobName,
145
+ startedAt: r.startedAt,
146
+ endedAt: r.endedAt,
147
+ outcome: r.outcome,
148
+ running: false,
149
+ durationMs: r.durationMs,
150
+ costUsd: r.costUsd,
151
+ failureReason: r.failureReason,
152
+ detailPruned: r.detailPruned,
153
+ }));
154
+ return c.json({ live, history });
155
+ }
156
+ catch (err) {
157
+ return c.json({ error: err instanceof Error ? err.message : "Failed to list activity" }, 500);
158
+ }
159
+ })
160
+ .get("/activity/runs/:runId", (c) => {
161
+ const runId = c.req.param("runId");
162
+ try {
163
+ const snapshot = store.snapshotRun(runId);
164
+ if (snapshot) {
165
+ // Through the SAME wire mappers the live stream uses: a raw
166
+ // SpanRow serializes null fields where the wire contract omits
167
+ // them, which broke the client's `outcome === undefined`
168
+ // liveness test on REST-loaded runs.
169
+ const detail = {
170
+ runId,
171
+ detailPruned: false,
172
+ spans: snapshot.spans.map(toWireSpan),
173
+ events: snapshot.events.map(toWireEvent),
174
+ highWaterSeq: snapshot.highWaterSeq,
175
+ };
176
+ return c.json(detail);
177
+ }
178
+ const row = db
179
+ .query("SELECT * FROM activity_run_rollups WHERE run_id = ?")
180
+ .get(runId);
181
+ if (!row)
182
+ return c.json({ error: "Unknown run" }, 404);
183
+ const r = rowToRunRollup(row);
184
+ const rollup = {
185
+ origin: r.origin,
186
+ name: r.name,
187
+ sessionId: r.sessionId,
188
+ jobName: r.jobName,
189
+ startedAt: r.startedAt,
190
+ endedAt: r.endedAt,
191
+ outcome: r.outcome,
192
+ durationMs: r.durationMs,
193
+ spanCount: r.spanCount,
194
+ costUsd: r.costUsd,
195
+ failureReason: r.failureReason,
196
+ };
197
+ const detail = { runId, detailPruned: true, rollup };
198
+ return c.json(detail);
199
+ }
200
+ catch (err) {
201
+ return c.json({ error: err instanceof Error ? err.message : "Failed to load run" }, 500);
202
+ }
203
+ })
204
+ .get("/activity/rollups", (c) => {
205
+ try {
206
+ const days = Math.min(Number(c.req.query("days") ?? 7) || 7, 90);
207
+ const since = Date.now() - days * 24 * 60 * 60 * 1000;
208
+ // The day boundary is the USER'S day, not UTC's — cron runs in UTC
209
+ // but nobody reviews spend in it. Configurable server-side.
210
+ const timeZone = getSetting(db, "activity.timezone", "UTC");
211
+ const dayOf = makeDayFormatter(timeZone);
212
+ // Job/session aggregates group SQL-side; the per-day fold stays in
213
+ // JS because only Intl knows the configured timezone's day boundary.
214
+ const rows = db
215
+ .query(`SELECT started_at, outcome, duration_ms, cost_usd, input_tokens,
216
+ output_tokens, cache_read_tokens, cache_creation_tokens
217
+ FROM activity_run_rollups WHERE started_at >= ?`)
218
+ .all(since);
219
+ const byDay = new Map();
220
+ for (const r of rows) {
221
+ add(byDay, dayOf(r.started_at), r);
222
+ }
223
+ const rollups = {
224
+ timeZone,
225
+ days: [...byDay.entries()]
226
+ .map(([key, a]) => ({ day: key, ...a }))
227
+ .sort((a, b) => (a.day < b.day ? 1 : -1)),
228
+ jobs: groupedAggregates(db, since, "job_name").map(({ key, ...a }) => ({
229
+ jobName: key,
230
+ ...a,
231
+ })),
232
+ sessions: groupedAggregates(db, since, "session_id").map(({ key, ...a }) => ({
233
+ sessionId: key,
234
+ ...a,
235
+ })),
236
+ };
237
+ return c.json(rollups);
238
+ }
239
+ catch (err) {
240
+ return c.json({ error: err instanceof Error ? err.message : "Failed to aggregate" }, 500);
241
+ }
242
+ });
243
+ }
244
+ /**
245
+ * SQL-side aggregation per group key. The failure predicate mirrors the
246
+ * SDK's `isFailureOutcome` — it cannot be shared into SQL, so keep the two
247
+ * in sync.
248
+ */
249
+ function groupedAggregates(db, since, column) {
250
+ return db
251
+ .query(`SELECT ${column} AS key,
252
+ COUNT(*) AS runs,
253
+ SUM(CASE WHEN outcome IN ('error', 'timeout', 'interrupted') THEN 1 ELSE 0 END) AS failures,
254
+ SUM(COALESCE(cost_usd, 0)) AS costUsd,
255
+ SUM(COALESCE(input_tokens, 0)) AS inputTokens,
256
+ SUM(COALESCE(output_tokens, 0)) AS outputTokens,
257
+ SUM(COALESCE(cache_read_tokens, 0)) AS cacheReadTokens,
258
+ SUM(COALESCE(cache_creation_tokens, 0)) AS cacheCreationTokens,
259
+ SUM(COALESCE(duration_ms, 0)) AS durationMs
260
+ FROM activity_run_rollups
261
+ WHERE started_at >= ? AND ${column} IS NOT NULL
262
+ GROUP BY ${column}`)
263
+ .all(since);
264
+ }
265
+ function add(map, key, r) {
266
+ const a = map.get(key) ??
267
+ {
268
+ runs: 0,
269
+ failures: 0,
270
+ costUsd: 0,
271
+ inputTokens: 0,
272
+ outputTokens: 0,
273
+ cacheReadTokens: 0,
274
+ cacheCreationTokens: 0,
275
+ durationMs: 0,
276
+ };
277
+ a.runs += 1;
278
+ if (isFailureOutcome(r.outcome)) {
279
+ a.failures += 1;
280
+ }
281
+ a.costUsd += r.cost_usd ?? 0;
282
+ a.inputTokens += r.input_tokens ?? 0;
283
+ a.outputTokens += r.output_tokens ?? 0;
284
+ a.cacheReadTokens += r.cache_read_tokens ?? 0;
285
+ a.cacheCreationTokens += r.cache_creation_tokens ?? 0;
286
+ a.durationMs += r.duration_ms ?? 0;
287
+ map.set(key, a);
288
+ }
289
+ /** YYYY-MM-DD in the given zone; a bad zone degrades loudly to UTC once. */
290
+ function makeDayFormatter(timeZone) {
291
+ let fmt;
292
+ try {
293
+ fmt = new Intl.DateTimeFormat("en-CA", { timeZone, dateStyle: "short" });
294
+ }
295
+ catch {
296
+ fmt = new Intl.DateTimeFormat("en-CA", { timeZone: "UTC", dateStyle: "short" });
297
+ }
298
+ return (ms) => fmt.format(new Date(ms));
299
+ }
300
+ //# sourceMappingURL=activity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity.js","sourceRoot":"","sources":["../../src/routes/activity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { Hono } from "hono";
2
+ import type { PushSender } from "../activity/push-sender.js";
3
+ export declare function createPushRoutes(deps: {
4
+ sender: PushSender;
5
+ }): Hono;
6
+ //# sourceMappingURL=push.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../src/routes/push.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAuB7D,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IAAE,MAAM,EAAE,UAAU,CAAA;CAAE,GAAG,IAAI,CA2DnE"}
@@ -0,0 +1,73 @@
1
+ import { Hono } from "hono";
2
+ import { z } from "zod";
3
+ /**
4
+ * Push subscription lifecycle. Behind the auth guard by mount position —
5
+ * the public key is per-deployment (not build-time), and subscribing is a
6
+ * write into the notification fan-out, which only the authenticated user
7
+ * may do. The VAPID PRIVATE key has no route, here or anywhere.
8
+ */
9
+ const subscribeSchema = z.object({
10
+ subscription: z.object({
11
+ endpoint: z.url().max(2048),
12
+ keys: z.object({
13
+ p256dh: z.string().min(1).max(512),
14
+ auth: z.string().min(1).max(512),
15
+ }),
16
+ }),
17
+ label: z.string().max(120).optional(),
18
+ });
19
+ const unsubscribeSchema = z.object({
20
+ endpoint: z.url().max(2048),
21
+ });
22
+ export function createPushRoutes(deps) {
23
+ const { sender } = deps;
24
+ return new Hono()
25
+ .get("/push/public-key", (c) => {
26
+ try {
27
+ return c.json({ publicKey: sender.publicKey() });
28
+ }
29
+ catch (err) {
30
+ return c.json({ error: err instanceof Error ? err.message : "Push unavailable" }, 500);
31
+ }
32
+ })
33
+ .get("/push/subscriptions", (c) => {
34
+ try {
35
+ // Endpoints are capability URLs — list only metadata.
36
+ return c.json({
37
+ subscriptions: sender.subscriptions().map((s) => ({
38
+ label: s.label,
39
+ createdAt: s.createdAt,
40
+ lastUsedAt: s.lastUsedAt,
41
+ // Enough for the client to recognize its own registration.
42
+ endpointHash: hashEndpoint(s.endpoint),
43
+ })),
44
+ });
45
+ }
46
+ catch (err) {
47
+ return c.json({ error: err instanceof Error ? err.message : "Failed to list" }, 500);
48
+ }
49
+ })
50
+ .post("/push/subscribe", async (c) => {
51
+ try {
52
+ const body = subscribeSchema.parse(await c.req.json());
53
+ sender.subscribe(body.subscription, body.label);
54
+ return c.json({ ok: true });
55
+ }
56
+ catch (err) {
57
+ return c.json({ error: err instanceof Error ? err.message : "Bad subscription" }, 400);
58
+ }
59
+ })
60
+ .post("/push/unsubscribe", async (c) => {
61
+ try {
62
+ const body = unsubscribeSchema.parse(await c.req.json());
63
+ return c.json({ removed: sender.unsubscribe(body.endpoint) });
64
+ }
65
+ catch (err) {
66
+ return c.json({ error: err instanceof Error ? err.message : "Bad request" }, 400);
67
+ }
68
+ });
69
+ }
70
+ function hashEndpoint(endpoint) {
71
+ return new Bun.CryptoHasher("sha256").update(endpoint).digest("hex").slice(0, 16);
72
+ }
73
+ //# sourceMappingURL=push.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/routes/push.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../src/routes/sessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACxC,QAAQ,EAAE,eAAe,CAAC;IAC1B,EAAE,EAAE,QAAQ,CAAC;CACd,GAAG,IAAI,CAgDP"}
1
+ {"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../src/routes/sessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACxC,QAAQ,EAAE,eAAe,CAAC;IAC1B,EAAE,EAAE,QAAQ,CAAC;CACd,GAAG,IAAI,CAoEP"}
@@ -11,10 +11,26 @@ export function createSessionRoutes(deps) {
11
11
  .get("/sessions", async (c) => {
12
12
  try {
13
13
  const backends = await registry.getBackends();
14
- const sessions = (await Promise.all(backends.map(async (backend) => (await backend.listSessions()).map((session) => ({
15
- ...session,
16
- backendId: backend.id,
17
- })))))
14
+ // The catalog's accounting (total_cost_usd, num_turns) was write-only
15
+ // for years on the default backend, whose listSessions hardcodes
16
+ // zeros — merge the stored numbers in so the drawer's cost renders
17
+ // from what the server actually recorded.
18
+ const accounting = new Map(db
19
+ .query("SELECT id, total_cost_usd AS cost, num_turns AS turns FROM sessions")
20
+ .all().map((r) => [r.id, r]));
21
+ const sessions = (await Promise.all(backends.map(async (backend) => (await backend.listSessions()).map((session) => {
22
+ const stored = accounting.get(session.id);
23
+ return {
24
+ ...session,
25
+ ...(stored?.cost && session.totalCostUsd === 0
26
+ ? { totalCostUsd: stored.cost }
27
+ : {}),
28
+ ...(stored?.turns && session.numTurns === 0
29
+ ? { numTurns: stored.turns }
30
+ : {}),
31
+ backendId: backend.id,
32
+ };
33
+ }))))
18
34
  .flat()
19
35
  .sort((a, b) => b.lastActiveAt - a.lastActiveAt);
20
36
  return c.json({ sessions });
@@ -1 +1 @@
1
- {"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/routes/sessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B,MAAM,UAAU,mBAAmB,CAAC,IAGnC;IACC,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;IAE9B,SAAS,kBAAkB,CAAC,SAAiB;QAC3C,MAAM,GAAG,GAAG,EAAE;aACX,KAAK,CAAC,2DAA2D,CAAC;aAClE,GAAG,CAAC,SAAS,CAAwC,CAAC;QACzD,OAAO,GAAG,EAAE,SAAS,IAAI,IAAI,CAAC;IAChC,CAAC;IAED,OAAO,IAAI,IAAI,EAAE;SAChB,GAAG,CAAC,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC5B,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC;YAC9C,MAAM,QAAQ,GAAG,CACf,MAAM,OAAO,CAAC,GAAG,CACf,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAC7B,CAAC,MAAM,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gBAC/C,GAAG,OAAO;gBACV,SAAS,EAAE,OAAO,CAAC,EAAE;aACtB,CAAC,CAAC,CACJ,CACF,CACF;iBACE,IAAI,EAAE;iBACN,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC;YACnD,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,CAAC,IAAI,CACX,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,yBAAyB,EAAE,EACzE,GAAG,CACJ,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;SAED,GAAG,CAAC,eAAe,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAChC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,oBAAoB,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5E,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;YAC9C,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;QAClC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,CAAC,IAAI,CACX,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,EAAE,EACvE,GAAG,CACJ,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/routes/sessions.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,8 @@
1
1
  import type { BackendBridge } from "@schlessera/brain-ui-sdk/server";
2
2
  import type { RunningTurn } from "./turns.js";
3
3
  import type { WsHost } from "./host.js";
4
+ import type { TurnRecorder } from "../activity/recorder.js";
4
5
  /** Build the per-turn bridge the backend drives. */
5
- export declare function makeBridge(host: WsHost, turn: RunningTurn, promptText: string, backendId: string): BackendBridge;
6
+ export declare function makeBridge(host: WsHost, turn: RunningTurn, promptText: string, backendId: string, recorder?: TurnRecorder): BackendBridge;
6
7
  export declare function emitTurnError(host: WsHost, turn: RunningTurn, err: unknown): void;
7
8
  //# sourceMappingURL=bridge.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../../src/ws/bridge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EAId,MAAM,iCAAiC,CAAC;AAGzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAExC,oDAAoD;AACpD,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,WAAW,EACjB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,aAAa,CAuIf;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,OAAO,GAAG,IAAI,CAwBjF"}
1
+ {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../../src/ws/bridge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,aAAa,EAId,MAAM,iCAAiC,CAAC;AAGzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5D,oDAAoD;AACpD,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,WAAW,EACjB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,YAAY,GACtB,aAAa,CAgLf;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,OAAO,GAAG,IAAI,CAwBjF"}