@pellux/goodvibes-sdk 1.0.0 → 1.2.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/dist/contracts/artifacts/operator-contract.json +2878 -264
- package/dist/events/communication.d.ts +1 -1
- package/dist/platform/agents/orchestrator-runner.d.ts +5 -5
- package/dist/platform/agents/orchestrator-runner.js +6 -6
- package/dist/platform/agents/orchestrator.d.ts +4 -4
- package/dist/platform/agents/orchestrator.js +2 -2
- package/dist/platform/agents/wrfc-controller.d.ts +1 -1
- package/dist/platform/agents/wrfc-controller.js +3 -3
- package/dist/platform/calendar/index.d.ts +2 -2
- package/dist/platform/calendar/index.js +3 -3
- package/dist/platform/calendar/oauth-providers.d.ts +1 -1
- package/dist/platform/calendar/oauth-providers.js +1 -1
- package/dist/platform/calendar/oauth-types.d.ts +1 -1
- package/dist/platform/calendar/oauth-types.js +1 -1
- package/dist/platform/companion/companion-chat-branching.d.ts +66 -0
- package/dist/platform/companion/companion-chat-branching.d.ts.map +1 -0
- package/dist/platform/companion/companion-chat-branching.js +142 -0
- package/dist/platform/companion/companion-chat-broker-bridge.d.ts +1 -1
- package/dist/platform/companion/companion-chat-broker-bridge.d.ts.map +1 -1
- package/dist/platform/companion/companion-chat-broker-sync.d.ts +2 -2
- package/dist/platform/companion/companion-chat-broker-sync.d.ts.map +1 -1
- package/dist/platform/companion/companion-chat-broker-sync.js +1 -1
- package/dist/platform/companion/companion-chat-manager.d.ts +26 -5
- package/dist/platform/companion/companion-chat-manager.d.ts.map +1 -1
- package/dist/platform/companion/companion-chat-manager.js +67 -81
- package/dist/platform/companion/companion-chat-routes.d.ts.map +1 -1
- package/dist/platform/companion/companion-chat-routes.js +77 -1
- package/dist/platform/companion/companion-chat-turn-execution.d.ts +61 -0
- package/dist/platform/companion/companion-chat-turn-execution.d.ts.map +1 -0
- package/dist/platform/companion/companion-chat-turn-execution.js +107 -0
- package/dist/platform/companion/companion-chat-types.d.ts +67 -0
- package/dist/platform/companion/companion-chat-types.d.ts.map +1 -1
- package/dist/platform/config/credential-status.d.ts +1 -1
- package/dist/platform/config/credential-status.js +1 -1
- package/dist/platform/config/index.d.ts +1 -1
- package/dist/platform/config/index.js +1 -1
- package/dist/platform/config/manager.d.ts +1 -1
- package/dist/platform/config/manager.js +1 -1
- package/dist/platform/config/migrations.d.ts +2 -2
- package/dist/platform/config/migrations.js +2 -2
- package/dist/platform/config/schema-domain-runtime.d.ts +8 -0
- package/dist/platform/config/schema-domain-runtime.d.ts.map +1 -1
- package/dist/platform/config/schema-domain-runtime.js +32 -0
- package/dist/platform/config/schema-types.d.ts +10 -2
- package/dist/platform/config/schema-types.d.ts.map +1 -1
- package/dist/platform/control-plane/gateway-scope-enforcement.js +2 -2
- package/dist/platform/control-plane/index.d.ts +2 -0
- package/dist/platform/control-plane/index.d.ts.map +1 -1
- package/dist/platform/control-plane/index.js +5 -1
- package/dist/platform/control-plane/invoke-input-validation.d.ts +1 -1
- package/dist/platform/control-plane/invoke-input-validation.js +1 -1
- package/dist/platform/control-plane/method-catalog-calendar.d.ts +2 -2
- package/dist/platform/control-plane/method-catalog-calendar.js +2 -2
- package/dist/platform/control-plane/method-catalog-channels.js +3 -3
- package/dist/platform/control-plane/method-catalog-control-automation.js +4 -4
- package/dist/platform/control-plane/method-catalog-control-companion.d.ts +1 -1
- package/dist/platform/control-plane/method-catalog-control-companion.d.ts.map +1 -1
- package/dist/platform/control-plane/method-catalog-control-companion.js +43 -0
- package/dist/platform/control-plane/method-catalog-control-core.js +3 -3
- package/dist/platform/control-plane/method-catalog-email.d.ts +1 -1
- package/dist/platform/control-plane/method-catalog-email.js +1 -1
- package/dist/platform/control-plane/method-catalog-fleet.d.ts +1 -1
- package/dist/platform/control-plane/method-catalog-push.d.ts +30 -0
- package/dist/platform/control-plane/method-catalog-push.d.ts.map +1 -0
- package/dist/platform/control-plane/method-catalog-push.js +80 -0
- package/dist/platform/control-plane/method-catalog-route-reconcile.d.ts +1 -1
- package/dist/platform/control-plane/method-catalog-runtime.d.ts.map +1 -1
- package/dist/platform/control-plane/method-catalog-runtime.js +177 -1
- package/dist/platform/control-plane/method-catalog.d.ts.map +1 -1
- package/dist/platform/control-plane/method-catalog.js +2 -0
- package/dist/platform/control-plane/operator-contract-schemas-fleet.js +1 -1
- package/dist/platform/control-plane/operator-contract-schemas-runtime.d.ts +15 -0
- package/dist/platform/control-plane/operator-contract-schemas-runtime.d.ts.map +1 -1
- package/dist/platform/control-plane/operator-contract-schemas-runtime.js +81 -0
- package/dist/platform/control-plane/routes/checkpoints.d.ts +1 -1
- package/dist/platform/control-plane/routes/fleet.d.ts +2 -2
- package/dist/platform/control-plane/routes/fleet.js +1 -1
- package/dist/platform/control-plane/routes/gateway-verb-error.d.ts +1 -1
- package/dist/platform/control-plane/routes/gateway-verb-error.js +1 -1
- package/dist/platform/control-plane/routes/index.js +1 -1
- package/dist/platform/control-plane/routes/invocation-params.d.ts +1 -1
- package/dist/platform/control-plane/routes/push.d.ts +26 -0
- package/dist/platform/control-plane/routes/push.d.ts.map +1 -0
- package/dist/platform/control-plane/routes/push.js +104 -0
- package/dist/platform/control-plane/routes/register-gateway-verb-groups.d.ts +31 -0
- package/dist/platform/control-plane/routes/register-gateway-verb-groups.d.ts.map +1 -0
- package/dist/platform/control-plane/routes/register-gateway-verb-groups.js +16 -0
- package/dist/platform/control-plane/routes/register-w3-s2.d.ts +2 -2
- package/dist/platform/control-plane/routes/session-search.d.ts +4 -4
- package/dist/platform/control-plane/session-broker.d.ts +1 -1
- package/dist/platform/control-plane/session-broker.js +1 -1
- package/dist/platform/control-plane/session-store-importer.d.ts +1 -1
- package/dist/platform/control-plane/session-store-importer.js +1 -1
- package/dist/platform/control-plane/session-types.d.ts +1 -1
- package/dist/platform/core/orchestrator-runtime.d.ts +4 -4
- package/dist/platform/core/orchestrator-tool-runtime.d.ts +1 -1
- package/dist/platform/core/orchestrator-turn-loop.d.ts +6 -6
- package/dist/platform/core/orchestrator-turn-loop.d.ts.map +1 -1
- package/dist/platform/core/orchestrator-turn-loop.js +23 -22
- package/dist/platform/core/orchestrator.d.ts +10 -10
- package/dist/platform/core/orchestrator.d.ts.map +1 -1
- package/dist/platform/core/orchestrator.js +8 -8
- package/dist/platform/daemon/boot.d.ts +6 -0
- package/dist/platform/daemon/boot.d.ts.map +1 -1
- package/dist/platform/daemon/boot.js +1 -0
- package/dist/platform/daemon/control-plane.js +2 -2
- package/dist/platform/daemon/facade.d.ts +4 -7
- package/dist/platform/daemon/facade.d.ts.map +1 -1
- package/dist/platform/daemon/facade.js +5 -7
- package/dist/platform/daemon/http/router-session-broker-adapter.d.ts +1 -1
- package/dist/platform/daemon/http/router.d.ts +1 -0
- package/dist/platform/daemon/http/router.d.ts.map +1 -1
- package/dist/platform/daemon/http/router.js +36 -19
- package/dist/platform/daemon/http/runtime-route-types.d.ts +1 -1
- package/dist/platform/daemon/http/runtime-route-types.d.ts.map +1 -1
- package/dist/platform/daemon/http/webui-serving.d.ts +68 -0
- package/dist/platform/daemon/http/webui-serving.d.ts.map +1 -0
- package/dist/platform/daemon/http/webui-serving.js +230 -0
- package/dist/platform/knowledge/knowledge-api.d.ts +1 -1
- package/dist/platform/orchestration/budget.d.ts +2 -2
- package/dist/platform/orchestration/cancellation.d.ts +2 -2
- package/dist/platform/orchestration/controller-compat.d.ts +2 -3
- package/dist/platform/orchestration/controller-compat.d.ts.map +1 -1
- package/dist/platform/orchestration/dirty-guard.js +1 -1
- package/dist/platform/orchestration/engine.d.ts.map +1 -1
- package/dist/platform/orchestration/engine.js +3 -4
- package/dist/platform/orchestration/persistence.js +2 -2
- package/dist/platform/orchestration/phase-runner.d.ts +4 -4
- package/dist/platform/orchestration/scheduler.d.ts +1 -1
- package/dist/platform/orchestration/types.d.ts +3 -3
- package/dist/platform/presentation/glyphs.d.ts +1 -1
- package/dist/platform/presentation/glyphs.js +1 -1
- package/dist/platform/presentation/index.d.ts +3 -3
- package/dist/platform/presentation/index.js +3 -3
- package/dist/platform/presentation/thinking-phrases.d.ts +1 -1
- package/dist/platform/presentation/thinking-phrases.js +1 -1
- package/dist/platform/presentation/waiting-wording.d.ts +1 -1
- package/dist/platform/presentation/waiting-wording.js +1 -1
- package/dist/platform/push/delivery.d.ts +48 -0
- package/dist/platform/push/delivery.d.ts.map +1 -0
- package/dist/platform/push/delivery.js +117 -0
- package/dist/platform/push/encryption.d.ts +41 -0
- package/dist/platform/push/encryption.d.ts.map +1 -0
- package/dist/platform/push/encryption.js +82 -0
- package/dist/platform/push/index.d.ts +17 -0
- package/dist/platform/push/index.d.ts.map +1 -0
- package/dist/platform/push/index.js +10 -0
- package/dist/platform/push/service.d.ts +75 -0
- package/dist/platform/push/service.d.ts.map +1 -0
- package/dist/platform/push/service.js +95 -0
- package/dist/platform/push/subscription-store.d.ts +50 -0
- package/dist/platform/push/subscription-store.d.ts.map +1 -0
- package/dist/platform/push/subscription-store.js +123 -0
- package/dist/platform/push/types.d.ts +68 -0
- package/dist/platform/push/types.d.ts.map +1 -0
- package/dist/platform/push/types.js +13 -0
- package/dist/platform/push/vapid.d.ts +54 -0
- package/dist/platform/push/vapid.d.ts.map +1 -0
- package/dist/platform/push/vapid.js +113 -0
- package/dist/platform/runtime/feature-flags/flags.js +3 -3
- package/dist/platform/runtime/fleet/adapters/agent.d.ts +2 -2
- package/dist/platform/runtime/fleet/adapters/agent.d.ts.map +1 -1
- package/dist/platform/runtime/fleet/adapters/agent.js +4 -4
- package/dist/platform/runtime/fleet/adapters/automation.d.ts +1 -1
- package/dist/platform/runtime/fleet/adapters/automation.js +1 -1
- package/dist/platform/runtime/fleet/adapters/code-index.d.ts +1 -1
- package/dist/platform/runtime/fleet/adapters/code-index.js +1 -1
- package/dist/platform/runtime/fleet/adapters/orchestration.js +1 -1
- package/dist/platform/runtime/fleet/adapters/schedule.d.ts +4 -4
- package/dist/platform/runtime/fleet/adapters/schedule.js +4 -4
- package/dist/platform/runtime/fleet/adapters/trigger.d.ts +3 -4
- package/dist/platform/runtime/fleet/adapters/trigger.d.ts.map +1 -1
- package/dist/platform/runtime/fleet/adapters/trigger.js +3 -4
- package/dist/platform/runtime/fleet/adapters/wrfc.js +1 -1
- package/dist/platform/runtime/fleet/registry.d.ts +7 -7
- package/dist/platform/runtime/fleet/registry.d.ts.map +1 -1
- package/dist/platform/runtime/fleet/registry.js +3 -3
- package/dist/platform/runtime/fleet/types.d.ts +9 -9
- package/dist/platform/runtime/fleet/types.d.ts.map +1 -1
- package/dist/platform/runtime/memory-spine/client.d.ts +240 -0
- package/dist/platform/runtime/memory-spine/client.d.ts.map +1 -0
- package/dist/platform/runtime/memory-spine/client.js +221 -0
- package/dist/platform/runtime/memory-spine/index.d.ts +17 -0
- package/dist/platform/runtime/memory-spine/index.d.ts.map +1 -0
- package/dist/platform/runtime/memory-spine/index.js +16 -0
- package/dist/platform/runtime/memory-spine/recall-snapshot.d.ts +74 -0
- package/dist/platform/runtime/memory-spine/recall-snapshot.d.ts.map +1 -0
- package/dist/platform/runtime/memory-spine/recall-snapshot.js +74 -0
- package/dist/platform/runtime/operator-client.d.ts +1 -1
- package/dist/platform/runtime/services.d.ts +6 -6
- package/dist/platform/runtime/services.d.ts.map +1 -1
- package/dist/platform/runtime/services.js +9 -9
- package/dist/platform/runtime/session-spine/union-cache.d.ts +1 -1
- package/dist/platform/runtime/session-spine/union-cache.js +1 -1
- package/dist/platform/state/canonical-memory.d.ts +7 -7
- package/dist/platform/state/canonical-memory.js +8 -8
- package/dist/platform/state/code-index-chunking.js +1 -1
- package/dist/platform/state/code-index-db.d.ts +1 -1
- package/dist/platform/state/code-index-store.js +1 -1
- package/dist/platform/state/index.d.ts +2 -2
- package/dist/platform/state/index.d.ts.map +1 -1
- package/dist/platform/state/index.js +1 -1
- package/dist/platform/state/memory-recall-contract.d.ts +59 -4
- package/dist/platform/state/memory-recall-contract.d.ts.map +1 -1
- package/dist/platform/state/memory-recall-contract.js +79 -3
- package/dist/platform/state/memory-registry.d.ts +8 -0
- package/dist/platform/state/memory-registry.d.ts.map +1 -1
- package/dist/platform/state/memory-registry.js +10 -0
- package/dist/platform/state/memory-vector-store.js +1 -1
- package/dist/platform/state/sqlite-vec-loader.d.ts +1 -1
- package/dist/platform/state/sqlite-vec-loader.js +1 -1
- package/dist/platform/state/vibe-projection.d.ts +3 -3
- package/dist/platform/state/vibe-projection.js +3 -3
- package/dist/platform/tools/agent/manager.d.ts +10 -10
- package/dist/platform/tools/agent/manager.js +7 -7
- package/dist/platform/tools/exec/runtime.js +5 -5
- package/dist/platform/tools/exec/schema.d.ts +1 -1
- package/dist/platform/tools/exec/schema.d.ts.map +1 -1
- package/dist/platform/tools/fetch/runtime.d.ts +1 -1
- package/dist/platform/tools/registry.d.ts +1 -1
- package/dist/platform/tools/registry.js +1 -1
- package/dist/platform/types/tools.d.ts +1 -1
- package/dist/platform/utils/request-body.d.ts.map +1 -1
- package/dist/platform/utils/request-body.js +50 -5
- package/dist/platform/version.js +1 -1
- package/dist/platform/voice/index.d.ts +2 -0
- package/dist/platform/voice/index.d.ts.map +1 -1
- package/dist/platform/voice/index.js +3 -0
- package/dist/platform/voice/spoken-turn/audio-sink.d.ts +111 -0
- package/dist/platform/voice/spoken-turn/audio-sink.d.ts.map +1 -0
- package/dist/platform/voice/spoken-turn/audio-sink.js +1 -0
- package/dist/platform/voice/spoken-turn/controller.d.ts +117 -0
- package/dist/platform/voice/spoken-turn/controller.d.ts.map +1 -0
- package/dist/platform/voice/spoken-turn/controller.js +448 -0
- package/dist/platform/voice/spoken-turn/index.d.ts +16 -0
- package/dist/platform/voice/spoken-turn/index.d.ts.map +1 -0
- package/dist/platform/voice/spoken-turn/index.js +12 -0
- package/dist/platform/voice/spoken-turn/text-chunker.d.ts +33 -0
- package/dist/platform/voice/spoken-turn/text-chunker.d.ts.map +1 -0
- package/dist/platform/voice/spoken-turn/text-chunker.js +97 -0
- package/package.json +13 -9
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/platform/runtime/fleet/types.ts"],"names":[],"mappings":"AAAA,qFAAqF;AAErF;;;;;;;;;;GAUG;AAEH,wDAAwD;AACxD,MAAM,MAAM,WAAW,GACnB,OAAO,GACP,YAAY,GACZ,cAAc,GACd,UAAU,GACV,SAAS,GACT,UAAU,GACV,SAAS,GACT,oBAAoB,GAGpB,YAAY,GACZ,OAAO,GACP,WAAW,GAKX,YAAY,CAAC;AAEjB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,YAAY,GACpB,UAAU,GACV,gBAAgB,GAChB,mBAAmB,GACnB,WAAW,GACX,SAAS,GACT,UAAU,GACV,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,aAAa,GACb,MAAM,GACN,QAAQ,GACR,QAAQ,CAAC;AAEb,0FAA0F;AAC1F,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED,8FAA8F;AAC9F,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,OAAO,CAAC;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,qFAAqF;IACrF,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED,wEAAwE;AACxE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B;;;;;;;;OAQG;IACH,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/platform/runtime/fleet/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* client.ts — the SDK memory-spine surface client (host-vs-client access mode).
|
|
3
|
+
*
|
|
4
|
+
* The daemon-owned memory service makes the daemon the SINGLE WRITER of its
|
|
5
|
+
* canonical sql.js store. sql.js has no row locking and rewrites the whole file on
|
|
6
|
+
* every save(), so two live processes writing the same file clobber each other —
|
|
7
|
+
* a whole-file lost update that would DELETE memory. One process must own the
|
|
8
|
+
* store; every other surface reaches it over the wire.
|
|
9
|
+
*
|
|
10
|
+
* This client is the surface-side switch that realizes that invariant, mirroring
|
|
11
|
+
* the session-spine host-vs-client pattern:
|
|
12
|
+
*
|
|
13
|
+
* - HOST / OFFLINE-EMBEDDED mode (transport NOT attached): the surface IS the only
|
|
14
|
+
* process touching its own store file, so it reads/writes the LOCAL embedded
|
|
15
|
+
* store directly. This is the offline fallback the agent and TUI keep — a daemon
|
|
16
|
+
* is not required for them to work.
|
|
17
|
+
* - CLIENT-OF-ADOPTED-DAEMON mode (transport attached): the daemon owns the store;
|
|
18
|
+
* the surface routes EVERY memory op through the injected wire transport and
|
|
19
|
+
* NEVER opens the file. Enforced structurally here — the active branch only ever
|
|
20
|
+
* touches `this.transport`, never `this.local`.
|
|
21
|
+
*
|
|
22
|
+
* FULL DETACH (SDK 1.2.0). The 1.1.0 wire family covered five verbs (add,
|
|
23
|
+
* honestSearch, get, updateReview, delete). That was enough for a surface to store
|
|
24
|
+
* and recall a fact over the wire, but NOT enough to fully detach every consumer
|
|
25
|
+
* from the store file: the agent's `list`/`update`/semantic-search paths and the
|
|
26
|
+
* TUI's `/recall` browse/link/queue/export paths still fell back to a local file.
|
|
27
|
+
* This client now exposes the FULL read/write catalog those consumers need
|
|
28
|
+
* (see MemoryExtendedAccess), so a wire client never opens the file for ANY of them.
|
|
29
|
+
*
|
|
30
|
+
* ONE-WRITER ENFORCEMENT RULING. The platform's convention (see canonical-memory.ts
|
|
31
|
+
* and the session spine) is honest sequential/owned access plus stated posture, NOT
|
|
32
|
+
* an OS advisory lock — sql.js exposes no lock and a cross-process flock would be a
|
|
33
|
+
* new, unenforceable-on-every-OS mechanism the rest of the store does not rely on.
|
|
34
|
+
* So the invariant is enforced two ways, both honest: (1) mode exclusivity — a
|
|
35
|
+
* client in wire mode provably cannot reach the local file because the code routes
|
|
36
|
+
* exclusively to the transport; (2) a documented single-writer contract for the
|
|
37
|
+
* embedded case — the daemon host and an offline surface are each the sole process
|
|
38
|
+
* for their own file. `mode()` reports the current posture so a surface can surface
|
|
39
|
+
* it rather than guess.
|
|
40
|
+
*
|
|
41
|
+
* HONEST FAILURE. Unlike the fire-and-forget session mirror, memory reads/writes
|
|
42
|
+
* return data, so this client is request/response. In client mode a transport
|
|
43
|
+
* failure is SURFACED to the caller (the promise rejects); it is deliberately NOT
|
|
44
|
+
* silently served from the local store — a wire client must not open the
|
|
45
|
+
* daemon-owned file, and returning a divergent local copy as if it were canonical
|
|
46
|
+
* would be the exact dishonest-recall failure this whole design exists to prevent.
|
|
47
|
+
* A sustained daemon loss is handled by `deactivate()`, which returns the surface
|
|
48
|
+
* to owned-local mode explicitly.
|
|
49
|
+
*
|
|
50
|
+
* VERSION TOLERANCE. The five CORE verbs are required of every transport. The
|
|
51
|
+
* EXTENDED verbs are OPTIONAL on the transport (`MemoryTransport`) so a surface
|
|
52
|
+
* pinned to an older SDK/daemon pair that predates a verb still satisfies the type.
|
|
53
|
+
* When a client in wire mode calls an extended verb its adopted daemon does not
|
|
54
|
+
* implement, the call REJECTS with a stated reason — it never silently reaches into
|
|
55
|
+
* the local file, which would break the one-writer invariant and lie about which
|
|
56
|
+
* store answered.
|
|
57
|
+
*/
|
|
58
|
+
import { logger } from '../../utils/logger.js';
|
|
59
|
+
import type { MemoryAddOptions, MemoryBundle, MemoryDoctorReport, MemoryImportResult, MemoryLink, MemoryRecord, MemoryReviewPatch, MemoryScope, MemorySearchFilter, MemorySemanticSearchResult } from '../../state/memory-store.js';
|
|
60
|
+
import type { MemoryVectorStats } from '../../state/memory-vector-store.js';
|
|
61
|
+
import type { HonestMemorySearchOptions, HonestMemorySearchResult } from '../../state/memory-recall-contract.js';
|
|
62
|
+
import { type MemoryRecallSnapshot, type MemoryRecallRefreshOptions } from './recall-snapshot.js';
|
|
63
|
+
/** Patch shape accepted by an editable-field update (scope/summary/detail/tags). */
|
|
64
|
+
export interface MemoryUpdatePatch {
|
|
65
|
+
readonly scope?: MemoryScope | undefined;
|
|
66
|
+
readonly summary?: string | undefined;
|
|
67
|
+
readonly detail?: string | undefined;
|
|
68
|
+
readonly tags?: string[] | undefined;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* The five CORE verbs, shipped in 1.1.0. Every transport must implement all five —
|
|
72
|
+
* they are the minimum that lets a surface store and recall a fact over the wire.
|
|
73
|
+
*/
|
|
74
|
+
export interface MemoryCoreAccess {
|
|
75
|
+
add(opts: MemoryAddOptions): Promise<MemoryRecord>;
|
|
76
|
+
honestSearch(filter: MemorySearchFilter, options?: HonestMemorySearchOptions): Promise<HonestMemorySearchResult>;
|
|
77
|
+
get(id: string): Promise<MemoryRecord | null>;
|
|
78
|
+
updateReview(id: string, patch: MemoryReviewPatch): Promise<MemoryRecord | null>;
|
|
79
|
+
delete(id: string): Promise<boolean>;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The EXTENDED verbs added in 1.2.0 so a wire client can fully detach from the file.
|
|
83
|
+
* Each maps to a MemoryRegistry read/write the consumers were still doing locally:
|
|
84
|
+
* - `list` — bulk read (getAll / literal browse): knowledge injection + agent `list`.
|
|
85
|
+
* - `searchSemantic`— scored semantic recall: agent semantic path + TUI `/recall --semantic`.
|
|
86
|
+
* - `update` — edit scope/summary/detail/tags (a scope edit is how a record is "promoted" project→team).
|
|
87
|
+
* - `link`/`linksFor` — relate records / read a record's links.
|
|
88
|
+
* - `reviewQueue` — records prioritised for review (the curator/queue surface).
|
|
89
|
+
* - `exportBundle`/`importBundle` — the no-loss bundle seam over the wire.
|
|
90
|
+
* - `vectorStats`/`doctor` — read the daemon's canonical index diagnostics.
|
|
91
|
+
*
|
|
92
|
+
* DELIBERATELY NOT HERE (host-only, ruled in the full-detach decision record):
|
|
93
|
+
* `rebuildVectors`/`rebuildVectorsAsync`. Rebuilding the vector index is maintenance
|
|
94
|
+
* a store performs on its OWN index; the daemon keeps its canonical index current on
|
|
95
|
+
* every add/import and exposes an admin `POST /api/memory/vector/rebuild` for a forced
|
|
96
|
+
* rebuild. A wire client owns no index to rebuild, so a client-initiated rebuild is an
|
|
97
|
+
* admin/diagnostic action against a store it does not own — it stays out of band, not
|
|
98
|
+
* a per-record detach need.
|
|
99
|
+
*/
|
|
100
|
+
export interface MemoryExtendedAccess {
|
|
101
|
+
list(filter?: MemorySearchFilter): Promise<readonly MemoryRecord[]>;
|
|
102
|
+
searchSemantic(filter?: MemorySearchFilter): Promise<readonly MemorySemanticSearchResult[]>;
|
|
103
|
+
update(id: string, patch: MemoryUpdatePatch): Promise<MemoryRecord | null>;
|
|
104
|
+
link(fromId: string, toId: string, relation: string): Promise<MemoryLink | null>;
|
|
105
|
+
linksFor(id: string): Promise<readonly MemoryLink[]>;
|
|
106
|
+
reviewQueue(limit?: number, scope?: MemoryScope): Promise<readonly MemoryRecord[]>;
|
|
107
|
+
exportBundle(filter?: MemorySearchFilter): Promise<MemoryBundle>;
|
|
108
|
+
importBundle(bundle: MemoryBundle): Promise<MemoryImportResult>;
|
|
109
|
+
vectorStats(): Promise<MemoryVectorStats>;
|
|
110
|
+
doctor(): Promise<MemoryDoctorReport>;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* The full memory read/write surface a caller uses without caring whether it
|
|
114
|
+
* resolves locally or over the wire. Every method is async so a local (sync store)
|
|
115
|
+
* and a wire (async) backend present the SAME shape.
|
|
116
|
+
*/
|
|
117
|
+
export interface MemoryAccess extends MemoryCoreAccess, MemoryExtendedAccess {
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* The injected wire transport. A consumer builds a thin adapter over the daemon's
|
|
121
|
+
* memory.records.* routes. The five CORE verbs are required; the EXTENDED verbs are
|
|
122
|
+
* optional so a surface pinned to an older SDK/daemon still satisfies the type — a
|
|
123
|
+
* client calling an extended verb the adopted daemon lacks gets an honest rejection,
|
|
124
|
+
* never a silent local-file read.
|
|
125
|
+
*/
|
|
126
|
+
export type MemoryTransport = MemoryCoreAccess & Partial<MemoryExtendedAccess>;
|
|
127
|
+
/**
|
|
128
|
+
* The local embedded store surface. The SDK's `MemoryRegistry` satisfies this
|
|
129
|
+
* structurally (its methods are mostly synchronous; the facade normalizes them to
|
|
130
|
+
* promises). Kept minimal so the client stays decoupled from the concrete class.
|
|
131
|
+
*/
|
|
132
|
+
export interface LocalMemoryStore {
|
|
133
|
+
add(opts: MemoryAddOptions): Promise<MemoryRecord> | MemoryRecord;
|
|
134
|
+
honestSearch(filter: MemorySearchFilter, options?: HonestMemorySearchOptions): HonestMemorySearchResult;
|
|
135
|
+
get(id: string): MemoryRecord | null;
|
|
136
|
+
review(id: string, patch: MemoryReviewPatch): MemoryRecord | null;
|
|
137
|
+
delete(id: string): boolean;
|
|
138
|
+
search(filter?: MemorySearchFilter): MemoryRecord[];
|
|
139
|
+
searchSemantic(filter?: MemorySearchFilter): MemorySemanticSearchResult[];
|
|
140
|
+
update(id: string, patch: MemoryUpdatePatch): MemoryRecord | null;
|
|
141
|
+
link(fromId: string, toId: string, relation: string): Promise<MemoryLink | null> | MemoryLink | null;
|
|
142
|
+
linksFor(id: string): MemoryLink[];
|
|
143
|
+
reviewQueue(limit?: number, scope?: MemoryScope): MemoryRecord[];
|
|
144
|
+
exportBundle(filter?: MemorySearchFilter): MemoryBundle;
|
|
145
|
+
importBundle(bundle: MemoryBundle): Promise<MemoryImportResult> | MemoryImportResult;
|
|
146
|
+
vectorStats(): MemoryVectorStats;
|
|
147
|
+
doctor(): Promise<MemoryDoctorReport> | MemoryDoctorReport;
|
|
148
|
+
}
|
|
149
|
+
/** Wrap a local embedded store (e.g. a MemoryRegistry) as a full MemoryAccess. */
|
|
150
|
+
export declare function createLocalMemoryAccess(store: LocalMemoryStore): MemoryAccess;
|
|
151
|
+
/** Current access posture — honest, reportable, never guessed. */
|
|
152
|
+
export type MemoryAccessMode = 'local' | 'client';
|
|
153
|
+
type SpineLogger = Pick<typeof logger, 'debug' | 'info'>;
|
|
154
|
+
export interface MemorySpineClientOptions {
|
|
155
|
+
/** The local embedded store, always present as the offline/host backend. */
|
|
156
|
+
readonly local: MemoryAccess;
|
|
157
|
+
/**
|
|
158
|
+
* Attach a wire transport at construction for CLIENT mode immediately (a surface
|
|
159
|
+
* that boots already adopted to a daemon). Omit for LOCAL mode until `activate()`
|
|
160
|
+
* (a surface that adopts a daemon later, or runs offline forever).
|
|
161
|
+
*/
|
|
162
|
+
readonly transport?: MemoryTransport | undefined;
|
|
163
|
+
/**
|
|
164
|
+
* How long a recall snapshot stays "fresh" before `recallSnapshot()` reports it
|
|
165
|
+
* stale. Defaults to {@link DEFAULT_RECALL_SNAPSHOT_STALE_AFTER_MS}.
|
|
166
|
+
*/
|
|
167
|
+
readonly recallSnapshotStaleAfterMs?: number | undefined;
|
|
168
|
+
readonly log?: SpineLogger;
|
|
169
|
+
}
|
|
170
|
+
export type { MemoryRecallSnapshot, MemoryRecallRefreshOptions } from './recall-snapshot.js';
|
|
171
|
+
/**
|
|
172
|
+
* Routes memory access to the LOCAL embedded store or, when a daemon has been
|
|
173
|
+
* adopted, THROUGH the wire — never both. Implements {@link MemoryAccess} so a
|
|
174
|
+
* caller uses one object regardless of mode.
|
|
175
|
+
*/
|
|
176
|
+
export declare class MemorySpineClient implements MemoryAccess {
|
|
177
|
+
private readonly local;
|
|
178
|
+
private transport;
|
|
179
|
+
private readonly log;
|
|
180
|
+
private readonly staleAfterMs;
|
|
181
|
+
/** Last recall snapshot captured by refreshRecallSnapshot(); null until first refresh. */
|
|
182
|
+
private snapshot;
|
|
183
|
+
constructor(options: MemorySpineClientOptions);
|
|
184
|
+
/** The current posture: 'client' when routing over the wire, 'local' otherwise. */
|
|
185
|
+
mode(): MemoryAccessMode;
|
|
186
|
+
/** Whether a wire transport is attached (client-of-adopted-daemon mode). */
|
|
187
|
+
get active(): boolean;
|
|
188
|
+
/**
|
|
189
|
+
* Adopt a daemon: route every memory op through the wire from now on. The local
|
|
190
|
+
* store is left untouched for the lifetime of client mode — the daemon is the
|
|
191
|
+
* single writer.
|
|
192
|
+
*/
|
|
193
|
+
activate(transport: MemoryTransport): void;
|
|
194
|
+
/** Release the daemon (mode lost / daemon stopped): return to owned-local access. */
|
|
195
|
+
deactivate(reason: string): void;
|
|
196
|
+
add(opts: MemoryAddOptions): Promise<MemoryRecord>;
|
|
197
|
+
honestSearch(filter: MemorySearchFilter, options?: HonestMemorySearchOptions): Promise<HonestMemorySearchResult>;
|
|
198
|
+
get(id: string): Promise<MemoryRecord | null>;
|
|
199
|
+
updateReview(id: string, patch: MemoryReviewPatch): Promise<MemoryRecord | null>;
|
|
200
|
+
delete(id: string): Promise<boolean>;
|
|
201
|
+
list(filter?: MemorySearchFilter): Promise<readonly MemoryRecord[]>;
|
|
202
|
+
searchSemantic(filter?: MemorySearchFilter): Promise<readonly MemorySemanticSearchResult[]>;
|
|
203
|
+
update(id: string, patch: MemoryUpdatePatch): Promise<MemoryRecord | null>;
|
|
204
|
+
link(fromId: string, toId: string, relation: string): Promise<MemoryLink | null>;
|
|
205
|
+
linksFor(id: string): Promise<readonly MemoryLink[]>;
|
|
206
|
+
reviewQueue(limit?: number, scope?: MemoryScope): Promise<readonly MemoryRecord[]>;
|
|
207
|
+
exportBundle(filter?: MemorySearchFilter): Promise<MemoryBundle>;
|
|
208
|
+
importBundle(bundle: MemoryBundle): Promise<MemoryImportResult>;
|
|
209
|
+
vectorStats(): Promise<MemoryVectorStats>;
|
|
210
|
+
doctor(): Promise<MemoryDoctorReport>;
|
|
211
|
+
/**
|
|
212
|
+
* Refresh the cached recall snapshot ASYNCHRONOUSLY over the CURRENT route (wire
|
|
213
|
+
* when adopted, local otherwise). Call this from an async pre-turn hook so a
|
|
214
|
+
* SYNCHRONOUS prompt builder can read the result via {@link recallSnapshot}
|
|
215
|
+
* without awaiting the wire. Runs the honest recall search (recall-injection
|
|
216
|
+
* contract ON by default), stamps the capture time and mode, and stores it.
|
|
217
|
+
*/
|
|
218
|
+
refreshRecallSnapshot(filter?: MemorySearchFilter, options?: MemoryRecallRefreshOptions): Promise<MemoryRecallSnapshot>;
|
|
219
|
+
/**
|
|
220
|
+
* Read the last recall snapshot SYNCHRONOUSLY (for a sync prompt builder). Never
|
|
221
|
+
* opens the file and never awaits: it returns whatever the last async refresh
|
|
222
|
+
* captured, with a freshly-computed age, a `stale` flag, and an HONEST `note`. If
|
|
223
|
+
* no refresh has happened yet it returns an EMPTY snapshot whose note says exactly
|
|
224
|
+
* that — never a silent empty that reads as "nothing was ever stored."
|
|
225
|
+
*/
|
|
226
|
+
recallSnapshot(now?: number): MemoryRecallSnapshot;
|
|
227
|
+
/**
|
|
228
|
+
* The single choke point that realizes the one-writer invariant: in client mode
|
|
229
|
+
* EVERY op resolves through the transport and the local store is never reached.
|
|
230
|
+
*/
|
|
231
|
+
private route;
|
|
232
|
+
/**
|
|
233
|
+
* Route an extended verb. Local mode → the local store. Client mode → the
|
|
234
|
+
* transport's verb if it implements it, otherwise an HONEST rejection stating the
|
|
235
|
+
* adopted daemon does not support it (never a silent local-file read, which would
|
|
236
|
+
* break the single-writer invariant and misreport which store answered).
|
|
237
|
+
*/
|
|
238
|
+
private routeExtended;
|
|
239
|
+
}
|
|
240
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../src/platform/runtime/memory-spine/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* client.ts — the SDK memory-spine surface client (host-vs-client access mode).
|
|
3
|
+
*
|
|
4
|
+
* The daemon-owned memory service makes the daemon the SINGLE WRITER of its
|
|
5
|
+
* canonical sql.js store. sql.js has no row locking and rewrites the whole file on
|
|
6
|
+
* every save(), so two live processes writing the same file clobber each other —
|
|
7
|
+
* a whole-file lost update that would DELETE memory. One process must own the
|
|
8
|
+
* store; every other surface reaches it over the wire.
|
|
9
|
+
*
|
|
10
|
+
* This client is the surface-side switch that realizes that invariant, mirroring
|
|
11
|
+
* the session-spine host-vs-client pattern:
|
|
12
|
+
*
|
|
13
|
+
* - HOST / OFFLINE-EMBEDDED mode (transport NOT attached): the surface IS the only
|
|
14
|
+
* process touching its own store file, so it reads/writes the LOCAL embedded
|
|
15
|
+
* store directly. This is the offline fallback the agent and TUI keep — a daemon
|
|
16
|
+
* is not required for them to work.
|
|
17
|
+
* - CLIENT-OF-ADOPTED-DAEMON mode (transport attached): the daemon owns the store;
|
|
18
|
+
* the surface routes EVERY memory op through the injected wire transport and
|
|
19
|
+
* NEVER opens the file. Enforced structurally here — the active branch only ever
|
|
20
|
+
* touches `this.transport`, never `this.local`.
|
|
21
|
+
*
|
|
22
|
+
* FULL DETACH (SDK 1.2.0). The 1.1.0 wire family covered five verbs (add,
|
|
23
|
+
* honestSearch, get, updateReview, delete). That was enough for a surface to store
|
|
24
|
+
* and recall a fact over the wire, but NOT enough to fully detach every consumer
|
|
25
|
+
* from the store file: the agent's `list`/`update`/semantic-search paths and the
|
|
26
|
+
* TUI's `/recall` browse/link/queue/export paths still fell back to a local file.
|
|
27
|
+
* This client now exposes the FULL read/write catalog those consumers need
|
|
28
|
+
* (see MemoryExtendedAccess), so a wire client never opens the file for ANY of them.
|
|
29
|
+
*
|
|
30
|
+
* ONE-WRITER ENFORCEMENT RULING. The platform's convention (see canonical-memory.ts
|
|
31
|
+
* and the session spine) is honest sequential/owned access plus stated posture, NOT
|
|
32
|
+
* an OS advisory lock — sql.js exposes no lock and a cross-process flock would be a
|
|
33
|
+
* new, unenforceable-on-every-OS mechanism the rest of the store does not rely on.
|
|
34
|
+
* So the invariant is enforced two ways, both honest: (1) mode exclusivity — a
|
|
35
|
+
* client in wire mode provably cannot reach the local file because the code routes
|
|
36
|
+
* exclusively to the transport; (2) a documented single-writer contract for the
|
|
37
|
+
* embedded case — the daemon host and an offline surface are each the sole process
|
|
38
|
+
* for their own file. `mode()` reports the current posture so a surface can surface
|
|
39
|
+
* it rather than guess.
|
|
40
|
+
*
|
|
41
|
+
* HONEST FAILURE. Unlike the fire-and-forget session mirror, memory reads/writes
|
|
42
|
+
* return data, so this client is request/response. In client mode a transport
|
|
43
|
+
* failure is SURFACED to the caller (the promise rejects); it is deliberately NOT
|
|
44
|
+
* silently served from the local store — a wire client must not open the
|
|
45
|
+
* daemon-owned file, and returning a divergent local copy as if it were canonical
|
|
46
|
+
* would be the exact dishonest-recall failure this whole design exists to prevent.
|
|
47
|
+
* A sustained daemon loss is handled by `deactivate()`, which returns the surface
|
|
48
|
+
* to owned-local mode explicitly.
|
|
49
|
+
*
|
|
50
|
+
* VERSION TOLERANCE. The five CORE verbs are required of every transport. The
|
|
51
|
+
* EXTENDED verbs are OPTIONAL on the transport (`MemoryTransport`) so a surface
|
|
52
|
+
* pinned to an older SDK/daemon pair that predates a verb still satisfies the type.
|
|
53
|
+
* When a client in wire mode calls an extended verb its adopted daemon does not
|
|
54
|
+
* implement, the call REJECTS with a stated reason — it never silently reaches into
|
|
55
|
+
* the local file, which would break the one-writer invariant and lie about which
|
|
56
|
+
* store answered.
|
|
57
|
+
*/
|
|
58
|
+
import { logger } from '../../utils/logger.js';
|
|
59
|
+
import { buildRecallSnapshot, emptyRecallSnapshot, DEFAULT_RECALL_SNAPSHOT_STALE_AFTER_MS, } from './recall-snapshot.js';
|
|
60
|
+
/** Wrap a local embedded store (e.g. a MemoryRegistry) as a full MemoryAccess. */
|
|
61
|
+
export function createLocalMemoryAccess(store) {
|
|
62
|
+
return {
|
|
63
|
+
add: (opts) => Promise.resolve(store.add(opts)),
|
|
64
|
+
honestSearch: (filter, options) => Promise.resolve(store.honestSearch(filter, options)),
|
|
65
|
+
get: (id) => Promise.resolve(store.get(id)),
|
|
66
|
+
updateReview: (id, patch) => Promise.resolve(store.review(id, patch)),
|
|
67
|
+
delete: (id) => Promise.resolve(store.delete(id)),
|
|
68
|
+
list: (filter) => Promise.resolve(store.search(filter ?? {})),
|
|
69
|
+
searchSemantic: (filter) => Promise.resolve(store.searchSemantic(filter ?? {})),
|
|
70
|
+
update: (id, patch) => Promise.resolve(store.update(id, patch)),
|
|
71
|
+
link: (fromId, toId, relation) => Promise.resolve(store.link(fromId, toId, relation)),
|
|
72
|
+
linksFor: (id) => Promise.resolve(store.linksFor(id)),
|
|
73
|
+
reviewQueue: (limit, scope) => Promise.resolve(store.reviewQueue(limit, scope)),
|
|
74
|
+
exportBundle: (filter) => Promise.resolve(store.exportBundle(filter ?? {})),
|
|
75
|
+
importBundle: (bundle) => Promise.resolve(store.importBundle(bundle)),
|
|
76
|
+
vectorStats: () => Promise.resolve(store.vectorStats()),
|
|
77
|
+
doctor: () => Promise.resolve(store.doctor()),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Routes memory access to the LOCAL embedded store or, when a daemon has been
|
|
82
|
+
* adopted, THROUGH the wire — never both. Implements {@link MemoryAccess} so a
|
|
83
|
+
* caller uses one object regardless of mode.
|
|
84
|
+
*/
|
|
85
|
+
export class MemorySpineClient {
|
|
86
|
+
local;
|
|
87
|
+
transport;
|
|
88
|
+
log;
|
|
89
|
+
staleAfterMs;
|
|
90
|
+
/** Last recall snapshot captured by refreshRecallSnapshot(); null until first refresh. */
|
|
91
|
+
snapshot = null;
|
|
92
|
+
constructor(options) {
|
|
93
|
+
this.local = options.local;
|
|
94
|
+
this.transport = options.transport ?? null;
|
|
95
|
+
this.log = options.log ?? logger;
|
|
96
|
+
this.staleAfterMs = options.recallSnapshotStaleAfterMs ?? DEFAULT_RECALL_SNAPSHOT_STALE_AFTER_MS;
|
|
97
|
+
}
|
|
98
|
+
/** The current posture: 'client' when routing over the wire, 'local' otherwise. */
|
|
99
|
+
mode() {
|
|
100
|
+
return this.transport ? 'client' : 'local';
|
|
101
|
+
}
|
|
102
|
+
/** Whether a wire transport is attached (client-of-adopted-daemon mode). */
|
|
103
|
+
get active() {
|
|
104
|
+
return this.transport !== null;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Adopt a daemon: route every memory op through the wire from now on. The local
|
|
108
|
+
* store is left untouched for the lifetime of client mode — the daemon is the
|
|
109
|
+
* single writer.
|
|
110
|
+
*/
|
|
111
|
+
activate(transport) {
|
|
112
|
+
this.transport = transport;
|
|
113
|
+
this.log.info('memory spine activated — routing memory through the adopted external daemon (single writer)', {});
|
|
114
|
+
}
|
|
115
|
+
/** Release the daemon (mode lost / daemon stopped): return to owned-local access. */
|
|
116
|
+
deactivate(reason) {
|
|
117
|
+
if (this.transport === null)
|
|
118
|
+
return;
|
|
119
|
+
this.transport = null;
|
|
120
|
+
this.log.info('memory spine deactivated — reverting to owned-local memory access', { reason });
|
|
121
|
+
}
|
|
122
|
+
// ── Core verbs (routed local-or-wire) ─────────────────────────────────────────
|
|
123
|
+
add(opts) {
|
|
124
|
+
return this.route().add(opts);
|
|
125
|
+
}
|
|
126
|
+
honestSearch(filter, options) {
|
|
127
|
+
return this.route().honestSearch(filter, options);
|
|
128
|
+
}
|
|
129
|
+
get(id) {
|
|
130
|
+
return this.route().get(id);
|
|
131
|
+
}
|
|
132
|
+
updateReview(id, patch) {
|
|
133
|
+
return this.route().updateReview(id, patch);
|
|
134
|
+
}
|
|
135
|
+
delete(id) {
|
|
136
|
+
return this.route().delete(id);
|
|
137
|
+
}
|
|
138
|
+
// ── Extended verbs (routed local-or-wire; honest reject if the daemon lacks one) ─
|
|
139
|
+
list(filter) {
|
|
140
|
+
return this.routeExtended('list', (a) => a.list(filter), (t) => t.list?.(filter));
|
|
141
|
+
}
|
|
142
|
+
searchSemantic(filter) {
|
|
143
|
+
return this.routeExtended('searchSemantic', (a) => a.searchSemantic(filter), (t) => t.searchSemantic?.(filter));
|
|
144
|
+
}
|
|
145
|
+
update(id, patch) {
|
|
146
|
+
return this.routeExtended('update', (a) => a.update(id, patch), (t) => t.update?.(id, patch));
|
|
147
|
+
}
|
|
148
|
+
link(fromId, toId, relation) {
|
|
149
|
+
return this.routeExtended('link', (a) => a.link(fromId, toId, relation), (t) => t.link?.(fromId, toId, relation));
|
|
150
|
+
}
|
|
151
|
+
linksFor(id) {
|
|
152
|
+
return this.routeExtended('linksFor', (a) => a.linksFor(id), (t) => t.linksFor?.(id));
|
|
153
|
+
}
|
|
154
|
+
reviewQueue(limit, scope) {
|
|
155
|
+
return this.routeExtended('reviewQueue', (a) => a.reviewQueue(limit, scope), (t) => t.reviewQueue?.(limit, scope));
|
|
156
|
+
}
|
|
157
|
+
exportBundle(filter) {
|
|
158
|
+
return this.routeExtended('exportBundle', (a) => a.exportBundle(filter), (t) => t.exportBundle?.(filter));
|
|
159
|
+
}
|
|
160
|
+
importBundle(bundle) {
|
|
161
|
+
return this.routeExtended('importBundle', (a) => a.importBundle(bundle), (t) => t.importBundle?.(bundle));
|
|
162
|
+
}
|
|
163
|
+
vectorStats() {
|
|
164
|
+
return this.routeExtended('vectorStats', (a) => a.vectorStats(), (t) => t.vectorStats?.());
|
|
165
|
+
}
|
|
166
|
+
doctor() {
|
|
167
|
+
return this.routeExtended('doctor', (a) => a.doctor(), (t) => t.doctor?.());
|
|
168
|
+
}
|
|
169
|
+
// ── The sync-recall seam ──────────────────────────────────────────────────────
|
|
170
|
+
/**
|
|
171
|
+
* Refresh the cached recall snapshot ASYNCHRONOUSLY over the CURRENT route (wire
|
|
172
|
+
* when adopted, local otherwise). Call this from an async pre-turn hook so a
|
|
173
|
+
* SYNCHRONOUS prompt builder can read the result via {@link recallSnapshot}
|
|
174
|
+
* without awaiting the wire. Runs the honest recall search (recall-injection
|
|
175
|
+
* contract ON by default), stamps the capture time and mode, and stores it.
|
|
176
|
+
*/
|
|
177
|
+
async refreshRecallSnapshot(filter = {}, options = {}) {
|
|
178
|
+
const recall = options.recall ?? true;
|
|
179
|
+
const result = await this.route().honestSearch(filter, { recall });
|
|
180
|
+
this.snapshot = buildRecallSnapshot(result, this.mode(), Date.now(), this.staleAfterMs);
|
|
181
|
+
return this.snapshot;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Read the last recall snapshot SYNCHRONOUSLY (for a sync prompt builder). Never
|
|
185
|
+
* opens the file and never awaits: it returns whatever the last async refresh
|
|
186
|
+
* captured, with a freshly-computed age, a `stale` flag, and an HONEST `note`. If
|
|
187
|
+
* no refresh has happened yet it returns an EMPTY snapshot whose note says exactly
|
|
188
|
+
* that — never a silent empty that reads as "nothing was ever stored."
|
|
189
|
+
*/
|
|
190
|
+
recallSnapshot(now = Date.now()) {
|
|
191
|
+
const cached = this.snapshot;
|
|
192
|
+
if (cached === null || cached.search === null || cached.capturedAt === null)
|
|
193
|
+
return emptyRecallSnapshot(this.mode());
|
|
194
|
+
return buildRecallSnapshot(cached.search, cached.mode, cached.capturedAt, this.staleAfterMs, now);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* The single choke point that realizes the one-writer invariant: in client mode
|
|
198
|
+
* EVERY op resolves through the transport and the local store is never reached.
|
|
199
|
+
*/
|
|
200
|
+
route() {
|
|
201
|
+
return this.transport ?? this.local;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Route an extended verb. Local mode → the local store. Client mode → the
|
|
205
|
+
* transport's verb if it implements it, otherwise an HONEST rejection stating the
|
|
206
|
+
* adopted daemon does not support it (never a silent local-file read, which would
|
|
207
|
+
* break the single-writer invariant and misreport which store answered).
|
|
208
|
+
*/
|
|
209
|
+
routeExtended(verb, local, wire) {
|
|
210
|
+
if (this.transport === null)
|
|
211
|
+
return local(this.local);
|
|
212
|
+
const call = wire(this.transport);
|
|
213
|
+
if (call === undefined) {
|
|
214
|
+
return Promise.reject(new Error(`memory spine: the adopted daemon does not support the '${verb}' memory verb over the wire — `
|
|
215
|
+
+ 'upgrade the daemon to a build that serves it, or run this surface offline (no daemon adopted). '
|
|
216
|
+
+ 'A wire client will not read its own local store for this op, because that would break the '
|
|
217
|
+
+ 'single-writer invariant and report a divergent local copy as if it were the canonical store.'));
|
|
218
|
+
}
|
|
219
|
+
return call;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @pellux/goodvibes-sdk/platform/runtime/memory-spine
|
|
3
|
+
*
|
|
4
|
+
* The surface-side host-vs-client switch for the daemon-owned single-writer memory
|
|
5
|
+
* service. A daemon host (and any offline/embedded surface) uses the LOCAL store
|
|
6
|
+
* directly; a surface that has adopted a compatible daemon routes memory THROUGH
|
|
7
|
+
* the wire and never opens the store file. Mirrors the session-spine pattern; the
|
|
8
|
+
* offline fallback stays, so the agent and TUI keep working with no daemon running.
|
|
9
|
+
*
|
|
10
|
+
* As of 1.2.0 the client exposes the FULL read/write catalog (see
|
|
11
|
+
* MemoryExtendedAccess) so a wire client fully detaches from the file, plus a
|
|
12
|
+
* freshness-stamped recall snapshot (recall-snapshot.ts) for the synchronous
|
|
13
|
+
* per-turn prompt-injection seam.
|
|
14
|
+
*/
|
|
15
|
+
export { MemorySpineClient, createLocalMemoryAccess, type MemoryAccess, type MemoryCoreAccess, type MemoryExtendedAccess, type MemoryAccessMode, type MemoryTransport, type MemoryUpdatePatch, type LocalMemoryStore, type MemorySpineClientOptions, type MemoryRecallSnapshot, type MemoryRecallRefreshOptions, } from './client.js';
|
|
16
|
+
export { buildRecallSnapshot, emptyRecallSnapshot, DEFAULT_RECALL_SNAPSHOT_STALE_AFTER_MS, } from './recall-snapshot.js';
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/platform/runtime/memory-spine/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,iBAAiB,EACjB,uBAAuB,EACvB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,GAChC,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,sCAAsC,GACvC,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @pellux/goodvibes-sdk/platform/runtime/memory-spine
|
|
3
|
+
*
|
|
4
|
+
* The surface-side host-vs-client switch for the daemon-owned single-writer memory
|
|
5
|
+
* service. A daemon host (and any offline/embedded surface) uses the LOCAL store
|
|
6
|
+
* directly; a surface that has adopted a compatible daemon routes memory THROUGH
|
|
7
|
+
* the wire and never opens the store file. Mirrors the session-spine pattern; the
|
|
8
|
+
* offline fallback stays, so the agent and TUI keep working with no daemon running.
|
|
9
|
+
*
|
|
10
|
+
* As of 1.2.0 the client exposes the FULL read/write catalog (see
|
|
11
|
+
* MemoryExtendedAccess) so a wire client fully detaches from the file, plus a
|
|
12
|
+
* freshness-stamped recall snapshot (recall-snapshot.ts) for the synchronous
|
|
13
|
+
* per-turn prompt-injection seam.
|
|
14
|
+
*/
|
|
15
|
+
export { MemorySpineClient, createLocalMemoryAccess, } from './client.js';
|
|
16
|
+
export { buildRecallSnapshot, emptyRecallSnapshot, DEFAULT_RECALL_SNAPSHOT_STALE_AFTER_MS, } from './recall-snapshot.js';
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* recall-snapshot.ts — the sync-recall seam for the memory spine.
|
|
3
|
+
*
|
|
4
|
+
* THE PROBLEM. Per-turn memory recall wants to inject the recall-eligible records
|
|
5
|
+
* into the system prompt. But the prompt builder is SYNCHRONOUS
|
|
6
|
+
* (`Orchestrator.getSystemPrompt()` returns a string, not a promise), while a wire
|
|
7
|
+
* client's memory reads are ASYNCHRONOUS (a fetch to the adopted daemon). A sync
|
|
8
|
+
* function cannot await a wire read, so it cannot pull fresh memory over the wire
|
|
9
|
+
* inline.
|
|
10
|
+
*
|
|
11
|
+
* THE DESIGN (cached snapshot, freshness-stamped, honest staleness note). Rather
|
|
12
|
+
* than make the whole prompt path async (a large, cross-consumer refactor) or open
|
|
13
|
+
* the store file from a wire client (which would break the single-writer invariant),
|
|
14
|
+
* the spine maintains a CACHED recall snapshot:
|
|
15
|
+
*
|
|
16
|
+
* 1. an ASYNC pre-turn hook calls `MemorySpineClient.refreshRecallSnapshot()` —
|
|
17
|
+
* this awaits the wire (or local) honest recall search and stamps the result
|
|
18
|
+
* with a capture time and the access mode it came from;
|
|
19
|
+
* 2. the SYNC prompt builder calls `MemorySpineClient.recallSnapshot()` — this
|
|
20
|
+
* returns the cached records immediately, with a freshly-computed age, a
|
|
21
|
+
* `stale` flag, and a human-readable `note`.
|
|
22
|
+
*
|
|
23
|
+
* HONESTY. The snapshot never lies about its own freshness. If it has never been
|
|
24
|
+
* refreshed, it returns an EMPTY snapshot whose note says exactly that — never a
|
|
25
|
+
* silent empty that a reader would misread as "nothing was ever stored". If the last
|
|
26
|
+
* refresh is older than the staleness window, `stale` is true and the note says so,
|
|
27
|
+
* so an injector can choose to note the staleness in the prompt rather than present
|
|
28
|
+
* possibly-old memory as live. The `mode` records WHERE the snapshot was captured
|
|
29
|
+
* (local host store vs the adopted daemon over the wire), so the note never implies
|
|
30
|
+
* a wire read happened when it did not.
|
|
31
|
+
*/
|
|
32
|
+
import type { MemoryRecord } from '../../state/memory-store.js';
|
|
33
|
+
import type { HonestMemorySearchResult } from '../../state/memory-recall-contract.js';
|
|
34
|
+
import type { MemoryAccessMode } from './client.js';
|
|
35
|
+
/** Default freshness window: a snapshot older than this reports `stale: true`. */
|
|
36
|
+
export declare const DEFAULT_RECALL_SNAPSHOT_STALE_AFTER_MS = 30000;
|
|
37
|
+
export interface MemoryRecallRefreshOptions {
|
|
38
|
+
/**
|
|
39
|
+
* Apply the recall-injection contract when refreshing (exclude flagged records and
|
|
40
|
+
* drop sub-floor records, each exclusion counted). Defaults to TRUE — the snapshot
|
|
41
|
+
* exists for prompt injection, which must honor the recall floor. Pass false to
|
|
42
|
+
* capture an unfiltered browse set instead.
|
|
43
|
+
*/
|
|
44
|
+
readonly recall?: boolean | undefined;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* A freshness-stamped, synchronously-readable recall result. `records` is what a
|
|
48
|
+
* sync prompt builder injects; the rest is the honest receipt.
|
|
49
|
+
*/
|
|
50
|
+
export interface MemoryRecallSnapshot {
|
|
51
|
+
/** The recall-eligible records captured by the last refresh (empty until first refresh). */
|
|
52
|
+
readonly records: readonly MemoryRecord[];
|
|
53
|
+
/** The full honest search envelope the records came from (null until first refresh). */
|
|
54
|
+
readonly search: HonestMemorySearchResult | null;
|
|
55
|
+
/** When the snapshot was captured (epoch ms), or null if never refreshed. */
|
|
56
|
+
readonly capturedAt: number | null;
|
|
57
|
+
/** Age of the snapshot in ms at read time, or null if never refreshed. */
|
|
58
|
+
readonly ageMs: number | null;
|
|
59
|
+
/** True when the snapshot is older than the staleness window (or never captured). */
|
|
60
|
+
readonly stale: boolean;
|
|
61
|
+
/** Where the snapshot was captured from — 'client' (over the wire) or 'local'. */
|
|
62
|
+
readonly mode: MemoryAccessMode;
|
|
63
|
+
/** An honest, human-readable freshness/degradation note — never silent. */
|
|
64
|
+
readonly note: string;
|
|
65
|
+
}
|
|
66
|
+
/** The snapshot returned before any refresh has happened — empty, and it says so. */
|
|
67
|
+
export declare function emptyRecallSnapshot(mode: MemoryAccessMode): MemoryRecallSnapshot;
|
|
68
|
+
/**
|
|
69
|
+
* Build a snapshot from an honest search envelope captured at `capturedAt`, with age
|
|
70
|
+
* and staleness computed against `now`. The `note` states the source, the age, and
|
|
71
|
+
* — when stale — that the records may be out of date.
|
|
72
|
+
*/
|
|
73
|
+
export declare function buildRecallSnapshot(search: HonestMemorySearchResult, mode: MemoryAccessMode, capturedAt: number, staleAfterMs: number, now?: number): MemoryRecallSnapshot;
|
|
74
|
+
//# sourceMappingURL=recall-snapshot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recall-snapshot.d.ts","sourceRoot":"","sources":["../../../../src/platform/runtime/memory-spine/recall-snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AACtF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,kFAAkF;AAClF,eAAO,MAAM,sCAAsC,QAAS,CAAC;AAE7D,MAAM,WAAW,0BAA0B;IACzC;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACvC;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,4FAA4F;IAC5F,QAAQ,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;IAC1C,wFAAwF;IACxF,QAAQ,CAAC,MAAM,EAAE,wBAAwB,GAAG,IAAI,CAAC;IACjD,6EAA6E;IAC7E,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,0EAA0E;IAC1E,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,qFAAqF;IACrF,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,kFAAkF;IAClF,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,2EAA2E;IAC3E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAID,qFAAqF;AACrF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,gBAAgB,GAAG,oBAAoB,CAWhF;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,wBAAwB,EAChC,IAAI,EAAE,gBAAgB,EACtB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,GAAG,GAAE,MAAmB,GACvB,oBAAoB,CAqBtB"}
|