@north-light/crouter 0.3.262 → 0.3.263

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 (48) hide show
  1. package/dist/api/dto/health.d.ts +2 -0
  2. package/dist/builtin-memory/internal/memory-loading.md +3 -3
  3. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +4 -3
  4. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +5 -3
  5. package/dist/clients/attach/input/controller.d.ts +4 -0
  6. package/dist/clients/attach/input/controller.js +8 -0
  7. package/dist/clients/attach/session/bindings.d.ts +3 -0
  8. package/dist/clients/attach/session/bindings.js +7 -0
  9. package/dist/clients/attach/session/keys.d.ts +2 -0
  10. package/dist/clients/attach/session/keys.js +3 -3
  11. package/dist/clients/attach/viewer.js +616 -616
  12. package/dist/commands/memory/read.js +15 -38
  13. package/dist/commands/memory/shared.d.ts +1 -1
  14. package/dist/commands/memory/shared.js +1 -1
  15. package/dist/commands/sys/context/admin/docs-panel.d.ts +3 -3
  16. package/dist/commands/sys/context/admin/model.d.ts +7 -2
  17. package/dist/commands/sys/context/admin/model.js +7 -1
  18. package/dist/commands/sys/context/admin/read-view.d.ts +5 -5
  19. package/dist/commands/sys/context/admin/read-view.js +9 -4
  20. package/dist/commands/sys/context/resolve.d.ts +32 -3
  21. package/dist/commands/sys/context/resolve.js +74 -25
  22. package/dist/commands/sys/panels/models-panel.d.ts +28 -5
  23. package/dist/commands/sys/panels/models-panel.js +558 -75
  24. package/dist/core/__tests__/integration/broker-sdk-wiring.test.js +1 -1
  25. package/dist/core/__tests__/model-routes-config.test.d.ts +1 -0
  26. package/dist/core/__tests__/model-routes-config.test.js +142 -0
  27. package/dist/core/__tests__/on-read-nested-store.test.js +8 -0
  28. package/dist/core/__tests__/profile-project-memory-delivery.test.js +264 -1
  29. package/dist/core/__tests__/seam/broker-provider-retry.test.js +2 -2
  30. package/dist/core/canvas/render-source.d.ts +1 -1
  31. package/dist/core/canvas/render-source.js +3 -2
  32. package/dist/core/config.d.ts +19 -2
  33. package/dist/core/config.js +162 -47
  34. package/dist/core/keybindings/catalog.js +9 -7
  35. package/dist/core/model-routes.js +10 -3
  36. package/dist/core/substrate/listings.d.ts +1 -1
  37. package/dist/core/substrate/listings.js +6 -2
  38. package/dist/core/substrate/on-read.d.ts +61 -5
  39. package/dist/core/substrate/on-read.js +129 -22
  40. package/dist/core/substrate/render.d.ts +3 -2
  41. package/dist/core/substrate/render.js +133 -38
  42. package/dist/daemon/api/__tests__/seam/api-server.test.js +34 -0
  43. package/dist/daemon/api/handlers/canvas.js +18 -2
  44. package/dist/daemon/api/handlers/health.js +17 -12
  45. package/dist/pi-extensions/__tests__/pre-command-gate.test.js +2 -2
  46. package/dist/types.d.ts +4 -2
  47. package/package.json +1 -1
  48. package/runtime.lock.json +2 -2
@@ -12,26 +12,29 @@ import { currentVersion } from '../../../core/self-update.js';
12
12
  import { API_VERSION } from '../../../api/index.js';
13
13
  import { DEFAULT_INTERVAL_MS } from '../../supervise-cadence.js';
14
14
  import { envCrtrdTcp } from '../../../shared/env.js';
15
+ import { isPidAlive } from '../../../core/canvas/pid.js';
16
+ import { isBusy } from '../../../core/runtime/busy.js';
15
17
  // The daemon's supervise-loop cadence, echoed as an informational field; the
16
18
  // loop itself is unchanged (hard constraint). Derived from the single shared
17
19
  // constant so it can never drift from crtrd's actual interval.
18
20
  const TICK_INTERVAL_MS = DEFAULT_INTERVAL_MS;
19
- /** Count the canvas rows by status — a cheap store-access probe doubling as the
20
- * status snapshot's `node_counts`. Returns null when the store throws. */
21
- function nodeCounts() {
21
+ /** Read all canvas rows — a cheap store-access probe for health and status. */
22
+ function canvasRows() {
22
23
  try {
23
- const counts = {};
24
- for (const row of listNodes()) {
25
- counts[row.status] = (counts[row.status] ?? 0) + 1;
26
- }
27
- return counts;
24
+ return listNodes();
28
25
  }
29
26
  catch {
30
27
  return null;
31
28
  }
32
29
  }
30
+ function nodeCounts(rows) {
31
+ const counts = {};
32
+ for (const row of rows)
33
+ counts[row.status] = (counts[row.status] ?? 0) + 1;
34
+ return counts;
35
+ }
33
36
  function handleHealthz() {
34
- const storeAccessible = nodeCounts() !== null;
37
+ const storeAccessible = canvasRows() !== null;
35
38
  const body = {
36
39
  ok: storeAccessible,
37
40
  daemon_up: true,
@@ -41,16 +44,18 @@ function handleHealthz() {
41
44
  return { status: storeAccessible ? 200 : 503, body };
42
45
  }
43
46
  function handleStatus() {
44
- const counts = nodeCounts();
45
- if (counts === null) {
47
+ const rows = canvasRows();
48
+ if (rows === null) {
46
49
  // The store is unreachable — spec §8 store_unavailable.
47
50
  throw { status: 503, code: 'store_unavailable', message: 'canvas store is inaccessible' };
48
51
  }
52
+ const busyNodeCount = rows.filter((row) => row.kind !== 'human' && isBusy(row.node_id) && isPidAlive(row.pi_pid)).length;
49
53
  const tcp = envCrtrdTcp();
50
54
  const body = {
51
55
  daemon_pid: process.pid,
52
56
  tick_interval_ms: TICK_INTERVAL_MS,
53
- node_counts: counts,
57
+ node_counts: nodeCounts(rows),
58
+ busy_node_count: busyNodeCount,
54
59
  listeners: {
55
60
  socket_path: apiSocketPath(),
56
61
  tcp: tcp !== undefined && tcp !== '' ? tcp : null,
@@ -175,7 +175,7 @@ test('a matching command is held with its doc, every sibling in the message with
175
175
  // both — and that single fact is what releases the re-issue below.
176
176
  const afterBlock = loadContextExposureState('gate-hold');
177
177
  assert.deepEqual(afterBlock.exposures.get(docPath), { transcript: 3 }, 'the held doc is recorded as delivered');
178
- assert.equal(afterBlock.exposures.size, 2, 'the content alias is recorded alongside the path');
178
+ assert.equal(afterBlock.exposures.size, 4, 'the content alias and the read-equivalent memory-read companion are recorded alongside the held doc');
179
179
  // Siblings of the same assistant message. The doc is already exposed, so
180
180
  // without the per-turn flag the render would come back empty and let them
181
181
  // through. The flag covers the whole message, matching or not: every command
@@ -203,7 +203,7 @@ test('compaction re-arms the hold and leaves an exposure ledger that reloads', a
203
203
  // proof it did.
204
204
  const afterCompact = loadContextExposureState('gate-compact');
205
205
  assert.equal(afterCompact.exposures.has(docPath), false, 'compaction forgets the delivery that compaction dropped');
206
- assert.equal(afterCompact.exposures.size, 0, 'the content alias is forgotten too, and no rankless entry survives');
206
+ assert.equal(afterCompact.exposures.size, 2, 'the held doc and its alias are forgotten while its read-equivalent companion remains, with no rankless entry');
207
207
  const reheld = assertHeld(await pi.bash('deploy prod'), 'the same command after compaction');
208
208
  assert.ok(reheld.reason.includes(DOCTRINE_BODY), 'guidance the transcript no longer carries is delivered again');
209
209
  });
package/dist/types.d.ts CHANGED
@@ -189,12 +189,14 @@ export interface ModelLaddersConfig {
189
189
  openai: Record<ModelStrength, string>;
190
190
  }
191
191
  /** A declared provider/model route. Route ids are the keys of `modelRoutes` so
192
- * scopes can override one route without restating the registry. */
192
+ * scopes can override one route without restating the registry. `credentialSource`
193
+ * orders otherwise-equivalent routes; credentials are selected by `providerId`.
194
+ * Effective routes always name every strength. */
193
195
  export interface ModelRouteConfig {
194
196
  family: string;
195
197
  credentialSource: string;
196
198
  providerId: string;
197
- models: Partial<Record<ModelStrength, string>>;
199
+ models: Record<ModelStrength, string>;
198
200
  }
199
201
  export interface ModelRoutingConfig {
200
202
  credentialSourceOrder?: string[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@north-light/crouter",
3
- "version": "0.3.262",
3
+ "version": "0.3.263",
4
4
  "description": "crtr — agent runtime with memory, plugins, and marketplaces",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/runtime.lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@north-light/crouter",
3
- "version": "0.3.262",
3
+ "version": "0.3.263",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@north-light/crouter",
9
- "version": "0.3.262",
9
+ "version": "0.3.263",
10
10
  "hasInstallScript": true,
11
11
  "license": "MIT",
12
12
  "dependencies": {