@moltzap/client 2026.811.0 → 2026.902.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/LICENSE +202 -21
- package/NOTICE +19 -0
- package/README.md +50 -0
- package/bin/moltzapd +9 -0
- package/dist/client-runtime.d.ts +10 -0
- package/dist/client-runtime.d.ts.map +1 -0
- package/dist/client-runtime.js +218 -0
- package/dist/client-runtime.js.map +1 -0
- package/dist/contract.d.ts +338 -0
- package/dist/contract.d.ts.map +1 -0
- package/dist/contract.js +213 -0
- package/dist/contract.js.map +1 -0
- package/dist/contract.types-check.d.ts +99 -0
- package/dist/contract.types-check.d.ts.map +1 -0
- package/dist/contract.types-check.js +7 -0
- package/dist/contract.types-check.js.map +1 -0
- package/dist/daemon/configuration.d.ts +46 -0
- package/dist/daemon/configuration.d.ts.map +1 -0
- package/dist/daemon/configuration.js +69 -0
- package/dist/daemon/configuration.js.map +1 -0
- package/dist/daemon/management.d.ts +23 -0
- package/dist/daemon/management.d.ts.map +1 -0
- package/dist/daemon/management.js +489 -0
- package/dist/daemon/management.js.map +1 -0
- package/dist/daemon/registration.d.ts +72 -0
- package/dist/daemon/registration.d.ts.map +1 -0
- package/dist/daemon/registration.js +109 -0
- package/dist/daemon/registration.js.map +1 -0
- package/dist/daemon/runtime/activation.d.ts +95 -0
- package/dist/daemon/runtime/activation.d.ts.map +1 -0
- package/dist/daemon/runtime/activation.js +99 -0
- package/dist/daemon/runtime/activation.js.map +1 -0
- package/dist/daemon/runtime/controller.d.ts +34 -0
- package/dist/daemon/runtime/controller.d.ts.map +1 -0
- package/dist/daemon/runtime/controller.js +106 -0
- package/dist/daemon/runtime/controller.js.map +1 -0
- package/dist/daemon/runtime/history-export.d.ts +23 -0
- package/dist/daemon/runtime/history-export.d.ts.map +1 -0
- package/dist/daemon/runtime/history-export.js +47 -0
- package/dist/daemon/runtime/history-export.js.map +1 -0
- package/dist/daemon/runtime/index.d.ts +24 -0
- package/dist/daemon/runtime/index.d.ts.map +1 -0
- package/dist/daemon/runtime/index.js +65 -0
- package/dist/daemon/runtime/index.js.map +1 -0
- package/dist/daemon/runtime/protocol.d.ts +63 -0
- package/dist/daemon/runtime/protocol.d.ts.map +1 -0
- package/dist/daemon/runtime/protocol.js +133 -0
- package/dist/daemon/runtime/protocol.js.map +1 -0
- package/dist/endpoint/addressing/index.d.ts +39 -0
- package/dist/endpoint/addressing/index.d.ts.map +1 -0
- package/dist/endpoint/addressing/index.js +114 -0
- package/dist/endpoint/addressing/index.js.map +1 -0
- package/dist/endpoint/engine-dissemination.d.ts +11 -0
- package/dist/endpoint/engine-dissemination.d.ts.map +1 -0
- package/dist/endpoint/engine-dissemination.js +71 -0
- package/dist/endpoint/engine-dissemination.js.map +1 -0
- package/dist/endpoint/engine-durability.d.ts +69 -0
- package/dist/endpoint/engine-durability.d.ts.map +1 -0
- package/dist/endpoint/engine-durability.js +210 -0
- package/dist/endpoint/engine-durability.js.map +1 -0
- package/dist/endpoint/engine-send.d.ts +50 -0
- package/dist/endpoint/engine-send.d.ts.map +1 -0
- package/dist/endpoint/engine-send.js +422 -0
- package/dist/endpoint/engine-send.js.map +1 -0
- package/dist/endpoint/engine-types.d.ts +132 -0
- package/dist/endpoint/engine-types.d.ts.map +1 -0
- package/dist/endpoint/engine-types.js +13 -0
- package/dist/endpoint/engine-types.js.map +1 -0
- package/dist/endpoint/engine.d.ts +14 -0
- package/dist/endpoint/engine.d.ts.map +1 -0
- package/dist/endpoint/engine.js +280 -0
- package/dist/endpoint/engine.js.map +1 -0
- package/dist/endpoint/protocol/evidence.d.ts +37 -0
- package/dist/endpoint/protocol/evidence.d.ts.map +1 -0
- package/dist/endpoint/protocol/evidence.js +80 -0
- package/dist/endpoint/protocol/evidence.js.map +1 -0
- package/dist/endpoint/protocol/index.d.ts +26 -0
- package/dist/endpoint/protocol/index.d.ts.map +1 -0
- package/dist/endpoint/protocol/index.js +543 -0
- package/dist/endpoint/protocol/index.js.map +1 -0
- package/dist/endpoint/recovery/barrier.d.ts +23 -0
- package/dist/endpoint/recovery/barrier.d.ts.map +1 -0
- package/dist/endpoint/recovery/barrier.js +47 -0
- package/dist/endpoint/recovery/barrier.js.map +1 -0
- package/dist/endpoint/recovery/index.d.ts +29 -0
- package/dist/endpoint/recovery/index.d.ts.map +1 -0
- package/dist/endpoint/recovery/index.js +489 -0
- package/dist/endpoint/recovery/index.js.map +1 -0
- package/dist/endpoint/recovery/reanchor/empty.d.ts +22 -0
- package/dist/endpoint/recovery/reanchor/empty.d.ts.map +1 -0
- package/dist/endpoint/recovery/reanchor/empty.js +163 -0
- package/dist/endpoint/recovery/reanchor/empty.js.map +1 -0
- package/dist/endpoint/recovery/reanchor/index.d.ts +30 -0
- package/dist/endpoint/recovery/reanchor/index.d.ts.map +1 -0
- package/dist/endpoint/recovery/reanchor/index.js +479 -0
- package/dist/endpoint/recovery/reanchor/index.js.map +1 -0
- package/dist/endpoint/recovery/state.d.ts +130 -0
- package/dist/endpoint/recovery/state.d.ts.map +1 -0
- package/dist/endpoint/recovery/state.js +296 -0
- package/dist/endpoint/recovery/state.js.map +1 -0
- package/dist/endpoint/recovery/store-evidence.d.ts +17 -0
- package/dist/endpoint/recovery/store-evidence.d.ts.map +1 -0
- package/dist/endpoint/recovery/store-evidence.js +79 -0
- package/dist/endpoint/recovery/store-evidence.js.map +1 -0
- package/dist/endpoint/recovery/store.d.ts +56 -0
- package/dist/endpoint/recovery/store.d.ts.map +1 -0
- package/dist/endpoint/recovery/store.js +499 -0
- package/dist/endpoint/recovery/store.js.map +1 -0
- package/dist/endpoint/representation-canonical.d.ts +17 -0
- package/dist/endpoint/representation-canonical.d.ts.map +1 -0
- package/dist/endpoint/representation-canonical.js +48 -0
- package/dist/endpoint/representation-canonical.js.map +1 -0
- package/dist/endpoint/representation-codec.d.ts +51 -0
- package/dist/endpoint/representation-codec.d.ts.map +1 -0
- package/dist/endpoint/representation-codec.js +159 -0
- package/dist/endpoint/representation-codec.js.map +1 -0
- package/dist/endpoint/representation-schemas.d.ts +1831 -0
- package/dist/endpoint/representation-schemas.d.ts.map +1 -0
- package/dist/endpoint/representation-schemas.js +195 -0
- package/dist/endpoint/representation-schemas.js.map +1 -0
- package/dist/endpoint/representation-verification.d.ts +79 -0
- package/dist/endpoint/representation-verification.d.ts.map +1 -0
- package/dist/endpoint/representation-verification.js +420 -0
- package/dist/endpoint/representation-verification.js.map +1 -0
- package/dist/endpoint/representation.d.ts +6 -0
- package/dist/endpoint/representation.d.ts.map +1 -0
- package/dist/endpoint/representation.js +8 -0
- package/dist/endpoint/representation.js.map +1 -0
- package/dist/endpoint/router-worker/index.d.ts +16 -0
- package/dist/endpoint/router-worker/index.d.ts.map +1 -0
- package/dist/endpoint/router-worker/index.js +547 -0
- package/dist/endpoint/router-worker/index.js.map +1 -0
- package/dist/endpoint/router-worker/types.d.ts +183 -0
- package/dist/endpoint/router-worker/types.d.ts.map +1 -0
- package/dist/endpoint/router-worker/types.js +31 -0
- package/dist/endpoint/router-worker/types.js.map +1 -0
- package/dist/endpoint/store/anchors.d.ts +83 -0
- package/dist/endpoint/store/anchors.d.ts.map +1 -0
- package/dist/endpoint/store/anchors.js +471 -0
- package/dist/endpoint/store/anchors.js.map +1 -0
- package/dist/endpoint/store/database/index.d.ts +6 -0
- package/dist/endpoint/store/database/index.d.ts.map +1 -0
- package/dist/endpoint/store/database/index.js +6 -0
- package/dist/endpoint/store/database/index.js.map +1 -0
- package/dist/endpoint/store/database/schema.d.ts +44 -0
- package/dist/endpoint/store/database/schema.d.ts.map +1 -0
- package/dist/endpoint/store/database/schema.js +345 -0
- package/dist/endpoint/store/database/schema.js.map +1 -0
- package/dist/endpoint/store/database/values.d.ts +119 -0
- package/dist/endpoint/store/database/values.d.ts.map +1 -0
- package/dist/endpoint/store/database/values.js +194 -0
- package/dist/endpoint/store/database/values.js.map +1 -0
- package/dist/endpoint/store/deliveries.d.ts +38 -0
- package/dist/endpoint/store/deliveries.d.ts.map +1 -0
- package/dist/endpoint/store/deliveries.js +124 -0
- package/dist/endpoint/store/deliveries.js.map +1 -0
- package/dist/endpoint/store/dissemination.d.ts +27 -0
- package/dist/endpoint/store/dissemination.d.ts.map +1 -0
- package/dist/endpoint/store/dissemination.js +139 -0
- package/dist/endpoint/store/dissemination.js.map +1 -0
- package/dist/endpoint/store/index.d.ts +15 -0
- package/dist/endpoint/store/index.d.ts.map +1 -0
- package/dist/endpoint/store/index.js +76 -0
- package/dist/endpoint/store/index.js.map +1 -0
- package/dist/endpoint/store/management.d.ts +42 -0
- package/dist/endpoint/store/management.d.ts.map +1 -0
- package/dist/endpoint/store/management.js +259 -0
- package/dist/endpoint/store/management.js.map +1 -0
- package/dist/endpoint/store/outbound.d.ts +62 -0
- package/dist/endpoint/store/outbound.d.ts.map +1 -0
- package/dist/endpoint/store/outbound.js +278 -0
- package/dist/endpoint/store/outbound.js.map +1 -0
- package/dist/endpoint/store/records.d.ts +56 -0
- package/dist/endpoint/store/records.d.ts.map +1 -0
- package/dist/endpoint/store/records.js +352 -0
- package/dist/endpoint/store/records.js.map +1 -0
- package/dist/endpoint/store/rows/index.d.ts +138 -0
- package/dist/endpoint/store/rows/index.d.ts.map +1 -0
- package/dist/endpoint/store/rows/index.js +307 -0
- package/dist/endpoint/store/rows/index.js.map +1 -0
- package/dist/endpoint/store/types.d.ts +223 -0
- package/dist/endpoint/store/types.d.ts.map +1 -0
- package/dist/endpoint/store/types.js +15 -0
- package/dist/endpoint/store/types.js.map +1 -0
- package/dist/endpoint/store.d.ts +10 -0
- package/dist/endpoint/store.d.ts.map +1 -0
- package/dist/endpoint/store.js +6 -0
- package/dist/endpoint/store.js.map +1 -0
- package/dist/harness-mcp-contract.d.ts +101 -0
- package/dist/harness-mcp-contract.d.ts.map +1 -0
- package/dist/harness-mcp-contract.js +61 -0
- package/dist/harness-mcp-contract.js.map +1 -0
- package/dist/harness-mcp-http.d.ts +19 -0
- package/dist/harness-mcp-http.d.ts.map +1 -0
- package/dist/{harness-mcp-server.js → harness-mcp-http.js} +43 -71
- package/dist/harness-mcp-http.js.map +1 -0
- package/dist/harness-mcp-subscription.d.ts +12 -7
- package/dist/harness-mcp-subscription.d.ts.map +1 -1
- package/dist/harness-mcp-subscription.js +113 -100
- package/dist/harness-mcp-subscription.js.map +1 -1
- package/dist/harness-mcp-wire.d.ts +26 -19
- package/dist/harness-mcp-wire.d.ts.map +1 -1
- package/dist/harness-mcp-wire.js +380 -67
- package/dist/harness-mcp-wire.js.map +1 -1
- package/dist/index.d.ts +4 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -8
- package/dist/index.js.map +1 -1
- package/dist/management-runtime.d.ts +217 -0
- package/dist/management-runtime.d.ts.map +1 -0
- package/dist/management-runtime.js +127 -0
- package/dist/management-runtime.js.map +1 -0
- package/dist/server.d.ts +16 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +46 -0
- package/dist/server.js.map +1 -0
- package/dist/server.types-check.d.ts +23 -0
- package/dist/server.types-check.d.ts.map +1 -0
- package/dist/server.types-check.js +7 -0
- package/dist/server.types-check.js.map +1 -0
- package/package.json +45 -47
- package/dist/agent-client.d.ts +0 -5
- package/dist/agent-client.d.ts.map +0 -1
- package/dist/agent-client.js +0 -3
- package/dist/agent-client.js.map +0 -1
- package/dist/auth.d.ts +0 -37
- package/dist/auth.d.ts.map +0 -1
- package/dist/auth.js +0 -79
- package/dist/auth.js.map +0 -1
- package/dist/bounded-map.d.ts +0 -32
- package/dist/bounded-map.d.ts.map +0 -1
- package/dist/bounded-map.js +0 -79
- package/dist/bounded-map.js.map +0 -1
- package/dist/channel-base/format-cross-conv.d.ts +0 -43
- package/dist/channel-base/format-cross-conv.d.ts.map +0 -1
- package/dist/channel-base/format-cross-conv.js +0 -65
- package/dist/channel-base/format-cross-conv.js.map +0 -1
- package/dist/channel-base/format-group-block.d.ts +0 -48
- package/dist/channel-base/format-group-block.d.ts.map +0 -1
- package/dist/channel-base/format-group-block.js +0 -62
- package/dist/channel-base/format-group-block.js.map +0 -1
- package/dist/channel-base/index.d.ts +0 -12
- package/dist/channel-base/index.d.ts.map +0 -1
- package/dist/channel-base/index.js +0 -13
- package/dist/channel-base/index.js.map +0 -1
- package/dist/channel-core-enrichment.d.ts +0 -14
- package/dist/channel-core-enrichment.d.ts.map +0 -1
- package/dist/channel-core-enrichment.js +0 -143
- package/dist/channel-core-enrichment.js.map +0 -1
- package/dist/channel-core-test-support.d.ts +0 -75
- package/dist/channel-core-test-support.d.ts.map +0 -1
- package/dist/channel-core-test-support.js +0 -74
- package/dist/channel-core-test-support.js.map +0 -1
- package/dist/channel-core.d.ts +0 -304
- package/dist/channel-core.d.ts.map +0 -1
- package/dist/channel-core.js +0 -363
- package/dist/channel-core.js.map +0 -1
- package/dist/cli/adapters.d.ts +0 -21
- package/dist/cli/adapters.d.ts.map +0 -1
- package/dist/cli/adapters.js +0 -111
- package/dist/cli/adapters.js.map +0 -1
- package/dist/cli/commands/agents.d.ts +0 -11
- package/dist/cli/commands/agents.d.ts.map +0 -1
- package/dist/cli/commands/agents.js +0 -27
- package/dist/cli/commands/agents.js.map +0 -1
- package/dist/cli/commands/conversations.d.ts +0 -18
- package/dist/cli/commands/conversations.d.ts.map +0 -1
- package/dist/cli/commands/conversations.js +0 -33
- package/dist/cli/commands/conversations.js.map +0 -1
- package/dist/cli/commands/messages.d.ts +0 -41
- package/dist/cli/commands/messages.d.ts.map +0 -1
- package/dist/cli/commands/messages.js +0 -39
- package/dist/cli/commands/messages.js.map +0 -1
- package/dist/cli/commands/register.d.ts +0 -46
- package/dist/cli/commands/register.d.ts.map +0 -1
- package/dist/cli/commands/register.js +0 -103
- package/dist/cli/commands/register.js.map +0 -1
- package/dist/cli/commands/send.d.ts +0 -53
- package/dist/cli/commands/send.d.ts.map +0 -1
- package/dist/cli/commands/send.js +0 -57
- package/dist/cli/commands/send.js.map +0 -1
- package/dist/cli/commands/start.d.ts +0 -34
- package/dist/cli/commands/start.d.ts.map +0 -1
- package/dist/cli/commands/start.js +0 -59
- package/dist/cli/commands/start.js.map +0 -1
- package/dist/cli/commands/status.d.ts +0 -7
- package/dist/cli/commands/status.d.ts.map +0 -1
- package/dist/cli/commands/status.js +0 -16
- package/dist/cli/commands/status.js.map +0 -1
- package/dist/cli/commands/test-transport.d.ts +0 -28
- package/dist/cli/commands/test-transport.d.ts.map +0 -1
- package/dist/cli/commands/test-transport.js +0 -40
- package/dist/cli/commands/test-transport.js.map +0 -1
- package/dist/cli/index.d.ts +0 -3
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/index.js +0 -105
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/output.d.ts +0 -14
- package/dist/cli/output.d.ts.map +0 -1
- package/dist/cli/output.js +0 -19
- package/dist/cli/output.js.map +0 -1
- package/dist/cli/socket-client.d.ts +0 -28
- package/dist/cli/socket-client.d.ts.map +0 -1
- package/dist/cli/socket-client.js +0 -63
- package/dist/cli/socket-client.js.map +0 -1
- package/dist/cli/transport.d.ts +0 -132
- package/dist/cli/transport.d.ts.map +0 -1
- package/dist/cli/transport.js +0 -127
- package/dist/cli/transport.js.map +0 -1
- package/dist/config.d.ts +0 -33
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -45
- package/dist/config.js.map +0 -1
- package/dist/config.test-utils.d.ts +0 -18
- package/dist/config.test-utils.d.ts.map +0 -1
- package/dist/config.test-utils.js +0 -53
- package/dist/config.test-utils.js.map +0 -1
- package/dist/harness/client-runtime.d.ts +0 -24
- package/dist/harness/client-runtime.d.ts.map +0 -1
- package/dist/harness/client-runtime.js +0 -107
- package/dist/harness/client-runtime.js.map +0 -1
- package/dist/harness/index.d.ts +0 -5
- package/dist/harness/index.d.ts.map +0 -1
- package/dist/harness/index.js +0 -5
- package/dist/harness/index.js.map +0 -1
- package/dist/harness/runtime.d.ts +0 -149
- package/dist/harness/runtime.d.ts.map +0 -1
- package/dist/harness/runtime.js +0 -68
- package/dist/harness/runtime.js.map +0 -1
- package/dist/harness-client.d.ts +0 -43
- package/dist/harness-client.d.ts.map +0 -1
- package/dist/harness-client.js +0 -21
- package/dist/harness-client.js.map +0 -1
- package/dist/harness-mcp-server.d.ts +0 -19
- package/dist/harness-mcp-server.d.ts.map +0 -1
- package/dist/harness-mcp-server.js.map +0 -1
- package/dist/local-daemon-rpc.d.ts +0 -1170
- package/dist/local-daemon-rpc.d.ts.map +0 -1
- package/dist/local-daemon-rpc.js +0 -178
- package/dist/local-daemon-rpc.js.map +0 -1
- package/dist/local-history.d.ts +0 -75
- package/dist/local-history.d.ts.map +0 -1
- package/dist/local-history.js +0 -82
- package/dist/local-history.js.map +0 -1
- package/dist/local-paths.d.ts +0 -22
- package/dist/local-paths.d.ts.map +0 -1
- package/dist/local-paths.js +0 -33
- package/dist/local-paths.js.map +0 -1
- package/dist/local-socket-server.d.ts +0 -33
- package/dist/local-socket-server.d.ts.map +0 -1
- package/dist/local-socket-server.js +0 -100
- package/dist/local-socket-server.js.map +0 -1
- package/dist/message-rendering.d.ts +0 -4
- package/dist/message-rendering.d.ts.map +0 -1
- package/dist/message-rendering.js +0 -8
- package/dist/message-rendering.js.map +0 -1
- package/dist/moltzapd.d.ts +0 -38
- package/dist/moltzapd.d.ts.map +0 -1
- package/dist/moltzapd.js +0 -78
- package/dist/moltzapd.js.map +0 -1
- package/dist/notification/__tests__/subscribe-signatures.types-check.d.ts +0 -53
- package/dist/notification/__tests__/subscribe-signatures.types-check.d.ts.map +0 -1
- package/dist/notification/__tests__/subscribe-signatures.types-check.js +0 -29
- package/dist/notification/__tests__/subscribe-signatures.types-check.js.map +0 -1
- package/dist/notification/errors.d.ts +0 -41
- package/dist/notification/errors.d.ts.map +0 -1
- package/dist/notification/errors.js +0 -24
- package/dist/notification/errors.js.map +0 -1
- package/dist/notification/index.d.ts +0 -6
- package/dist/notification/index.d.ts.map +0 -1
- package/dist/notification/index.js +0 -6
- package/dist/notification/index.js.map +0 -1
- package/dist/notification/stream.d.ts +0 -75
- package/dist/notification/stream.d.ts.map +0 -1
- package/dist/notification/stream.js +0 -30
- package/dist/notification/stream.js.map +0 -1
- package/dist/pagination.d.ts +0 -52
- package/dist/pagination.d.ts.map +0 -1
- package/dist/pagination.js +0 -51
- package/dist/pagination.js.map +0 -1
- package/dist/profile.d.ts +0 -104
- package/dist/profile.d.ts.map +0 -1
- package/dist/profile.js +0 -163
- package/dist/profile.js.map +0 -1
- package/dist/refs.d.ts +0 -18
- package/dist/refs.d.ts.map +0 -1
- package/dist/refs.js +0 -18
- package/dist/refs.js.map +0 -1
- package/dist/service-event-trace.d.ts +0 -15
- package/dist/service-event-trace.d.ts.map +0 -1
- package/dist/service-event-trace.js +0 -35
- package/dist/service-event-trace.js.map +0 -1
- package/dist/service-helpers.d.ts +0 -55
- package/dist/service-helpers.d.ts.map +0 -1
- package/dist/service-helpers.js +0 -108
- package/dist/service-helpers.js.map +0 -1
- package/dist/service-local-daemon.d.ts +0 -32
- package/dist/service-local-daemon.d.ts.map +0 -1
- package/dist/service-local-daemon.js +0 -153
- package/dist/service-local-daemon.js.map +0 -1
- package/dist/service.d.ts +0 -299
- package/dist/service.d.ts.map +0 -1
- package/dist/service.js +0 -789
- package/dist/service.js.map +0 -1
- package/dist/test-utils/channel-service-fixture.d.ts +0 -53
- package/dist/test-utils/channel-service-fixture.d.ts.map +0 -1
- package/dist/test-utils/channel-service-fixture.js +0 -178
- package/dist/test-utils/channel-service-fixture.js.map +0 -1
- package/dist/test-utils/fake-service.d.ts +0 -84
- package/dist/test-utils/fake-service.d.ts.map +0 -1
- package/dist/test-utils/fake-service.js +0 -108
- package/dist/test-utils/fake-service.js.map +0 -1
- package/dist/test-utils/harness.d.ts +0 -27
- package/dist/test-utils/harness.d.ts.map +0 -1
- package/dist/test-utils/harness.js +0 -33
- package/dist/test-utils/harness.js.map +0 -1
- package/dist/test-utils/ids.d.ts +0 -21
- package/dist/test-utils/ids.d.ts.map +0 -1
- package/dist/test-utils/ids.js +0 -68
- package/dist/test-utils/ids.js.map +0 -1
- package/dist/test-utils/index.d.ts +0 -54
- package/dist/test-utils/index.d.ts.map +0 -1
- package/dist/test-utils/index.js +0 -65
- package/dist/test-utils/index.js.map +0 -1
- package/dist/test-utils/standalone-provisioning.d.ts +0 -22
- package/dist/test-utils/standalone-provisioning.d.ts.map +0 -1
- package/dist/test-utils/standalone-provisioning.js +0 -17
- package/dist/test-utils/standalone-provisioning.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
package/dist/service.js
DELETED
|
@@ -1,789 +0,0 @@
|
|
|
1
|
-
import { agentId as AgentIdSchema, AgentNotFoundError, agentsList, } from "@moltzap/protocol/identity";
|
|
2
|
-
import { agentConversationCreate, conversationCreatedNotificationDefinition, conversationList, } from "@moltzap/protocol/conversation";
|
|
3
|
-
import { messageReceivedNotificationDefinition, messagesList, messagesSend, } from "@moltzap/protocol/message";
|
|
4
|
-
import { NotConnectedError, isNotificationDeliveryFor, } from "@moltzap/protocol/rpc";
|
|
5
|
-
import { BoundedMap } from "./bounded-map.js";
|
|
6
|
-
import { Deferred, Effect, Exit, HashMap, Option, Ref, Schema, Scope, Stream, } from "effect";
|
|
7
|
-
import { MoltZapAgentClient } from "./agent-client.js";
|
|
8
|
-
import { loadServiceConfig, } from "./config.js";
|
|
9
|
-
import { getOr, snapshot } from "./refs.js";
|
|
10
|
-
import { getMoltZapAgentServiceSocketPath, getMoltZapServiceSocketPath, } from "./local-paths.js";
|
|
11
|
-
import { makeLocalDaemonHandlers } from "./service-local-daemon.js";
|
|
12
|
-
import { startLocalSocketServer, stopLocalSocketServer, } from "./local-socket-server.js";
|
|
13
|
-
import { buildContextEntries, makeContextCandidate, newMessagesForConversation, notificationTraceRecord, } from "./service-helpers.js";
|
|
14
|
-
import { renderPart } from "./message-rendering.js";
|
|
15
|
-
import { formatHistoryMessage, lastReadIdsForSession, } from "./local-history.js";
|
|
16
|
-
import { appendClientEventTrace } from "./service-event-trace.js";
|
|
17
|
-
const CROSS_CONTEXT_TEXT_LIMIT = 120;
|
|
18
|
-
const DEFAULT_MAX_CONTEXT_CONVERSATIONS = 5;
|
|
19
|
-
const DEFAULT_MAX_MESSAGES_PER_CONVERSATION = 3;
|
|
20
|
-
const HISTORY_LOOKUP_CONCURRENCY = 2;
|
|
21
|
-
const AGENT_LOOKUP_PAGE_SIZE = 100;
|
|
22
|
-
const AGENT_LOOKUP_MAX_PAGES = 20;
|
|
23
|
-
const decodeAgentId = Schema.decodeUnknownOption(AgentIdSchema);
|
|
24
|
-
const agentNotFound = (agentName) => new AgentNotFoundError({
|
|
25
|
-
message: `Agent not found: ${agentName}`,
|
|
26
|
-
data: { agentName },
|
|
27
|
-
});
|
|
28
|
-
/**
|
|
29
|
-
* Escape `<`, `>`, `&` so sender content can't escape a `<system-reminder>` block.
|
|
30
|
-
* @param s Value supplied to the operation.
|
|
31
|
-
* @returns The sanitize for system reminder result.
|
|
32
|
-
*/
|
|
33
|
-
export function sanitizeForSystemReminder(s) {
|
|
34
|
-
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Format CrossConversationEntry[] as a `<system-reminder>` block. Adapters
|
|
38
|
-
* that inline context into prompt text (nanoclaw) and `MoltZapService.getContext`
|
|
39
|
-
* share this formatter so sanitization and line shape stay in one place.
|
|
40
|
-
* @param entries Value supplied to the operation.
|
|
41
|
-
* @param opts Value supplied to the operation.
|
|
42
|
-
* @param opts.header Value supplied to the operation.
|
|
43
|
-
* @returns The format cross conversation block result.
|
|
44
|
-
*/
|
|
45
|
-
function formatCrossConversationBlock(entries, opts) {
|
|
46
|
-
if (entries.length === 0) {
|
|
47
|
-
return null;
|
|
48
|
-
}
|
|
49
|
-
const lines = entries.map((e) => {
|
|
50
|
-
const safeSender = sanitizeForSystemReminder(e.senderName);
|
|
51
|
-
const safeText = sanitizeForSystemReminder(e.text.slice(0, CROSS_CONTEXT_TEXT_LIMIT));
|
|
52
|
-
return `@${safeSender} (${e.minutesAgo}m ago): (${e.count} new) "${safeText}"`;
|
|
53
|
-
});
|
|
54
|
-
return [
|
|
55
|
-
"<system-reminder>",
|
|
56
|
-
opts.header,
|
|
57
|
-
...lines,
|
|
58
|
-
"</system-reminder>",
|
|
59
|
-
].join("\n");
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Per-conversation message cap. Older messages are evicted FIFO; the
|
|
63
|
-
* on-disk history remains the source of truth. Sized for typical CLI
|
|
64
|
-
* display windows — `conversations get` shows at most a few hundred.
|
|
65
|
-
*/
|
|
66
|
-
const MAX_MESSAGES_PER_CONV = 1000;
|
|
67
|
-
/**
|
|
68
|
-
* Per-conversation dedup window. `BoundedMap` evicts the oldest message id
|
|
69
|
-
* when a new id arrives at capacity. 1000 × 36 bytes per UUID ≈ 36 KB per
|
|
70
|
-
* conversation, which keeps replay protection negligible at the expected
|
|
71
|
-
* conversation count.
|
|
72
|
-
*/
|
|
73
|
-
const DEDUP_WINDOW_PER_CONV = 1000;
|
|
74
|
-
/**
|
|
75
|
-
* Invoke every handler with `arg`, isolating throws so one bad handler
|
|
76
|
-
* doesn't abort the remaining fanout.
|
|
77
|
-
* @param handlers Value supplied to the operation.
|
|
78
|
-
* @param arg Value supplied to the operation.
|
|
79
|
-
*/
|
|
80
|
-
function fanout(handlers, arg) {
|
|
81
|
-
for (const h of handlers) {
|
|
82
|
-
try {
|
|
83
|
-
h(arg);
|
|
84
|
-
}
|
|
85
|
-
catch (err) {
|
|
86
|
-
Effect.runFork(Effect.logError("notification handler threw", err));
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Stateful MoltZap client that manages connection, conversation tracking,
|
|
92
|
-
* agent name resolution, and cross-conversation context generation.
|
|
93
|
-
*
|
|
94
|
-
* API contract: **every fallible method returns `Effect`.** No `*Async`
|
|
95
|
-
* Promise siblings — async/await consumers run the Effect at the edge
|
|
96
|
-
* with `Effect.runPromise`. Keep this class Effect-only so downstream
|
|
97
|
-
* callers compose failures and cancellation explicitly.
|
|
98
|
-
*/
|
|
99
|
-
export class MoltZapService {
|
|
100
|
-
client = null;
|
|
101
|
-
connectedValue = false;
|
|
102
|
-
shutdownCompletion = null;
|
|
103
|
-
/**
|
|
104
|
-
* Service-owned scope. Opened in `connect()`, owns the
|
|
105
|
-
* `subscribeAll → Stream.runForEach` fan-out fiber. Closed in `close()` so
|
|
106
|
-
* the fiber terminates with the service.
|
|
107
|
-
*
|
|
108
|
-
* Held off the public `connect()` signature so callers do not need to
|
|
109
|
-
* thread a `Scope` requirement.
|
|
110
|
-
*/
|
|
111
|
-
serviceScope = null;
|
|
112
|
-
conversationsRef = Effect.runSync(Ref.make(HashMap.empty()));
|
|
113
|
-
messagesRef = Effect.runSync(Ref.make(HashMap.empty()));
|
|
114
|
-
agentNamesRef = Effect.runSync(Ref.make(HashMap.empty()));
|
|
115
|
-
agentConversationCacheRef = Effect.runSync(Ref.make(HashMap.empty()));
|
|
116
|
-
lastNotifiedRef = Effect.runSync(Ref.make(HashMap.empty()));
|
|
117
|
-
lastReadRef = Effect.runSync(Ref.make(HashMap.empty()));
|
|
118
|
-
/**
|
|
119
|
-
* The branded outer and inner keys keep conversation and message ids from
|
|
120
|
-
* crossing accidentally while each conversation owns its eviction window.
|
|
121
|
-
*/
|
|
122
|
-
seenMessageIds = new Map();
|
|
123
|
-
handlers = {
|
|
124
|
-
message: [],
|
|
125
|
-
rawNotification: [],
|
|
126
|
-
disconnect: [],
|
|
127
|
-
};
|
|
128
|
-
ownAgentIdValue;
|
|
129
|
-
opts;
|
|
130
|
-
constructor(opts) {
|
|
131
|
-
this.opts = opts;
|
|
132
|
-
// The empty HelloOk carries no identity; `ownAgentId` is the client's
|
|
133
|
-
// registered/stored id, available before the handshake.
|
|
134
|
-
this.ownAgentIdValue = opts.agentId;
|
|
135
|
-
}
|
|
136
|
-
static fromConfig(config) {
|
|
137
|
-
return new MoltZapService(config);
|
|
138
|
-
}
|
|
139
|
-
static make(profileName) {
|
|
140
|
-
return loadServiceConfig(profileName).pipe(Effect.map((config) => MoltZapService.fromConfig(config)));
|
|
141
|
-
}
|
|
142
|
-
static startDaemon(profileName) {
|
|
143
|
-
return Effect.gen(function* () {
|
|
144
|
-
const service = yield* MoltZapService.make(profileName);
|
|
145
|
-
yield* service.connect();
|
|
146
|
-
yield* service.startSocketServer();
|
|
147
|
-
return service;
|
|
148
|
-
}).pipe(Effect.withSpan("MoltZapService.startDaemon"));
|
|
149
|
-
}
|
|
150
|
-
get connected() {
|
|
151
|
-
return this.connectedValue;
|
|
152
|
-
}
|
|
153
|
-
get ownAgentId() {
|
|
154
|
-
return this.ownAgentIdValue;
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* Effect-native: compose via `yield*` or bridge at the edge via `Effect.runPromise`.
|
|
158
|
-
* @returns The client result.
|
|
159
|
-
*/
|
|
160
|
-
connect() {
|
|
161
|
-
return Effect.gen(function* () {
|
|
162
|
-
// A new connection never takes ownership while resources from the
|
|
163
|
-
// preceding lifecycle are still closing.
|
|
164
|
-
while (this.shutdownCompletion !== null) {
|
|
165
|
-
const priorShutdown = this.shutdownCompletion;
|
|
166
|
-
yield* Deferred.await(priorShutdown);
|
|
167
|
-
if (this.shutdownCompletion === priorShutdown) {
|
|
168
|
-
this.shutdownCompletion = null;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
const client = new MoltZapAgentClient({
|
|
172
|
-
serverUrl: this.opts.serverUrl,
|
|
173
|
-
agentKey: this.opts.agentKey,
|
|
174
|
-
// The body doesn't branch on close metadata today; the signature is
|
|
175
|
-
// kept explicit so a future disconnect-handler chain can plumb
|
|
176
|
-
// code/reason through.
|
|
177
|
-
onDisconnect: () => {
|
|
178
|
-
this.connectedValue = false;
|
|
179
|
-
fanout(this.handlers.disconnect, undefined);
|
|
180
|
-
},
|
|
181
|
-
});
|
|
182
|
-
this.client = client;
|
|
183
|
-
// `subscribeAll().pipe(Stream.runForEach, …)` is forked into a
|
|
184
|
-
// service-owned scope. The Stream is materialized BEFORE `connect()` so
|
|
185
|
-
// subscriptions are registered with the registry pre-handshake (a
|
|
186
|
-
// pre-connect-legal operation).
|
|
187
|
-
//
|
|
188
|
-
// Stream errors of type `NotConnectedError` are surfaced on the
|
|
189
|
-
// fiber's failure channel only when the client transitions to
|
|
190
|
-
// terminal closed state (close() path); `Effect.catchAll` here
|
|
191
|
-
// would swallow them silently, so we route through `Effect.logError`
|
|
192
|
-
// before the fiber exits.
|
|
193
|
-
const serviceScope = yield* Scope.make();
|
|
194
|
-
this.serviceScope = serviceScope;
|
|
195
|
-
const fanoutEffect = client.subscribeAll().pipe(Stream.runForEach((notification) => Effect.sync(() => {
|
|
196
|
-
this.handleNotification(notification);
|
|
197
|
-
})), Effect.catchAll((cause) => Effect.logWarning("MoltZapService notification fan-out terminated", cause)), Effect.asVoid);
|
|
198
|
-
yield* Effect.forkIn(fanoutEffect, serviceScope);
|
|
199
|
-
const helloOk = yield* client.connect();
|
|
200
|
-
this.connectedValue = true;
|
|
201
|
-
return helloOk;
|
|
202
|
-
}.bind(this));
|
|
203
|
-
}
|
|
204
|
-
/**
|
|
205
|
-
* Returns a lazy teardown effect that resolves after the service's owned
|
|
206
|
-
* transports and notification scope close.
|
|
207
|
-
*
|
|
208
|
-
* @returns Completion of the service-owned cleanup.
|
|
209
|
-
* @internal
|
|
210
|
-
*/
|
|
211
|
-
shutdown() {
|
|
212
|
-
return Effect.suspend(() => this.beginShutdown());
|
|
213
|
-
}
|
|
214
|
-
beginShutdown() {
|
|
215
|
-
if (this.shutdownCompletion !== null) {
|
|
216
|
-
return Deferred.await(this.shutdownCompletion);
|
|
217
|
-
}
|
|
218
|
-
const shutdownCompletion = Effect.runSync(Deferred.make());
|
|
219
|
-
this.shutdownCompletion = shutdownCompletion;
|
|
220
|
-
this.connectedValue = false;
|
|
221
|
-
const stopSocketServer = this.stopSocketServer();
|
|
222
|
-
const scopeToClose = this.serviceScope;
|
|
223
|
-
const clientToClose = this.client;
|
|
224
|
-
this.serviceScope = null;
|
|
225
|
-
this.client = null;
|
|
226
|
-
const closeScope = scopeToClose === null
|
|
227
|
-
? Effect.void
|
|
228
|
-
: Scope.close(scopeToClose, Exit.void);
|
|
229
|
-
const closeClient = clientToClose === null ? Effect.void : clientToClose.close();
|
|
230
|
-
Effect.runSync(Effect.all([
|
|
231
|
-
Ref.set(this.conversationsRef, HashMap.empty()),
|
|
232
|
-
Ref.set(this.messagesRef, HashMap.empty()),
|
|
233
|
-
Ref.set(this.agentNamesRef, HashMap.empty()),
|
|
234
|
-
Ref.set(this.agentConversationCacheRef, HashMap.empty()),
|
|
235
|
-
Ref.set(this.lastNotifiedRef, HashMap.empty()),
|
|
236
|
-
Ref.set(this.lastReadRef, HashMap.empty()),
|
|
237
|
-
]));
|
|
238
|
-
this.seenMessageIds.clear();
|
|
239
|
-
// Handlers are preserved across explicit close()/connect() cycles.
|
|
240
|
-
// MoltZapChannelCore subscribes once in its constructor; clearing handlers
|
|
241
|
-
// here would silently drop inbound dispatch after the next connect.
|
|
242
|
-
return Effect.uninterruptible(Effect.all([stopSocketServer, closeScope.pipe(Effect.zipRight(closeClient))], { concurrency: 2, discard: true }).pipe(Effect.ensuring(Deferred.succeed(shutdownCompletion, undefined).pipe(Effect.asVoid))));
|
|
243
|
-
}
|
|
244
|
-
/**
|
|
245
|
-
* Starts service teardown for callers that use the legacy synchronous
|
|
246
|
-
* lifecycle boundary.
|
|
247
|
-
*/
|
|
248
|
-
close() {
|
|
249
|
-
Effect.runFork(this.beginShutdown());
|
|
250
|
-
}
|
|
251
|
-
// --- Socket Server ---
|
|
252
|
-
socketServerScope = null;
|
|
253
|
-
activeSocketPath = null;
|
|
254
|
-
/** Default socket path for CLI discovery. Per-instance path uses agentId. */
|
|
255
|
-
static SOCKET_PATH = getMoltZapServiceSocketPath();
|
|
256
|
-
/**
|
|
257
|
-
* `agentId` is a server-assigned string. Treat it as untrusted: if a
|
|
258
|
-
* compromised or malicious server returns an id containing `..` or a
|
|
259
|
-
* path separator, a naive `path.join(... , agentId)` escapes `~/.moltzap`.
|
|
260
|
-
* Reject anything that isn't a safe identifier.
|
|
261
|
-
* @param id Value supplied to the operation.
|
|
262
|
-
* @returns The id result.
|
|
263
|
-
*/
|
|
264
|
-
static safeAgentIdSegment(id) {
|
|
265
|
-
return /^[A-Za-z0-9_-]+$/.test(id) ? id : "default";
|
|
266
|
-
}
|
|
267
|
-
/**
|
|
268
|
-
* Per-instance socket path based on connected agentId.
|
|
269
|
-
* @returns The id result.
|
|
270
|
-
*/
|
|
271
|
-
get socketPath() {
|
|
272
|
-
const id = MoltZapService.safeAgentIdSegment(this.ownAgentId ?? "default");
|
|
273
|
-
return getMoltZapAgentServiceSocketPath(id);
|
|
274
|
-
}
|
|
275
|
-
startSocketServer() {
|
|
276
|
-
return Effect.gen(function* () {
|
|
277
|
-
const previous = this.resetSocketServerState();
|
|
278
|
-
yield* stopLocalSocketServer({
|
|
279
|
-
socketScope: previous.socketScope,
|
|
280
|
-
socketPath: previous.sockPath,
|
|
281
|
-
defaultSocketPath: MoltZapService.SOCKET_PATH,
|
|
282
|
-
});
|
|
283
|
-
const running = yield* startLocalSocketServer({
|
|
284
|
-
socketPath: this.socketPath,
|
|
285
|
-
defaultSocketPath: MoltZapService.SOCKET_PATH,
|
|
286
|
-
handlers: this.localDaemonHandlers(),
|
|
287
|
-
});
|
|
288
|
-
this.socketServerScope = running.socketScope;
|
|
289
|
-
this.activeSocketPath = running.socketPath;
|
|
290
|
-
}.bind(this)).pipe(Effect.withSpan("MoltZapService.startSocketServer"));
|
|
291
|
-
}
|
|
292
|
-
resetSocketServerState() {
|
|
293
|
-
const socketScope = this.socketServerScope;
|
|
294
|
-
this.socketServerScope = null;
|
|
295
|
-
const sockPath = this.activeSocketPath ?? this.socketPath;
|
|
296
|
-
this.activeSocketPath = null;
|
|
297
|
-
return { socketScope, sockPath };
|
|
298
|
-
}
|
|
299
|
-
stopSocketServer() {
|
|
300
|
-
const { socketScope, sockPath } = this.resetSocketServerState();
|
|
301
|
-
return stopLocalSocketServer({
|
|
302
|
-
socketScope,
|
|
303
|
-
socketPath: sockPath,
|
|
304
|
-
defaultSocketPath: MoltZapService.SOCKET_PATH,
|
|
305
|
-
}).pipe(Effect.withSpan("MoltZapService.stopSocketServer"));
|
|
306
|
-
}
|
|
307
|
-
localDaemonHandlers() {
|
|
308
|
-
return makeLocalDaemonHandlers({
|
|
309
|
-
ownAgentId: this.ownAgentIdValue,
|
|
310
|
-
// A live thunk, not a snapshot: the handler table outlives connection
|
|
311
|
-
// cycles, and daemon/status must report the same liveness the MCP
|
|
312
|
-
// status tool reads.
|
|
313
|
-
connected: () => this.connectedValue,
|
|
314
|
-
conversationCount: () => this.getConversations().length,
|
|
315
|
-
call: this.call.bind(this),
|
|
316
|
-
handleHistoryRequest: (request) => this.handleHistoryRequest(request),
|
|
317
|
-
});
|
|
318
|
-
}
|
|
319
|
-
handleHistoryRequest(request) {
|
|
320
|
-
return Effect.gen(function* () {
|
|
321
|
-
const result = yield* this.call(messagesList.name, {
|
|
322
|
-
conversationId: request.conversationId,
|
|
323
|
-
limit: request.limit,
|
|
324
|
-
});
|
|
325
|
-
const convMeta = yield* this.loadHistorySupportData(request.conversationId, result.messages);
|
|
326
|
-
const agentNames = yield* Ref.get(this.agentNamesRef);
|
|
327
|
-
const lastReadMap = yield* Ref.get(this.lastReadRef);
|
|
328
|
-
const lastReadIds = lastReadIdsForSession(lastReadMap, request);
|
|
329
|
-
const messages = result.messages.map((message) => formatHistoryMessage(message, {
|
|
330
|
-
agentNames,
|
|
331
|
-
ownAgentId: this.ownAgentId,
|
|
332
|
-
lastReadIds,
|
|
333
|
-
hasSessionKey: request.sessionKey !== undefined,
|
|
334
|
-
}));
|
|
335
|
-
yield* this.advanceHistoryLastRead(request, result.messages);
|
|
336
|
-
return {
|
|
337
|
-
messages,
|
|
338
|
-
conversationMeta: convMeta,
|
|
339
|
-
newCount: messages.filter((message) => message.isNew).length,
|
|
340
|
-
};
|
|
341
|
-
}.bind(this));
|
|
342
|
-
}
|
|
343
|
-
loadHistorySupportData(convId, messages) {
|
|
344
|
-
return Effect.gen(function* () {
|
|
345
|
-
const [, convMeta] = yield* Effect.all([
|
|
346
|
-
this.refreshHistoryAgentNames(messages),
|
|
347
|
-
this.fetchHistoryConversationMeta(convId),
|
|
348
|
-
], {
|
|
349
|
-
concurrency: HISTORY_LOOKUP_CONCURRENCY,
|
|
350
|
-
});
|
|
351
|
-
return convMeta;
|
|
352
|
-
}.bind(this));
|
|
353
|
-
}
|
|
354
|
-
refreshHistoryAgentNames(messages) {
|
|
355
|
-
return Effect.gen(function* () {
|
|
356
|
-
const knownNames = yield* Ref.get(this.agentNamesRef);
|
|
357
|
-
const unknownAgentIds = [
|
|
358
|
-
...new Set(messages.map((message) => message.senderId)),
|
|
359
|
-
].filter((id) => !HashMap.has(knownNames, id));
|
|
360
|
-
if (unknownAgentIds.length === 0) {
|
|
361
|
-
return;
|
|
362
|
-
}
|
|
363
|
-
yield* this.cacheVisibleAgentNamesForIds(new Set(unknownAgentIds)).pipe(Effect.asVoid, Effect.catchAll(() => Effect.void));
|
|
364
|
-
}.bind(this));
|
|
365
|
-
}
|
|
366
|
-
fetchHistoryConversationMeta(convId) {
|
|
367
|
-
// The client filters `ConversationList` output for the matching
|
|
368
|
-
// conversation id (there is no per-conversation get RPC).
|
|
369
|
-
return this.call(conversationList.name, {}).pipe(Effect.map((result) => {
|
|
370
|
-
const hit = result.items.find((item) => item.conversation.id === convId);
|
|
371
|
-
return hit?.conversation;
|
|
372
|
-
}), Effect.orElseSucceed(() => undefined));
|
|
373
|
-
}
|
|
374
|
-
advanceHistoryLastRead(request, messages) {
|
|
375
|
-
if (request.sessionKey === undefined || messages.length === 0) {
|
|
376
|
-
return Effect.void;
|
|
377
|
-
}
|
|
378
|
-
const { conversationId, sessionKey } = request;
|
|
379
|
-
return Ref.update(this.lastReadRef, (outer) => {
|
|
380
|
-
const perSession = getOr(outer, sessionKey, () => HashMap.empty());
|
|
381
|
-
const existing = getOr(perSession, conversationId, () =>
|
|
382
|
-
/* Safe because the surrounding invariant establishes this asserted shape. */ new Set());
|
|
383
|
-
if (messages.every((message) => existing.has(message.id))) {
|
|
384
|
-
return outer;
|
|
385
|
-
}
|
|
386
|
-
const nextSet = new Set(existing);
|
|
387
|
-
for (const message of messages) {
|
|
388
|
-
nextSet.add(message.id);
|
|
389
|
-
}
|
|
390
|
-
return HashMap.set(outer, sessionKey, HashMap.set(perSession, conversationId, nextSet));
|
|
391
|
-
});
|
|
392
|
-
}
|
|
393
|
-
// --- Conversations ---
|
|
394
|
-
getConversation(convId) {
|
|
395
|
-
return Option.getOrUndefined(HashMap.get(snapshot(this.conversationsRef), convId));
|
|
396
|
-
}
|
|
397
|
-
getConversations() {
|
|
398
|
-
return [...HashMap.values(snapshot(this.conversationsRef))];
|
|
399
|
-
}
|
|
400
|
-
// --- Messages ---
|
|
401
|
-
getHistory(convId, limit) {
|
|
402
|
-
const msgs = getOr(snapshot(this.messagesRef), convId, () => []);
|
|
403
|
-
return limit ? msgs.slice(-limit) : [...msgs];
|
|
404
|
-
}
|
|
405
|
-
// --- Agent Names ---
|
|
406
|
-
getAgentName(agentId) {
|
|
407
|
-
return Option.getOrUndefined(HashMap.get(snapshot(this.agentNamesRef), agentId));
|
|
408
|
-
}
|
|
409
|
-
/**
|
|
410
|
-
* Cache-first agent-name lookup. Never fails: falls back to `agentId`
|
|
411
|
-
* when the RPC errors or the server has no record. The error path logs
|
|
412
|
-
* so ops can see repeated lookup failures; the empty-response path is
|
|
413
|
-
* silent (a cold agent is an expected transient state).
|
|
414
|
-
* @param agentId Identifier of the agent targeted by the operation.
|
|
415
|
-
* @returns The decoded d agent id.
|
|
416
|
-
*/
|
|
417
|
-
resolveAgentName(agentId) {
|
|
418
|
-
return Effect.gen(function* () {
|
|
419
|
-
const decodedAgentId = Option.getOrUndefined(decodeAgentId(agentId));
|
|
420
|
-
if (decodedAgentId === undefined) {
|
|
421
|
-
return agentId;
|
|
422
|
-
}
|
|
423
|
-
const cached = Option.getOrUndefined(HashMap.get(snapshot(this.agentNamesRef), agentId));
|
|
424
|
-
if (cached !== undefined) {
|
|
425
|
-
return cached;
|
|
426
|
-
}
|
|
427
|
-
return yield* this.cacheVisibleAgentNamesForIds(new Set([decodedAgentId])).pipe(Effect.map(() => {
|
|
428
|
-
const resolved = Option.getOrUndefined(HashMap.get(snapshot(this.agentNamesRef), agentId));
|
|
429
|
-
return resolved ?? agentId;
|
|
430
|
-
}), Effect.catchAll((err) => Effect.logWarning("agent/identity/agents/list failed; falling back to agentId").pipe(Effect.annotateLogs({ agentId, err: String(err) }), Effect.as(agentId))));
|
|
431
|
-
}.bind(this));
|
|
432
|
-
}
|
|
433
|
-
// --- Messaging ---
|
|
434
|
-
/**
|
|
435
|
-
* Send a text message into a conversation.
|
|
436
|
-
*
|
|
437
|
-
* ```mermaid
|
|
438
|
-
* sequenceDiagram
|
|
439
|
-
* participant caller
|
|
440
|
-
* participant svc as MoltZapService
|
|
441
|
-
* participant ws as MoltZapAgentClient
|
|
442
|
-
* participant server
|
|
443
|
-
*
|
|
444
|
-
* caller->>svc: send(convId, text, opts?)
|
|
445
|
-
* svc->>ws: sendRpc(MessagesSend, params)
|
|
446
|
-
* Note over ws: stateRef None → fail NotConnectedError; otherwise allocate request id, encode frame
|
|
447
|
-
* ws->>server: {jsonrpc, method agent/message/send, id, params}
|
|
448
|
-
* Note over ws: Deferred raced against 30s timeout
|
|
449
|
-
* server-->>ws: {result, id} or {error, id}
|
|
450
|
-
* Note over ws: reader fiber decodes, resolves the Deferred
|
|
451
|
-
* ws-->>svc: result or RpcServerError or RpcTimeoutError
|
|
452
|
-
* svc-->>caller: Effect.void
|
|
453
|
-
* ```
|
|
454
|
-
*
|
|
455
|
-
* @param conversationId Value supplied to the operation.
|
|
456
|
-
* @param text Text to process.
|
|
457
|
-
* @returns The send result.
|
|
458
|
-
*/
|
|
459
|
-
send(conversationId, text) {
|
|
460
|
-
return Effect.asVoid(this.call(messagesSend.name, {
|
|
461
|
-
conversationId,
|
|
462
|
-
parts: [{ type: "text", text }],
|
|
463
|
-
}));
|
|
464
|
-
}
|
|
465
|
-
/**
|
|
466
|
-
* Send to a named agent, minting the DM conversation on first use and
|
|
467
|
-
* reusing it afterwards. The per-name cache is what makes the DM stable:
|
|
468
|
-
* `agent/conversation/create` mints a fresh conversation on every call.
|
|
469
|
-
* @param agentName Name of the agent to reach.
|
|
470
|
-
* @param text Text to process.
|
|
471
|
-
* @returns The send result.
|
|
472
|
-
*/
|
|
473
|
-
sendToAgent(agentName, text) {
|
|
474
|
-
return Effect.gen(function* () {
|
|
475
|
-
const cache = yield* Ref.get(this.agentConversationCacheRef);
|
|
476
|
-
let conversationId = Option.getOrUndefined(HashMap.get(cache, agentName));
|
|
477
|
-
if (conversationId === undefined) {
|
|
478
|
-
const agent = yield* this.findVisibleAgentByName(agentName);
|
|
479
|
-
if (!agent) {
|
|
480
|
-
return yield* agentNotFound(agentName);
|
|
481
|
-
}
|
|
482
|
-
const created = yield* this.call(agentConversationCreate.name, {
|
|
483
|
-
participants: [agent.id],
|
|
484
|
-
});
|
|
485
|
-
conversationId = created.conversation.id;
|
|
486
|
-
const cached = conversationId;
|
|
487
|
-
yield* Ref.update(this.agentConversationCacheRef, (m) => HashMap.set(m, agentName, cached));
|
|
488
|
-
}
|
|
489
|
-
yield* this.send(conversationId, text);
|
|
490
|
-
}.bind(this));
|
|
491
|
-
}
|
|
492
|
-
cacheAgentNames(agents) {
|
|
493
|
-
if (agents.length === 0) {
|
|
494
|
-
return Effect.void;
|
|
495
|
-
}
|
|
496
|
-
return Ref.update(this.agentNamesRef, (names) => {
|
|
497
|
-
let next = names;
|
|
498
|
-
for (const agent of agents) {
|
|
499
|
-
next = HashMap.set(next, agent.id, agent.name);
|
|
500
|
-
}
|
|
501
|
-
return next;
|
|
502
|
-
});
|
|
503
|
-
}
|
|
504
|
-
agentListParams(cursor) {
|
|
505
|
-
return cursor === undefined
|
|
506
|
-
? { limit: AGENT_LOOKUP_PAGE_SIZE }
|
|
507
|
-
: { limit: AGENT_LOOKUP_PAGE_SIZE, cursor };
|
|
508
|
-
}
|
|
509
|
-
cacheVisibleAgentNamesForIds(agentIds) {
|
|
510
|
-
return Effect.gen(function* () {
|
|
511
|
-
const missing = new Set(agentIds);
|
|
512
|
-
let cursor = undefined;
|
|
513
|
-
for (let page = 0; page < AGENT_LOOKUP_MAX_PAGES; page++) {
|
|
514
|
-
const params = this.agentListParams(cursor);
|
|
515
|
-
const result = yield* this.call(agentsList.name, params);
|
|
516
|
-
yield* this.cacheAgentNames(result.agents);
|
|
517
|
-
for (const agent of result.agents) {
|
|
518
|
-
missing.delete(agent.id);
|
|
519
|
-
}
|
|
520
|
-
if (missing.size === 0 || result.nextCursor === undefined) {
|
|
521
|
-
return;
|
|
522
|
-
}
|
|
523
|
-
cursor = result.nextCursor;
|
|
524
|
-
}
|
|
525
|
-
}.bind(this));
|
|
526
|
-
}
|
|
527
|
-
findVisibleAgentByName(agentName) {
|
|
528
|
-
return Effect.gen(function* () {
|
|
529
|
-
let cursor = undefined;
|
|
530
|
-
for (let page = 0; page < AGENT_LOOKUP_MAX_PAGES; page++) {
|
|
531
|
-
const params = this.agentListParams(cursor);
|
|
532
|
-
const result = yield* this.call(agentsList.name, params);
|
|
533
|
-
yield* this.cacheAgentNames(result.agents);
|
|
534
|
-
const hit = result.agents.find((agent) => agent.name === agentName);
|
|
535
|
-
if (hit !== undefined || result.nextCursor === undefined) {
|
|
536
|
-
return hit;
|
|
537
|
-
}
|
|
538
|
-
cursor = result.nextCursor;
|
|
539
|
-
}
|
|
540
|
-
return undefined;
|
|
541
|
-
}.bind(this));
|
|
542
|
-
}
|
|
543
|
-
// --- Cross-Conversation Context ---
|
|
544
|
-
/**
|
|
545
|
-
* Generate a system reminder with updates from other conversations.
|
|
546
|
-
* Each conversation has its own view of what's "new" — markers are tracked
|
|
547
|
-
* per viewing conversation and advanced after notification.
|
|
548
|
-
* @param currentConvId Value supplied to the operation.
|
|
549
|
-
* @param opts Value supplied to the operation.
|
|
550
|
-
* @returns The context options result.
|
|
551
|
-
*/
|
|
552
|
-
getContext(currentConvId, opts) {
|
|
553
|
-
const contextOptions = opts ?? {};
|
|
554
|
-
const { entries, commit } = this.peekContextEntries(currentConvId, contextOptions);
|
|
555
|
-
if (entries.length === 0) {
|
|
556
|
-
return null;
|
|
557
|
-
}
|
|
558
|
-
commit();
|
|
559
|
-
return formatCrossConversationBlock(entries, {
|
|
560
|
-
header: `Recent updates (you are in conv:${currentConvId}):`,
|
|
561
|
-
});
|
|
562
|
-
}
|
|
563
|
-
/**
|
|
564
|
-
* Return recent activity in other conversations without advancing any state.
|
|
565
|
-
* Call `commit()` on the result to mark the returned messages as seen so
|
|
566
|
-
* subsequent peeks return only what's new. A caller that reads without
|
|
567
|
-
* committing can re-peek idempotently.
|
|
568
|
-
* @param currentConvId Value supplied to the operation.
|
|
569
|
-
* @param opts Value supplied to the operation.
|
|
570
|
-
* @param opts.maxConversations Value supplied to the operation.
|
|
571
|
-
* @param opts.maxMessagesPerConv Value supplied to the operation.
|
|
572
|
-
* @returns The max convs result.
|
|
573
|
-
*/
|
|
574
|
-
peekContextEntries(currentConvId, opts) {
|
|
575
|
-
const maxConvs = opts?.maxConversations ?? DEFAULT_MAX_CONTEXT_CONVERSATIONS;
|
|
576
|
-
const maxMsgsPerConv = opts?.maxMessagesPerConv ?? DEFAULT_MAX_MESSAGES_PER_CONVERSATION;
|
|
577
|
-
const state = this.readCrossConvState(currentConvId);
|
|
578
|
-
const candidates = this.collectContextCandidates(state, currentConvId);
|
|
579
|
-
const { entries, pendingAdvances } = buildContextEntries(candidates.slice(0, maxConvs), state, maxMsgsPerConv);
|
|
580
|
-
return {
|
|
581
|
-
entries,
|
|
582
|
-
commit: () => {
|
|
583
|
-
this.advanceLastNotified(currentConvId, pendingAdvances);
|
|
584
|
-
},
|
|
585
|
-
};
|
|
586
|
-
}
|
|
587
|
-
/**
|
|
588
|
-
* Return all new messages from all other conversations as full transcripts,
|
|
589
|
-
* sorted chronologically. Uses the same lastNotified markers as
|
|
590
|
-
* peekContextEntries. Call commit() to advance markers.
|
|
591
|
-
* @param currentConvId Value supplied to the operation.
|
|
592
|
-
* @returns The all messages result.
|
|
593
|
-
*/
|
|
594
|
-
peekFullMessages(currentConvId) {
|
|
595
|
-
const { messagesMap, conversationsMap, agentNamesMap, viewMarkers } = this.readCrossConvState(currentConvId);
|
|
596
|
-
const allMessages = [];
|
|
597
|
-
const pendingAdvances = [];
|
|
598
|
-
for (const [convId, newMsgs] of this.iterNewMessagesByConv(messagesMap, viewMarkers, currentConvId)) {
|
|
599
|
-
const convName = Option.getOrUndefined(HashMap.get(conversationsMap, convId))?.name;
|
|
600
|
-
for (const m of newMsgs) {
|
|
601
|
-
allMessages.push({
|
|
602
|
-
conversationId: convId,
|
|
603
|
-
conversationName: convName,
|
|
604
|
-
senderName: getOr(agentNamesMap, m.senderId, () => m.senderId),
|
|
605
|
-
senderId: m.senderId,
|
|
606
|
-
text: m.parts.map(renderPart).join(" "),
|
|
607
|
-
timestamp: m.createdAt,
|
|
608
|
-
});
|
|
609
|
-
}
|
|
610
|
-
pendingAdvances.push([
|
|
611
|
-
convId,
|
|
612
|
-
/* Safe because the surrounding invariant establishes this asserted shape. */ newMsgs[newMsgs.length - 1].id,
|
|
613
|
-
]);
|
|
614
|
-
}
|
|
615
|
-
allMessages.sort((a, b) => a.timestamp.localeCompare(b.timestamp));
|
|
616
|
-
return {
|
|
617
|
-
messages: allMessages,
|
|
618
|
-
commit: () => {
|
|
619
|
-
this.advanceLastNotified(currentConvId, pendingAdvances);
|
|
620
|
-
},
|
|
621
|
-
};
|
|
622
|
-
}
|
|
623
|
-
readCrossConvState(currentConvId) {
|
|
624
|
-
const lastNotifiedMap = snapshot(this.lastNotifiedRef);
|
|
625
|
-
return {
|
|
626
|
-
messagesMap: snapshot(this.messagesRef),
|
|
627
|
-
conversationsMap: snapshot(this.conversationsRef),
|
|
628
|
-
agentNamesMap: snapshot(this.agentNamesRef),
|
|
629
|
-
viewMarkers: getOr(lastNotifiedMap, currentConvId, () => HashMap.empty()),
|
|
630
|
-
};
|
|
631
|
-
}
|
|
632
|
-
collectContextCandidates(state, currentConvId) {
|
|
633
|
-
const candidates = [];
|
|
634
|
-
for (const [convId, newMsgs] of this.iterNewMessagesByConv(state.messagesMap, state.viewMarkers, currentConvId)) {
|
|
635
|
-
candidates.push(makeContextCandidate(convId, newMsgs));
|
|
636
|
-
}
|
|
637
|
-
candidates.sort((a, b) => b.lastTs - a.lastTs);
|
|
638
|
-
return candidates;
|
|
639
|
-
}
|
|
640
|
-
*iterNewMessagesByConv(messagesMap, viewMarkers, currentConvId) {
|
|
641
|
-
for (const [convId, msgs] of messagesMap) {
|
|
642
|
-
const newMsgs = newMessagesForConversation(convId, msgs, viewMarkers, currentConvId);
|
|
643
|
-
if (newMsgs.length > 0) {
|
|
644
|
-
yield [convId, newMsgs];
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
advanceLastNotified(currentConvId, pendingAdvances) {
|
|
649
|
-
if (pendingAdvances.length === 0) {
|
|
650
|
-
return;
|
|
651
|
-
}
|
|
652
|
-
Effect.runSync(Ref.update(this.lastNotifiedRef, (outer) => {
|
|
653
|
-
let markers = getOr(outer, currentConvId, () => HashMap.empty());
|
|
654
|
-
for (const [convId, msgId] of pendingAdvances) {
|
|
655
|
-
markers = HashMap.set(markers, convId, msgId);
|
|
656
|
-
}
|
|
657
|
-
return HashMap.set(outer, currentConvId, markers);
|
|
658
|
-
}));
|
|
659
|
-
}
|
|
660
|
-
// --- Notifications ---
|
|
661
|
-
on(notification, handler) {
|
|
662
|
-
this.handlers[notification].push(handler);
|
|
663
|
-
}
|
|
664
|
-
// --- RPC passthrough ---
|
|
665
|
-
/**
|
|
666
|
-
* Outbound RPC, typed per method — delegates to the agent client's typed
|
|
667
|
-
* `call`. `call("agent/identity/agents/list", payload)` recovers the result and that
|
|
668
|
-
* method's tagged-error union; an app-only method does not typecheck.
|
|
669
|
-
* @param tag Value supplied to the operation.
|
|
670
|
-
* @param payload Value supplied to the operation.
|
|
671
|
-
* @param opts Value supplied to the operation.
|
|
672
|
-
* @returns The client result.
|
|
673
|
-
*/
|
|
674
|
-
call(tag, payload, opts) {
|
|
675
|
-
return Effect.suspend(() => {
|
|
676
|
-
const client = this.client;
|
|
677
|
-
if (!client) {
|
|
678
|
-
return Effect.fail(new NotConnectedError({ message: "Not connected" }));
|
|
679
|
-
}
|
|
680
|
-
return client.call(tag, payload, opts);
|
|
681
|
-
});
|
|
682
|
-
}
|
|
683
|
-
callDefinition(definition, payload, opts) {
|
|
684
|
-
return Effect.suspend(() => {
|
|
685
|
-
const client = this.client;
|
|
686
|
-
if (!client) {
|
|
687
|
-
return Effect.fail(new NotConnectedError({ message: "Not connected" }));
|
|
688
|
-
}
|
|
689
|
-
return client.callDefinition(definition, payload, opts);
|
|
690
|
-
});
|
|
691
|
-
}
|
|
692
|
-
// --- Internals ---
|
|
693
|
-
handleNotification(notification) {
|
|
694
|
-
this.recordNotificationTrace(notification);
|
|
695
|
-
fanout(this.handlers.rawNotification, notification);
|
|
696
|
-
this.dispatchTypedNotification(notification);
|
|
697
|
-
}
|
|
698
|
-
recordNotificationTrace(notification) {
|
|
699
|
-
Effect.runFork(appendClientEventTrace(notificationTraceRecord(notification, this.ownAgentIdValue)));
|
|
700
|
-
}
|
|
701
|
-
dispatchTypedNotification(notification) {
|
|
702
|
-
if (this.dispatchMessageNotification(notification)) {
|
|
703
|
-
return;
|
|
704
|
-
}
|
|
705
|
-
this.dispatchConversationNotification(notification);
|
|
706
|
-
}
|
|
707
|
-
dispatchMessageNotification(notification) {
|
|
708
|
-
if (isNotificationDeliveryFor(notification, messageReceivedNotificationDefinition)) {
|
|
709
|
-
this.handleMessageReceivedNotification(notification.params);
|
|
710
|
-
return true;
|
|
711
|
-
}
|
|
712
|
-
return false;
|
|
713
|
-
}
|
|
714
|
-
dispatchConversationNotification(notification) {
|
|
715
|
-
if (isNotificationDeliveryFor(notification, conversationCreatedNotificationDefinition)) {
|
|
716
|
-
this.handleConversationCreatedNotification(notification.params);
|
|
717
|
-
return true;
|
|
718
|
-
}
|
|
719
|
-
return false;
|
|
720
|
-
}
|
|
721
|
-
/**
|
|
722
|
-
* Record `messageId` in the per-conversation dedup window. Returns
|
|
723
|
-
* `true` when the id is new (caller proceeds), `false` when the id is
|
|
724
|
-
* a duplicate within the window (caller drops). On a new id, evicts
|
|
725
|
-
* the oldest entry if the window is full.
|
|
726
|
-
*
|
|
727
|
-
* Bound to the live `agent/message/received` notification path: a single
|
|
728
|
-
* server-side broadcast that surfaces the same id twice (network
|
|
729
|
-
* replay, dual subscription) is suppressed to one
|
|
730
|
-
* `on("message", ...)` event. `agent/message/list` returns raw history
|
|
731
|
-
* unfiltered; consumers that combine both feeds dedup themselves.
|
|
732
|
-
* @param convId Value supplied to the operation.
|
|
733
|
-
* @param msgId Value supplied to the operation.
|
|
734
|
-
* @returns The dedup window result.
|
|
735
|
-
*/
|
|
736
|
-
recordMessageIdIfNew(convId, msgId) {
|
|
737
|
-
let dedupWindow = this.seenMessageIds.get(convId);
|
|
738
|
-
if (dedupWindow === undefined) {
|
|
739
|
-
dedupWindow = new BoundedMap(DEDUP_WINDOW_PER_CONV);
|
|
740
|
-
this.seenMessageIds.set(convId, dedupWindow);
|
|
741
|
-
}
|
|
742
|
-
if (dedupWindow.has(msgId)) {
|
|
743
|
-
// Replays retain their original FIFO age so repeated delivery cannot
|
|
744
|
-
// keep an old id resident forever.
|
|
745
|
-
return false;
|
|
746
|
-
}
|
|
747
|
-
dedupWindow.set(msgId, true);
|
|
748
|
-
return true;
|
|
749
|
-
}
|
|
750
|
-
handleMessageReceivedNotification(notification) {
|
|
751
|
-
const msg = notification.message;
|
|
752
|
-
const convId = msg.conversationId;
|
|
753
|
-
if (!this.recordMessageIdIfNew(convId, msg.id)) {
|
|
754
|
-
return;
|
|
755
|
-
}
|
|
756
|
-
this.storeMessage(msg);
|
|
757
|
-
// Name resolution is driven lazily by channel-core's serialized consumer
|
|
758
|
-
// via resolveAgentName(), which populates agentNamesRef on first miss and
|
|
759
|
-
// hits the cache on every subsequent message.
|
|
760
|
-
if (msg.senderId !== this.ownAgentIdValue) {
|
|
761
|
-
fanout(this.handlers.message, { message: msg });
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
handleConversationCreatedNotification(notification) {
|
|
765
|
-
const { conversationId, name, participants } = notification;
|
|
766
|
-
Effect.runSync(Ref.update(this.conversationsRef, (m) => {
|
|
767
|
-
// The notification carries the full membership, this agent included,
|
|
768
|
-
// so anything past two members is a group.
|
|
769
|
-
const inferredType = participants.length <= 2 ? "dm" : "group";
|
|
770
|
-
return HashMap.set(m, conversationId, {
|
|
771
|
-
id: conversationId,
|
|
772
|
-
type: inferredType,
|
|
773
|
-
participants: participants.map((p) => `agent:${p}`),
|
|
774
|
-
...(name !== undefined ? { name } : {}),
|
|
775
|
-
});
|
|
776
|
-
}));
|
|
777
|
-
}
|
|
778
|
-
storeMessage(msg) {
|
|
779
|
-
Effect.runSync(Ref.update(this.messagesRef, (m) => {
|
|
780
|
-
const existing = getOr(m, msg.conversationId, () => []);
|
|
781
|
-
const appended = [...existing, msg];
|
|
782
|
-
const capped = appended.length > MAX_MESSAGES_PER_CONV
|
|
783
|
-
? appended.slice(-MAX_MESSAGES_PER_CONV)
|
|
784
|
-
: appended;
|
|
785
|
-
return HashMap.set(m, msg.conversationId, capped);
|
|
786
|
-
}));
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
//# sourceMappingURL=service.js.map
|