@jungjaehoon/mama-core 2.4.1 → 4.1.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/README.md +76 -239
- package/db/migrations/030-case-first-memory-substrate.sql +13 -98
- package/db/migrations/034-add-connector-event-scope-columns.sql +9 -13
- package/db/migrations/039-add-connector-event-operator-ingest-seq.sql +9 -95
- package/db/migrations/062-refresh-connector-event-sequences.sql +9 -113
- package/db/migrations/063-refresh-legacy-connector-event-updates.sql +9 -32
- package/db/migrations/067-add-connector-event-source-entity-id.sql +9 -13
- package/db/migrations/069-create-registry-nodes.sql +52 -0
- package/db/migrations/070-record-identity.sql +35 -0
- package/db/migrations/071-service-operation-origins.sql +187 -0
- package/db/migrations/072-observation-versions.sql +29 -0
- package/db/migrations/073-registry-corrections.sql +45 -0
- package/db/migrations/074-work-graph-ref-kinds.sql +39 -0
- package/db/migrations/075-agent-judgments.sql +58 -0
- package/db/migrations/076-scoped-checkpoint-bindings.sql +15 -0
- package/db/migrations/077-legacy-record-kind.sql +6 -0
- package/db/migrations/078-source-ingest-commands.sql +18 -0
- package/db/migrations/079-twin-edge-relations.sql +43 -0
- package/db/migrations/080-restore-duration-days.sql +7 -0
- package/db/migrations/081-mailbox.sql +61 -0
- package/db/migrations/082-commitments-row-id.sql +12 -0
- package/db/migrations/083-observation-is-the-evidence.sql +49 -0
- package/db/migrations/084-scope-kind-is-not-the-cores-to-list.sql +34 -0
- package/db/migrations/085-a-migration-has-a-source.sql +37 -0
- package/db/migrations/086-the-mailbox-is-generic.sql +110 -0
- package/db/migrations/087-mailbox-payload.sql +5 -0
- package/db/migrations/088-native-input-journal.sql +14 -0
- package/db/migrations/089-native-turn-receipt-lookup.sql +3 -0
- package/db/migrations/090-model-run-native-inputs.sql +29 -0
- package/db/migrations/091-native-turn-results.sql +11 -0
- package/db/migrations/092-restore-decision-fts.sql +34 -0
- package/db/migrations/093-native-turn-primary-kind.sql +14 -0
- package/db/migrations/094-commitment-run-provenance.sql +9 -0
- package/db/migrations/095-model-run-native-input-identity.sql +39 -0
- package/db/migrations/096-drop-connector-event-index-fts.sql +9 -0
- package/db/migrations/097-native-input-json-validity.sql +37 -0
- package/db/migrations/098-workflow-memory-kind.sql +105 -0
- package/db/migrations/099-commitment-revision-graph.sql +2 -0
- package/dist/action-contracts.d.ts +212 -0
- package/dist/action-contracts.js +10 -0
- package/dist/api/catalog.d.ts +118 -0
- package/dist/api/catalog.js +1756 -0
- package/dist/api/dispatch.d.ts +76 -0
- package/dist/api/dispatch.js +372 -0
- package/dist/canonicalize.d.ts +2 -2
- package/dist/canonicalize.js +3 -3
- package/dist/client/client.d.ts +33 -0
- package/dist/client/client.js +123 -0
- package/dist/client/ipc.d.ts +81 -0
- package/dist/client/ipc.js +314 -0
- package/dist/db-adapter/base-adapter.d.ts +6 -66
- package/dist/db-adapter/base-adapter.js +6 -6
- package/dist/db-adapter/index.d.ts +5 -5
- package/dist/db-adapter/index.js +2 -5
- package/dist/db-adapter/node-sqlite-adapter.d.ts +85 -15
- package/dist/db-adapter/node-sqlite-adapter.js +1985 -570
- package/dist/db-manager.d.ts +53 -97
- package/dist/db-manager.js +121 -603
- package/dist/embedding/embedder.d.ts +132 -0
- package/dist/embedding/embedder.js +299 -0
- package/dist/identity/principal-repository.d.ts +2 -2
- package/dist/index.d.ts +43 -58
- package/dist/index.js +97 -145
- package/dist/{context-compile/channel-grant.d.ts → knowledge/access.d.ts} +12 -17
- package/dist/knowledge/access.js +663 -0
- package/dist/knowledge/case-errors.d.ts +31 -0
- package/dist/knowledge/case-errors.js +40 -0
- package/dist/{cases/search-rollup.d.ts → knowledge/case-search-rollup.d.ts} +5 -4
- package/dist/{cases/search-rollup.js → knowledge/case-search-rollup.js} +6 -8
- package/dist/{cases/store.d.ts → knowledge/case-store.d.ts} +3 -6
- package/dist/{cases/store.js → knowledge/case-store.js} +7 -42
- package/dist/{cases/timeline-range.d.ts → knowledge/case-timeline-range.d.ts} +3 -3
- package/dist/{cases/timeline-range.js → knowledge/case-timeline-range.js} +47 -25
- package/dist/{cases/types.d.ts → knowledge/case-types.d.ts} +8 -2
- package/dist/{cases/types.js → knowledge/case-types.js} +1 -1
- package/dist/knowledge/commitment-revision-migration.d.ts +4 -0
- package/dist/knowledge/commitment-revision-migration.js +50 -0
- package/dist/knowledge/commitments.d.ts +192 -0
- package/dist/knowledge/commitments.js +386 -0
- package/dist/knowledge/decision-edges.d.ts +70 -0
- package/dist/knowledge/decision-edges.js +123 -0
- package/dist/{agent-graph/types.d.ts → knowledge/graph-query.d.ts} +80 -70
- package/dist/knowledge/graph-query.js +1585 -0
- package/dist/knowledge/identity.d.ts +16 -0
- package/dist/knowledge/identity.js +22 -0
- package/dist/knowledge/index.d.ts +47 -0
- package/dist/knowledge/index.js +90 -0
- package/dist/knowledge/judgment-edge.d.ts +6 -0
- package/dist/knowledge/judgment-edge.js +22 -0
- package/dist/knowledge/judgments.d.ts +118 -0
- package/dist/knowledge/judgments.js +802 -0
- package/dist/knowledge/observations.d.ts +160 -0
- package/dist/knowledge/observations.js +449 -0
- package/dist/knowledge/question-type.d.ts +34 -0
- package/dist/knowledge/question-type.js +70 -0
- package/dist/{search → knowledge}/ranker-features.js +1 -1
- package/dist/{search → knowledge}/search-quality.d.ts +0 -1
- package/dist/knowledge/search.d.ts +38 -0
- package/dist/knowledge/search.js +91 -0
- package/dist/knowledge/source-ingest.d.ts +65 -0
- package/dist/knowledge/source-ingest.js +174 -0
- package/dist/{edges/types.d.ts → knowledge/twin-edge-types.d.ts} +31 -4
- package/dist/{edges/types.js → knowledge/twin-edge-types.js} +13 -2
- package/dist/knowledge/work-dates.d.ts +49 -0
- package/dist/knowledge/work-dates.js +120 -0
- package/dist/mama-api.d.ts +114 -778
- package/dist/mama-api.js +313 -2461
- package/dist/memory/api.d.ts +264 -24
- package/dist/memory/api.js +1633 -843
- package/dist/memory/bootstrap-builder.d.ts +2 -1
- package/dist/memory/bootstrap-builder.js +5 -5
- package/dist/memory/channel-summary-state-store.d.ts +3 -2
- package/dist/memory/channel-summary-state-store.js +53 -51
- package/dist/memory/channel-summary-store.d.ts +5 -3
- package/dist/memory/channel-summary-store.js +3 -8
- package/dist/memory/dashboard-read.d.ts +46 -0
- package/dist/memory/dashboard-read.js +94 -0
- package/dist/memory/event-store.d.ts +3 -3
- package/dist/memory/event-store.js +3 -10
- package/dist/memory/finding-store.d.ts +3 -2
- package/dist/memory/finding-store.js +2 -7
- package/dist/memory/graph-read.d.ts +52 -0
- package/dist/memory/graph-read.js +130 -0
- package/dist/memory/judgment-types.d.ts +394 -0
- package/dist/memory/judgment-types.js +16 -0
- package/dist/memory/provenance-audit.d.ts +5 -2
- package/dist/memory/provenance-audit.js +8 -14
- package/dist/memory/provenance-live.d.ts +141 -0
- package/dist/memory/provenance-live.js +409 -0
- package/dist/memory/provenance-query.d.ts +5 -4
- package/dist/memory/provenance-query.js +21 -29
- package/dist/memory/provenance-resolver.d.ts +191 -0
- package/dist/memory/provenance-resolver.js +155 -0
- package/dist/memory/provenance.d.ts +1 -11
- package/dist/memory/provenance.js +2 -33
- package/dist/memory/recall-sanitize.d.ts +55 -0
- package/dist/memory/recall-sanitize.js +144 -0
- package/dist/memory/secret-filter.d.ts +32 -0
- package/dist/memory/secret-filter.js +126 -0
- package/dist/memory/truth-store.d.ts +2 -1
- package/dist/memory/truth-store.js +1 -4
- package/dist/memory/types.d.ts +74 -24
- package/dist/memory/types.js +75 -5
- package/dist/memory/write-adapters.d.ts +98 -0
- package/dist/memory/write-adapters.js +242 -0
- package/dist/operations/owner-action-effects.d.ts +53 -0
- package/dist/operations/owner-action-effects.js +96 -0
- package/dist/provenance/source-ref.d.ts +1 -1
- package/dist/provenance/source-ref.js +0 -2
- package/dist/registry/corrections.d.ts +31 -0
- package/dist/registry/corrections.js +332 -0
- package/dist/registry/record-identity.d.ts +49 -0
- package/dist/registry/record-identity.js +133 -0
- package/dist/registry/store.d.ts +101 -0
- package/dist/registry/store.js +395 -0
- package/dist/registry/types.d.ts +28 -0
- package/dist/registry/types.js +5 -0
- package/dist/relevance-scorer.js +2 -2
- package/dist/runtime/agent-event-bus.d.ts +50 -0
- package/dist/runtime/agent-event-bus.js +101 -0
- package/dist/runtime/drivers/claude-cli-wrapper.d.ts +152 -0
- package/dist/runtime/drivers/claude-cli-wrapper.js +375 -0
- package/dist/runtime/drivers/claude-effort.d.ts +4 -0
- package/dist/runtime/drivers/claude-effort.js +16 -0
- package/dist/runtime/drivers/cli-arg-redaction.d.ts +2 -0
- package/dist/runtime/drivers/cli-arg-redaction.js +18 -0
- package/dist/runtime/drivers/cli-secret-redaction.d.ts +17 -0
- package/dist/runtime/drivers/cli-secret-redaction.js +126 -0
- package/dist/runtime/drivers/codex-app-server-process.d.ts +277 -0
- package/dist/runtime/drivers/codex-app-server-process.js +2342 -0
- package/dist/runtime/drivers/codex-auxiliary-tools.d.ts +17 -0
- package/dist/runtime/drivers/codex-auxiliary-tools.js +267 -0
- package/dist/runtime/drivers/codex-home.d.ts +20 -0
- package/dist/runtime/drivers/codex-home.js +674 -0
- package/dist/runtime/drivers/codex-thread-registry.d.ts +63 -0
- package/dist/runtime/drivers/codex-thread-registry.js +433 -0
- package/dist/runtime/drivers/persistent-cli-adapter.d.ts +160 -0
- package/dist/runtime/drivers/persistent-cli-adapter.js +396 -0
- package/dist/runtime/drivers/persistent-cli-process.d.ts +425 -0
- package/dist/runtime/drivers/persistent-cli-process.js +1529 -0
- package/dist/runtime/drivers/types.d.ts +456 -0
- package/dist/runtime/drivers/types.js +110 -0
- package/dist/runtime/mailbox.d.ts +223 -0
- package/dist/runtime/mailbox.js +582 -0
- package/dist/runtime/model-run-store.d.ts +28 -0
- package/dist/{model-runs/store.js → runtime/model-run-store.js} +81 -41
- package/dist/{model-runs/types.d.ts → runtime/model-run-types.d.ts} +33 -4
- package/dist/{model-runs/types.js → runtime/model-run-types.js} +1 -1
- package/dist/runtime/native-effect-observer.d.ts +22 -0
- package/dist/runtime/native-effect-observer.js +103 -0
- package/dist/runtime/native-input-journal.d.ts +46 -0
- package/dist/runtime/native-input-journal.js +308 -0
- package/dist/runtime/native-prompt.d.ts +118 -0
- package/dist/runtime/native-prompt.js +496 -0
- package/dist/runtime/native-session.d.ts +10 -0
- package/dist/{agent-graph/index.js → runtime/native-session.js} +9 -6
- package/dist/runtime/native-tool-trace-observer.d.ts +5 -0
- package/dist/runtime/native-tool-trace-observer.js +65 -0
- package/dist/runtime/native-turn.d.ts +272 -0
- package/dist/runtime/native-turn.js +1041 -0
- package/dist/runtime/operations.d.ts +236 -0
- package/dist/runtime/operations.js +565 -0
- package/dist/runtime/post-tool-handler.d.ts +74 -0
- package/dist/runtime/post-tool-handler.js +137 -0
- package/dist/runtime/prompt-layers.d.ts +126 -0
- package/dist/runtime/prompt-layers.js +239 -0
- package/dist/runtime/runtime-process.d.ts +102 -0
- package/dist/runtime/runtime-process.js +206 -0
- package/dist/runtime/runtime.d.ts +278 -0
- package/dist/runtime/runtime.js +563 -0
- package/dist/runtime/session-pool.d.ts +176 -0
- package/dist/runtime/session-pool.js +369 -0
- package/dist/runtime/stimulus-payload.d.ts +5 -0
- package/dist/runtime/stimulus-payload.js +50 -0
- package/dist/runtime/subagent-bridge.d.ts +24 -0
- package/dist/{agent-graph/types.js → runtime/subagent-bridge.js} +1 -1
- package/dist/runtime/text-completion.d.ts +22 -0
- package/dist/{agent-situation/types.js → runtime/text-completion.js} +1 -1
- package/dist/runtime/token-estimator.d.ts +25 -0
- package/dist/runtime/token-estimator.js +75 -0
- package/dist/runtime/tool-trace-store.d.ts +22 -0
- package/dist/{model-runs → runtime}/tool-trace-store.js +46 -27
- package/dist/runtime/trace-summary.d.ts +5 -0
- package/dist/runtime/trace-summary.js +74 -0
- package/dist/runtime/turn-text.d.ts +23 -0
- package/dist/runtime/turn-text.js +41 -0
- package/dist/storage/database.d.ts +67 -0
- package/dist/storage/database.js +158 -0
- package/package.json +20 -34
- package/dist/agent-graph/alias-write.d.ts +0 -3
- package/dist/agent-graph/alias-write.js +0 -234
- package/dist/agent-graph/entity-resolve.d.ts +0 -3
- package/dist/agent-graph/entity-resolve.js +0 -271
- package/dist/agent-graph/errors.d.ts +0 -4
- package/dist/agent-graph/errors.js +0 -11
- package/dist/agent-graph/graph-query.d.ts +0 -5
- package/dist/agent-graph/graph-query.js +0 -360
- package/dist/agent-graph/index.d.ts +0 -6
- package/dist/agent-situation/builder.d.ts +0 -8
- package/dist/agent-situation/builder.js +0 -239
- package/dist/agent-situation/cache-key.d.ts +0 -4
- package/dist/agent-situation/cache-key.js +0 -64
- package/dist/agent-situation/index.d.ts +0 -7
- package/dist/agent-situation/index.js +0 -28
- package/dist/agent-situation/packet-store.d.ts +0 -27
- package/dist/agent-situation/packet-store.js +0 -228
- package/dist/agent-situation/ranking-policy.d.ts +0 -18
- package/dist/agent-situation/ranking-policy.js +0 -75
- package/dist/agent-situation/source-readers.d.ts +0 -52
- package/dist/agent-situation/source-readers.js +0 -300
- package/dist/agent-situation/types.d.ts +0 -195
- package/dist/cases/wiki-page-index.d.ts +0 -37
- package/dist/cases/wiki-page-index.js +0 -201
- package/dist/config-loader.d.ts +0 -68
- package/dist/config-loader.js +0 -239
- package/dist/connectors/event-index.d.ts +0 -24
- package/dist/connectors/event-index.js +0 -245
- package/dist/connectors/raw-query.d.ts +0 -40
- package/dist/connectors/raw-query.js +0 -412
- package/dist/connectors/types.d.ts +0 -117
- package/dist/connectors/types.js +0 -3
- package/dist/context-compile/boundary-defaults.d.ts +0 -12
- package/dist/context-compile/boundary-defaults.js +0 -105
- package/dist/context-compile/channel-grant.js +0 -66
- package/dist/context-compile/compiler-policy.d.ts +0 -39
- package/dist/context-compile/compiler-policy.js +0 -147
- package/dist/context-compile/compiler.d.ts +0 -18
- package/dist/context-compile/compiler.js +0 -404
- package/dist/context-compile/index.d.ts +0 -10
- package/dist/context-compile/index.js +0 -26
- package/dist/context-compile/packet-store.d.ts +0 -8
- package/dist/context-compile/packet-store.js +0 -239
- package/dist/context-compile/ref.d.ts +0 -7
- package/dist/context-compile/ref.js +0 -102
- package/dist/context-compile/source-readers.d.ts +0 -70
- package/dist/context-compile/source-readers.js +0 -840
- package/dist/context-compile/types.d.ts +0 -155
- package/dist/context-compile/types.js +0 -11
- package/dist/context-compile/visibility.d.ts +0 -21
- package/dist/context-compile/visibility.js +0 -224
- package/dist/decision-tracker.d.ts +0 -206
- package/dist/decision-tracker.js +0 -481
- package/dist/edges/ref-validation.d.ts +0 -7
- package/dist/edges/ref-validation.js +0 -321
- package/dist/edges/store.d.ts +0 -8
- package/dist/edges/store.js +0 -129
- package/dist/embedding-client.d.ts +0 -28
- package/dist/embedding-client.js +0 -53
- package/dist/embedding-server/index.d.ts +0 -67
- package/dist/embedding-server/index.js +0 -405
- package/dist/embedding-server/mobile/auth.d.ts +0 -44
- package/dist/embedding-server/mobile/auth.js +0 -150
- package/dist/embedding-server/mobile/daemon.d.ts +0 -129
- package/dist/embedding-server/mobile/daemon.js +0 -313
- package/dist/embedding-server/mobile/output-parser.d.ts +0 -115
- package/dist/embedding-server/mobile/output-parser.js +0 -241
- package/dist/embedding-server/mobile/session-api.d.ts +0 -57
- package/dist/embedding-server/mobile/session-api.js +0 -261
- package/dist/embedding-server/mobile/session-manager.d.ts +0 -138
- package/dist/embedding-server/mobile/session-manager.js +0 -378
- package/dist/embedding-server/mobile/websocket-handler.d.ts +0 -137
- package/dist/embedding-server/mobile/websocket-handler.js +0 -486
- package/dist/embeddings.d.ts +0 -68
- package/dist/embeddings.js +0 -244
- package/dist/entities/audit-metrics.d.ts +0 -68
- package/dist/entities/audit-metrics.js +0 -124
- package/dist/entities/candidate-generator.d.ts +0 -8
- package/dist/entities/candidate-generator.js +0 -24
- package/dist/entities/entity-linked-decision-counts.d.ts +0 -2
- package/dist/entities/entity-linked-decision-counts.js +0 -29
- package/dist/entities/entity-list.d.ts +0 -22
- package/dist/entities/entity-list.js +0 -3
- package/dist/entities/entity-orphan-list.d.ts +0 -17
- package/dist/entities/entity-orphan-list.js +0 -3
- package/dist/entities/entity-search.d.ts +0 -20
- package/dist/entities/entity-search.js +0 -3
- package/dist/entities/errors.d.ts +0 -55
- package/dist/entities/errors.js +0 -100
- package/dist/entities/lineage-store.d.ts +0 -28
- package/dist/entities/lineage-store.js +0 -204
- package/dist/entities/normalization.d.ts +0 -14
- package/dist/entities/normalization.js +0 -63
- package/dist/entities/policy-store.d.ts +0 -8
- package/dist/entities/policy-store.js +0 -75
- package/dist/entities/policy-types.d.ts +0 -72
- package/dist/entities/policy-types.js +0 -59
- package/dist/entities/projection.d.ts +0 -8
- package/dist/entities/projection.js +0 -82
- package/dist/entities/provenance-query.d.ts +0 -32
- package/dist/entities/provenance-query.js +0 -3
- package/dist/entities/read-identity.d.ts +0 -31
- package/dist/entities/read-identity.js +0 -264
- package/dist/entities/recall-bridge.d.ts +0 -5
- package/dist/entities/recall-bridge.js +0 -171
- package/dist/entities/resolution-engine.d.ts +0 -8
- package/dist/entities/resolution-engine.js +0 -3
- package/dist/entities/rollback-preview.d.ts +0 -35
- package/dist/entities/rollback-preview.js +0 -3
- package/dist/entities/source-locator.d.ts +0 -3
- package/dist/entities/source-locator.js +0 -32
- package/dist/entities/store.d.ts +0 -69
- package/dist/entities/store.js +0 -544
- package/dist/entities/types.d.ts +0 -166
- package/dist/entities/types.js +0 -30
- package/dist/memory/extraction-prompt.d.ts +0 -4
- package/dist/memory/extraction-prompt.js +0 -89
- package/dist/memory/scope-backfill.d.ts +0 -14
- package/dist/memory/scope-backfill.js +0 -3
- package/dist/memory/scope-store.d.ts +0 -4
- package/dist/memory/scope-store.js +0 -9
- package/dist/memory-store.d.ts +0 -87
- package/dist/memory-store.js +0 -78
- package/dist/model-runs/store.d.ts +0 -13
- package/dist/model-runs/tool-trace-store.d.ts +0 -8
- package/dist/notification-manager.d.ts +0 -7
- package/dist/notification-manager.js +0 -12
- package/dist/outcome-tracker.d.ts +0 -151
- package/dist/outcome-tracker.js +0 -271
- package/dist/query-intent.d.ts +0 -23
- package/dist/query-intent.js +0 -114
- package/dist/runtime/trusted-provenance.d.ts +0 -3
- package/dist/runtime/trusted-provenance.js +0 -6
- package/dist/search/question-type.d.ts +0 -5
- package/dist/search/question-type.js +0 -41
- package/dist/test-utils.d.ts +0 -80
- package/dist/test-utils.js +0 -218
- package/dist/tier-validator.d.ts +0 -43
- package/dist/tier-validator.js +0 -159
- package/dist/time-formatter.d.ts +0 -25
- package/dist/time-formatter.js +0 -93
- /package/dist/{search → knowledge}/feedback-store.d.ts +0 -0
- /package/dist/{search → knowledge}/feedback-store.js +0 -0
- /package/dist/{search → knowledge}/ranker-features.d.ts +0 -0
- /package/dist/{search → knowledge}/ranker-rescore.d.ts +0 -0
- /package/dist/{search → knowledge}/ranker-rescore.js +0 -0
- /package/dist/{search → knowledge}/ranker-trainer.d.ts +0 -0
- /package/dist/{search → knowledge}/ranker-trainer.js +0 -0
- /package/dist/{search → knowledge}/search-quality.js +0 -0
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Registry store: work items, people and clients as nodes with the names they go by.
|
|
4
|
+
*
|
|
5
|
+
* Identity used to live in strings such as task titles and decision topics, so alternate
|
|
6
|
+
* spellings could not join without an explicit durable identity.
|
|
7
|
+
*
|
|
8
|
+
* A node here is cheap: an id, a kind, a display name, and the aliases it answers to.
|
|
9
|
+
* What it buys is that a record can point at identity instead of spelling it.
|
|
10
|
+
*
|
|
11
|
+
* Two decisions this module refuses to make on its own:
|
|
12
|
+
* - It never merges by similarity. `mergeNodes` happens because a caller decided, and the
|
|
13
|
+
* reason is stored with it.
|
|
14
|
+
* - It never reassigns a contested alias. Claiming an alias another node holds raises, so
|
|
15
|
+
* the caller resolves it (merge, or pick a different alias) rather than the store
|
|
16
|
+
* silently moving identity from under existing records.
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.RegistryError = exports.REGISTRY_KINDS = void 0;
|
|
20
|
+
exports.currentIdentityRevision = currentIdentityRevision;
|
|
21
|
+
exports.rebuildRegistryProjections = rebuildRegistryProjections;
|
|
22
|
+
exports.normalizeAlias = normalizeAlias;
|
|
23
|
+
exports.createNode = createNode;
|
|
24
|
+
exports.addAliases = addAliases;
|
|
25
|
+
exports.upsertNode = upsertNode;
|
|
26
|
+
exports.addAlias = addAlias;
|
|
27
|
+
exports.resolveNodeById = resolveNodeById;
|
|
28
|
+
exports.resolveAlias = resolveAlias;
|
|
29
|
+
exports.resolveAliasCandidates = resolveAliasCandidates;
|
|
30
|
+
exports.listNodes = listNodes;
|
|
31
|
+
exports.mergeNodes = mergeNodes;
|
|
32
|
+
exports.splitNode = splitNode;
|
|
33
|
+
const node_crypto_1 = require("node:crypto");
|
|
34
|
+
const types_js_1 = require("./types.js");
|
|
35
|
+
Object.defineProperty(exports, "REGISTRY_KINDS", { enumerable: true, get: function () { return types_js_1.REGISTRY_KINDS; } });
|
|
36
|
+
class RegistryError extends Error {
|
|
37
|
+
code;
|
|
38
|
+
constructor(code, message) {
|
|
39
|
+
super(message);
|
|
40
|
+
this.code = code;
|
|
41
|
+
this.name = 'RegistryError';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
exports.RegistryError = RegistryError;
|
|
45
|
+
function currentIdentityRevision(adapter) {
|
|
46
|
+
const row = adapter
|
|
47
|
+
.prepare('SELECT revision FROM registry_identity_state WHERE singleton = 1')
|
|
48
|
+
.get();
|
|
49
|
+
if (!row || !Number.isSafeInteger(row.revision) || row.revision < 0) {
|
|
50
|
+
throw new Error('registry_identity_state is missing or malformed');
|
|
51
|
+
}
|
|
52
|
+
return row.revision;
|
|
53
|
+
}
|
|
54
|
+
function rebuildRegistryProjections(adapter) {
|
|
55
|
+
const revision = currentIdentityRevision(adapter);
|
|
56
|
+
const row = adapter
|
|
57
|
+
.prepare('SELECT MAX(committed_revision) AS revision FROM registry_corrections')
|
|
58
|
+
.get();
|
|
59
|
+
if ((row.revision ?? 0) !== revision) {
|
|
60
|
+
throw new Error('Registry correction projection revision is inconsistent');
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The lookup key for an alias: case-folded, inner runs of whitespace collapsed, trimmed.
|
|
65
|
+
*
|
|
66
|
+
* Deliberately conservative - it folds the differences that are the same string typed
|
|
67
|
+
* twice, and nothing else. Hyphens, underscores and script differences stay significant,
|
|
68
|
+
* because "a-0001" and "a_0001" being the same thing is a judgement about the work, not
|
|
69
|
+
* about text, and belongs in an alias row someone added.
|
|
70
|
+
*/
|
|
71
|
+
function normalizeAlias(value) {
|
|
72
|
+
return value.trim().replace(/\s+/g, ' ').toLowerCase();
|
|
73
|
+
}
|
|
74
|
+
function toNode(row) {
|
|
75
|
+
return {
|
|
76
|
+
id: row.id,
|
|
77
|
+
kind: row.kind,
|
|
78
|
+
name: row.name,
|
|
79
|
+
parentId: row.parent_id,
|
|
80
|
+
mergedInto: row.merged_into,
|
|
81
|
+
note: row.note,
|
|
82
|
+
createdAt: row.created_at,
|
|
83
|
+
updatedAt: row.updated_at,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function requireKind(kind) {
|
|
87
|
+
if (!types_js_1.REGISTRY_KINDS.includes(kind)) {
|
|
88
|
+
throw new RegistryError('invalid_kind', `Unknown registry kind: ${kind}`);
|
|
89
|
+
}
|
|
90
|
+
return kind;
|
|
91
|
+
}
|
|
92
|
+
function readNode(adapter, id) {
|
|
93
|
+
const row = adapter.prepare('SELECT * FROM registry_nodes WHERE id = ?').get(id);
|
|
94
|
+
return row ? toNode(row) : null;
|
|
95
|
+
}
|
|
96
|
+
function isNodeVisible(adapter, id, scopes) {
|
|
97
|
+
const bindings = adapter
|
|
98
|
+
.prepare('SELECT scope_kind AS kind, scope_id AS id FROM registry_scope_bindings WHERE node_id = ?')
|
|
99
|
+
.all(id);
|
|
100
|
+
if (bindings.length === 0) {
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
if (!scopes || scopes.length === 0) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
return scopes.some((scope) => bindings.some((binding) => binding.kind === scope.kind && binding.id === scope.id));
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Follow `merged_into` to the node that now holds this identity.
|
|
110
|
+
*
|
|
111
|
+
* Bounded: a cycle written by a bad merge would otherwise hang every lookup, so the walk
|
|
112
|
+
* stops and reports rather than spinning.
|
|
113
|
+
*/
|
|
114
|
+
function followMerges(adapter, id) {
|
|
115
|
+
let current = readNode(adapter, id);
|
|
116
|
+
for (let hops = 0; current?.mergedInto && hops < 8; hops += 1) {
|
|
117
|
+
current = readNode(adapter, current.mergedInto);
|
|
118
|
+
}
|
|
119
|
+
if (current?.mergedInto) {
|
|
120
|
+
throw new RegistryError('merge_chain_too_long', `Merge chain from ${id} does not settle`);
|
|
121
|
+
}
|
|
122
|
+
return current;
|
|
123
|
+
}
|
|
124
|
+
/** Write one alias row, or raise when another node already answers to it. */
|
|
125
|
+
function aliasScopes(scopes) {
|
|
126
|
+
return scopes && scopes.length > 0 ? scopes : [{ kind: 'global', id: '*' }];
|
|
127
|
+
}
|
|
128
|
+
function insertAlias(adapter, nodeId, kind, alias, now, scopes) {
|
|
129
|
+
const normalized = normalizeAlias(alias);
|
|
130
|
+
if (!normalized) {
|
|
131
|
+
throw new RegistryError('empty_alias', 'An alias must contain at least one character');
|
|
132
|
+
}
|
|
133
|
+
for (const scope of aliasScopes(scopes)) {
|
|
134
|
+
const existing = adapter
|
|
135
|
+
.prepare(`SELECT node_id FROM registry_aliases
|
|
136
|
+
WHERE kind = ? AND alias = ? AND scope_kind = ? AND scope_id = ?`)
|
|
137
|
+
.get(kind, normalized, scope.kind, scope.id);
|
|
138
|
+
if (existing) {
|
|
139
|
+
if (existing.node_id === nodeId) {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
throw new RegistryError('alias_taken', `Alias "${alias}" is already registered in this scope.`);
|
|
143
|
+
}
|
|
144
|
+
adapter
|
|
145
|
+
.prepare(`INSERT INTO registry_aliases
|
|
146
|
+
(node_id, kind, alias, alias_display, scope_kind, scope_id, created_at)
|
|
147
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`)
|
|
148
|
+
.run(nodeId, kind, normalized, alias.trim(), scope.kind, scope.id, now);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
function createNode(adapter, input) {
|
|
152
|
+
const write = () => {
|
|
153
|
+
const kind = requireKind(input.kind);
|
|
154
|
+
const name = input.name.trim();
|
|
155
|
+
if (!name) {
|
|
156
|
+
throw new RegistryError('empty_name', 'A registry node needs a name');
|
|
157
|
+
}
|
|
158
|
+
const id = `reg_${(0, node_crypto_1.randomUUID)().replace(/-/g, '').slice(0, 20)}`;
|
|
159
|
+
const now = Date.now();
|
|
160
|
+
adapter
|
|
161
|
+
.prepare(`INSERT INTO registry_nodes (id, kind, name, parent_id, merged_into, merge_reason, note, created_at, updated_at)
|
|
162
|
+
VALUES (?, ?, ?, ?, NULL, NULL, ?, ?, ?)`)
|
|
163
|
+
.run(id, kind, name, input.parentId ?? null, input.note ?? null, now, now);
|
|
164
|
+
// The name is an alias too: asking for a node by the name it displays must work.
|
|
165
|
+
insertAlias(adapter, id, kind, name, now, input.scopes);
|
|
166
|
+
for (const alias of input.aliases ?? []) {
|
|
167
|
+
insertAlias(adapter, id, kind, alias, now, input.scopes);
|
|
168
|
+
}
|
|
169
|
+
for (const scope of input.scopes ?? []) {
|
|
170
|
+
if (!scope.id.trim()) {
|
|
171
|
+
throw new RegistryError('invalid_scope', 'Registry scope id must be nonblank');
|
|
172
|
+
}
|
|
173
|
+
adapter
|
|
174
|
+
.prepare(`INSERT INTO registry_scope_bindings (node_id, scope_kind, scope_id)
|
|
175
|
+
VALUES (?, ?, ?)`)
|
|
176
|
+
.run(id, scope.kind, scope.id);
|
|
177
|
+
}
|
|
178
|
+
return id;
|
|
179
|
+
};
|
|
180
|
+
return adapter.transaction(write);
|
|
181
|
+
}
|
|
182
|
+
function addAliases(adapter, nodeId, aliases, scopes) {
|
|
183
|
+
const write = () => {
|
|
184
|
+
if (scopes === undefined) {
|
|
185
|
+
for (const alias of aliases) {
|
|
186
|
+
addAlias(adapter, nodeId, alias);
|
|
187
|
+
}
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const node = readNode(adapter, nodeId);
|
|
191
|
+
if (!node || node.mergedInto) {
|
|
192
|
+
throw new RegistryError('unknown_node', 'Registry node unavailable');
|
|
193
|
+
}
|
|
194
|
+
for (const alias of aliases) {
|
|
195
|
+
insertAlias(adapter, nodeId, node.kind, alias, Date.now(), scopes);
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
adapter.transaction(write);
|
|
199
|
+
}
|
|
200
|
+
function upsertNode(adapter, input) {
|
|
201
|
+
const write = () => {
|
|
202
|
+
const existing = resolveAlias(adapter, input.name, input.kind, input.scopes);
|
|
203
|
+
if (existing) {
|
|
204
|
+
if (input.children && input.children.length > 0) {
|
|
205
|
+
throw new RegistryError('existing_children_unsupported', 'Adding children to an existing node requires an explicit correction.');
|
|
206
|
+
}
|
|
207
|
+
addAliases(adapter, existing.id, input.aliases ?? [], input.scopes);
|
|
208
|
+
return { id: existing.id, created: false, children: [] };
|
|
209
|
+
}
|
|
210
|
+
const id = createNode(adapter, input);
|
|
211
|
+
const children = input.children && input.children.length > 0
|
|
212
|
+
? splitNode(adapter, {
|
|
213
|
+
parent: id,
|
|
214
|
+
children: input.children,
|
|
215
|
+
reason: input.note?.trim() || 'explicit parent declaration',
|
|
216
|
+
})
|
|
217
|
+
: [];
|
|
218
|
+
return { id, created: true, children };
|
|
219
|
+
};
|
|
220
|
+
return adapter.transaction(write);
|
|
221
|
+
}
|
|
222
|
+
function addAlias(adapter, nodeId, alias) {
|
|
223
|
+
const node = readNode(adapter, nodeId);
|
|
224
|
+
if (!node) {
|
|
225
|
+
throw new RegistryError('unknown_node', `No registry node ${nodeId}`);
|
|
226
|
+
}
|
|
227
|
+
if (node.mergedInto) {
|
|
228
|
+
throw new RegistryError('node_merged', `Node ${nodeId} was merged into ${node.mergedInto}; add the alias there`);
|
|
229
|
+
}
|
|
230
|
+
const scopes = adapter
|
|
231
|
+
.prepare('SELECT scope_kind AS kind, scope_id AS id FROM registry_scope_bindings WHERE node_id = ?')
|
|
232
|
+
.all(nodeId);
|
|
233
|
+
insertAlias(adapter, nodeId, node.kind, alias, Date.now(), scopes);
|
|
234
|
+
}
|
|
235
|
+
/** The live node behind an id, following merges. Null when the id is unknown. */
|
|
236
|
+
function resolveNodeById(adapter, id) {
|
|
237
|
+
return followMerges(adapter, id);
|
|
238
|
+
}
|
|
239
|
+
/** The node an alias names, following merges. `kind` narrows when the same word is both. */
|
|
240
|
+
function resolveAlias(adapter, alias, kind, scopes) {
|
|
241
|
+
const candidates = resolveAliasCandidates(adapter, alias, { kind, scopes });
|
|
242
|
+
if (candidates.length > 1) {
|
|
243
|
+
throw new RegistryError('alias_ambiguous', 'Alias resolves to multiple visible nodes.');
|
|
244
|
+
}
|
|
245
|
+
return candidates[0] ?? null;
|
|
246
|
+
}
|
|
247
|
+
function resolveAliasCandidates(adapter, alias, options) {
|
|
248
|
+
const normalized = normalizeAlias(alias);
|
|
249
|
+
if (!normalized) {
|
|
250
|
+
return [];
|
|
251
|
+
}
|
|
252
|
+
const admitted = options?.scopes && options.scopes.length > 0
|
|
253
|
+
? options.scopes
|
|
254
|
+
: [{ kind: 'global', id: '*' }];
|
|
255
|
+
const whereKind = options?.kind ? 'kind = ? AND' : '';
|
|
256
|
+
const rows = adapter
|
|
257
|
+
.prepare(`SELECT node_id, alias_display FROM registry_aliases
|
|
258
|
+
WHERE ${whereKind} alias = ?
|
|
259
|
+
AND ((scope_kind = 'global' AND scope_id = '*')
|
|
260
|
+
OR (scope_kind || ':' || scope_id) IN (${admitted.map(() => '?').join(', ')}))
|
|
261
|
+
ORDER BY created_at, rowid`)
|
|
262
|
+
.all(...(options?.kind ? [requireKind(options.kind)] : []), normalized, ...admitted.map((scope) => `${scope.kind}:${scope.id}`));
|
|
263
|
+
const visible = rows
|
|
264
|
+
.map((row) => {
|
|
265
|
+
const node = followMerges(adapter, row.node_id);
|
|
266
|
+
if (!node || !isNodeVisible(adapter, node.id, admitted)) {
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
269
|
+
const canonicalVisible = adapter
|
|
270
|
+
.prepare(`SELECT 1 FROM registry_aliases
|
|
271
|
+
WHERE node_id = ? AND alias = ?
|
|
272
|
+
AND ((scope_kind = 'global' AND scope_id = '*')
|
|
273
|
+
OR (scope_kind || ':' || scope_id) IN (${admitted.map(() => '?').join(', ')}))
|
|
274
|
+
LIMIT 1`)
|
|
275
|
+
.get(node.id, normalizeAlias(node.name), ...admitted.map((scope) => `${scope.kind}:${scope.id}`));
|
|
276
|
+
return { ...node, name: canonicalVisible ? node.name : row.alias_display };
|
|
277
|
+
})
|
|
278
|
+
.filter((node) => node !== null);
|
|
279
|
+
const unique = [...new Map(visible.map((node) => [node.id, node])).values()];
|
|
280
|
+
return unique;
|
|
281
|
+
}
|
|
282
|
+
function listNodes(adapter, filter) {
|
|
283
|
+
const where = [];
|
|
284
|
+
const params = [];
|
|
285
|
+
if (filter?.kind) {
|
|
286
|
+
where.push('kind = ?');
|
|
287
|
+
params.push(requireKind(filter.kind));
|
|
288
|
+
}
|
|
289
|
+
if (filter?.parentId !== undefined) {
|
|
290
|
+
if (filter.parentId === null) {
|
|
291
|
+
where.push('parent_id IS NULL');
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
where.push('parent_id = ?');
|
|
295
|
+
params.push(filter.parentId);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if (filter?.includeMerged !== true) {
|
|
299
|
+
where.push('merged_into IS NULL');
|
|
300
|
+
}
|
|
301
|
+
if (filter?.scopes && filter.scopes.length > 0) {
|
|
302
|
+
where.push(`(NOT EXISTS (SELECT 1 FROM registry_scope_bindings rs WHERE rs.node_id = registry_nodes.id)
|
|
303
|
+
OR EXISTS (
|
|
304
|
+
SELECT 1 FROM registry_scope_bindings rs
|
|
305
|
+
WHERE rs.node_id = registry_nodes.id
|
|
306
|
+
AND (rs.scope_kind || ':' || rs.scope_id) IN (${filter.scopes.map(() => '?').join(', ')})
|
|
307
|
+
))`);
|
|
308
|
+
params.push(...filter.scopes.map((scope) => `${scope.kind}:${scope.id}`));
|
|
309
|
+
}
|
|
310
|
+
// rowid, not id: a split writes its children inside one millisecond, so `created_at`
|
|
311
|
+
// alone would order them by random uuid and report the parts in the wrong order.
|
|
312
|
+
const sql = `SELECT * FROM registry_nodes${where.length ? ` WHERE ${where.join(' AND ')}` : ''} ORDER BY created_at, rowid`;
|
|
313
|
+
return adapter.prepare(sql).all(...params).map(toNode);
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Point one node's identity at another. The loser keeps its row as a tombstone so records
|
|
317
|
+
* that still reference it resolve forward instead of dangling.
|
|
318
|
+
*/
|
|
319
|
+
function mergeNodes(adapter, input) {
|
|
320
|
+
if (input.loser === input.survivor) {
|
|
321
|
+
throw new RegistryError('merge_self', 'A node cannot merge into itself');
|
|
322
|
+
}
|
|
323
|
+
const loser = readNode(adapter, input.loser);
|
|
324
|
+
const survivor = readNode(adapter, input.survivor);
|
|
325
|
+
if (!loser) {
|
|
326
|
+
throw new RegistryError('unknown_node', `No registry node ${input.loser}`);
|
|
327
|
+
}
|
|
328
|
+
if (loser.mergedInto) {
|
|
329
|
+
throw new RegistryError('loser_merged', `Node ${input.loser} was already merged`);
|
|
330
|
+
}
|
|
331
|
+
if (!survivor) {
|
|
332
|
+
throw new RegistryError('unknown_node', `No registry node ${input.survivor}`);
|
|
333
|
+
}
|
|
334
|
+
if (survivor.mergedInto) {
|
|
335
|
+
throw new RegistryError('survivor_merged', `Node ${input.survivor} was itself merged into ${survivor.mergedInto}`);
|
|
336
|
+
}
|
|
337
|
+
if (loser.kind !== survivor.kind) {
|
|
338
|
+
throw new RegistryError('kind_mismatch', `Cannot merge ${loser.kind} into ${survivor.kind}`);
|
|
339
|
+
}
|
|
340
|
+
const reason = input.reason.trim();
|
|
341
|
+
if (!reason) {
|
|
342
|
+
throw new RegistryError('missing_reason', 'A merge must record why');
|
|
343
|
+
}
|
|
344
|
+
const now = Date.now();
|
|
345
|
+
// Aliases move rather than duplicate: (kind, alias) is unique, and the loser's rows are
|
|
346
|
+
// exactly the spellings that must now reach the survivor.
|
|
347
|
+
adapter.transaction(() => {
|
|
348
|
+
adapter
|
|
349
|
+
.prepare(`INSERT OR IGNORE INTO registry_scope_bindings (node_id, scope_kind, scope_id)
|
|
350
|
+
SELECT ?, scope_kind, scope_id FROM registry_scope_bindings WHERE node_id = ?`)
|
|
351
|
+
.run(input.survivor, input.loser);
|
|
352
|
+
adapter
|
|
353
|
+
.prepare('UPDATE registry_aliases SET node_id = ? WHERE node_id = ?')
|
|
354
|
+
.run(input.survivor, input.loser);
|
|
355
|
+
adapter
|
|
356
|
+
.prepare('UPDATE registry_nodes SET merged_into = ?, merge_reason = ?, updated_at = ? WHERE id = ?')
|
|
357
|
+
.run(input.survivor, reason, now, input.loser);
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Split one item into the children it really covers, keeping the parent as the umbrella.
|
|
362
|
+
*
|
|
363
|
+
* Nothing is deleted: the parent stays resolvable by its own aliases, and existing records
|
|
364
|
+
* keep pointing at it until someone decides which child they belong to.
|
|
365
|
+
*/
|
|
366
|
+
function splitNode(adapter, input) {
|
|
367
|
+
const write = () => {
|
|
368
|
+
const parent = readNode(adapter, input.parent);
|
|
369
|
+
if (!parent) {
|
|
370
|
+
throw new RegistryError('unknown_node', `No registry node ${input.parent}`);
|
|
371
|
+
}
|
|
372
|
+
if (parent.mergedInto) {
|
|
373
|
+
throw new RegistryError('node_merged', `Node ${input.parent} was merged away`);
|
|
374
|
+
}
|
|
375
|
+
if (input.children.length < 2) {
|
|
376
|
+
throw new RegistryError('split_too_small', 'A split needs at least two children');
|
|
377
|
+
}
|
|
378
|
+
if (!input.reason.trim()) {
|
|
379
|
+
throw new RegistryError('missing_reason', 'A split must record why');
|
|
380
|
+
}
|
|
381
|
+
const parentScopes = adapter
|
|
382
|
+
.prepare('SELECT scope_kind AS kind, scope_id AS id FROM registry_scope_bindings WHERE node_id = ?')
|
|
383
|
+
.all(parent.id);
|
|
384
|
+
return input.children.map((child) => createNode(adapter, {
|
|
385
|
+
kind: parent.kind,
|
|
386
|
+
name: child.name,
|
|
387
|
+
aliases: child.aliases,
|
|
388
|
+
parentId: parent.id,
|
|
389
|
+
note: input.reason.trim(),
|
|
390
|
+
scopes: parentScopes,
|
|
391
|
+
}));
|
|
392
|
+
};
|
|
393
|
+
return adapter.transaction(write);
|
|
394
|
+
}
|
|
395
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export declare const REGISTRY_KINDS: readonly ["item", "person", "client"];
|
|
2
|
+
export type RegistryKind = (typeof REGISTRY_KINDS)[number];
|
|
3
|
+
export interface RegistryNode {
|
|
4
|
+
id: string;
|
|
5
|
+
kind: RegistryKind;
|
|
6
|
+
name: string;
|
|
7
|
+
parentId: string | null;
|
|
8
|
+
mergedInto: string | null;
|
|
9
|
+
note: string | null;
|
|
10
|
+
createdAt: number;
|
|
11
|
+
updatedAt: number;
|
|
12
|
+
}
|
|
13
|
+
export interface RecordActor {
|
|
14
|
+
personId: string;
|
|
15
|
+
role: string;
|
|
16
|
+
}
|
|
17
|
+
export interface RecordIdentity {
|
|
18
|
+
itemId: string | null;
|
|
19
|
+
}
|
|
20
|
+
export interface RegistryScopeRef {
|
|
21
|
+
/**
|
|
22
|
+
* The consumer's word for what kind of scope this is. The core matches it; it
|
|
23
|
+
* does not read it. Closed lists of kinds used to live here, in three copies.
|
|
24
|
+
*/
|
|
25
|
+
kind: string;
|
|
26
|
+
id: string;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=types.d.ts.map
|
package/dist/relevance-scorer.js
CHANGED
|
@@ -14,7 +14,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
14
14
|
exports.calculateRelevance = calculateRelevance;
|
|
15
15
|
exports.selectTopDecisions = selectTopDecisions;
|
|
16
16
|
exports.formatTopNContext = formatTopNContext;
|
|
17
|
-
const
|
|
17
|
+
const embedder_js_1 = require("./embedding/embedder.js");
|
|
18
18
|
/**
|
|
19
19
|
* Outcome weights for importance scoring
|
|
20
20
|
*/
|
|
@@ -70,7 +70,7 @@ function calculateRelevance(decision, queryContext) {
|
|
|
70
70
|
let semanticScore = 0;
|
|
71
71
|
if (decision.embedding && queryContext.embedding) {
|
|
72
72
|
// Task 1.3: Use cosine similarity function
|
|
73
|
-
semanticScore = (0,
|
|
73
|
+
semanticScore = (0, embedder_js_1.cosineSimilarity)(decision.embedding, queryContext.embedding);
|
|
74
74
|
}
|
|
75
75
|
else {
|
|
76
76
|
// Fallback: no semantic match if embeddings missing
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export interface AgentNotice {
|
|
2
|
+
agent: string;
|
|
3
|
+
action: string;
|
|
4
|
+
target: string;
|
|
5
|
+
timestamp: number;
|
|
6
|
+
}
|
|
7
|
+
export type AgentEvent = {
|
|
8
|
+
type: 'memory:saved';
|
|
9
|
+
topic: string;
|
|
10
|
+
project?: string;
|
|
11
|
+
} | {
|
|
12
|
+
type: 'extraction:completed';
|
|
13
|
+
projects: string[];
|
|
14
|
+
} | {
|
|
15
|
+
type: 'memory:promoted';
|
|
16
|
+
saved: number;
|
|
17
|
+
} | {
|
|
18
|
+
type: 'wiki:compiled';
|
|
19
|
+
pages: string[];
|
|
20
|
+
} | {
|
|
21
|
+
type: 'dashboard:refresh';
|
|
22
|
+
} | {
|
|
23
|
+
type: 'agent:action';
|
|
24
|
+
agent: string;
|
|
25
|
+
action: string;
|
|
26
|
+
target: string;
|
|
27
|
+
};
|
|
28
|
+
export type AgentEventType = AgentEvent['type'];
|
|
29
|
+
type EventHandler = (event: AgentEvent) => void | Promise<void>;
|
|
30
|
+
export declare class AgentEventBus {
|
|
31
|
+
static readonly MAX_NOTICES = 50;
|
|
32
|
+
private listeners;
|
|
33
|
+
private debounceTimers;
|
|
34
|
+
private listenerDebounceTimers;
|
|
35
|
+
private notices;
|
|
36
|
+
on(type: AgentEventType, handler: EventHandler): void;
|
|
37
|
+
off(type: AgentEventType, handler: EventHandler): void;
|
|
38
|
+
emit(event: AgentEvent): void;
|
|
39
|
+
emitDebounced(event: AgentEvent, delayMs: number): void;
|
|
40
|
+
/**
|
|
41
|
+
* Register a handler whose invocation is trailing-edge debounced: rapid
|
|
42
|
+
* successive events collapse into one call with the LAST event after
|
|
43
|
+
* delayMs of quiet. Pending invocations are cancelled by destroy().
|
|
44
|
+
*/
|
|
45
|
+
onDebounced(type: AgentEventType, handler: EventHandler, delayMs: number): void;
|
|
46
|
+
getRecentNotices(limit: number): AgentNotice[];
|
|
47
|
+
destroy(): void;
|
|
48
|
+
}
|
|
49
|
+
export {};
|
|
50
|
+
//# sourceMappingURL=agent-event-bus.d.ts.map
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AgentEventBus = void 0;
|
|
4
|
+
class AgentEventBus {
|
|
5
|
+
static MAX_NOTICES = 50;
|
|
6
|
+
listeners = new Map();
|
|
7
|
+
debounceTimers = new Map();
|
|
8
|
+
listenerDebounceTimers = new Set();
|
|
9
|
+
notices = [];
|
|
10
|
+
on(type, handler) {
|
|
11
|
+
if (!this.listeners.has(type)) {
|
|
12
|
+
this.listeners.set(type, new Set());
|
|
13
|
+
}
|
|
14
|
+
this.listeners.get(type).add(handler);
|
|
15
|
+
}
|
|
16
|
+
off(type, handler) {
|
|
17
|
+
this.listeners.get(type)?.delete(handler);
|
|
18
|
+
}
|
|
19
|
+
emit(event) {
|
|
20
|
+
const handlers = this.listeners.get(event.type);
|
|
21
|
+
if (handlers) {
|
|
22
|
+
for (const handler of handlers) {
|
|
23
|
+
try {
|
|
24
|
+
const result = handler(event);
|
|
25
|
+
if (result && typeof result.catch === 'function') {
|
|
26
|
+
result.catch((err) => console.error(`[EventBus] Handler error for ${event.type}:`, err));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
console.error(`[EventBus] Sync handler error for ${event.type}:`, err);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (event.type === 'agent:action') {
|
|
35
|
+
this.notices.unshift({
|
|
36
|
+
agent: event.agent,
|
|
37
|
+
action: event.action,
|
|
38
|
+
target: event.target,
|
|
39
|
+
timestamp: Date.now(),
|
|
40
|
+
});
|
|
41
|
+
if (this.notices.length > AgentEventBus.MAX_NOTICES) {
|
|
42
|
+
this.notices.length = AgentEventBus.MAX_NOTICES;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
emitDebounced(event, delayMs) {
|
|
47
|
+
const existing = this.debounceTimers.get(event.type);
|
|
48
|
+
if (existing)
|
|
49
|
+
clearTimeout(existing);
|
|
50
|
+
this.debounceTimers.set(event.type, setTimeout(() => {
|
|
51
|
+
this.debounceTimers.delete(event.type);
|
|
52
|
+
this.emit(event);
|
|
53
|
+
}, delayMs));
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Register a handler whose invocation is trailing-edge debounced: rapid
|
|
57
|
+
* successive events collapse into one call with the LAST event after
|
|
58
|
+
* delayMs of quiet. Pending invocations are cancelled by destroy().
|
|
59
|
+
*/
|
|
60
|
+
onDebounced(type, handler, delayMs) {
|
|
61
|
+
let timer = null;
|
|
62
|
+
this.on(type, (event) => {
|
|
63
|
+
if (timer) {
|
|
64
|
+
clearTimeout(timer);
|
|
65
|
+
this.listenerDebounceTimers.delete(timer);
|
|
66
|
+
}
|
|
67
|
+
const scheduled = setTimeout(() => {
|
|
68
|
+
this.listenerDebounceTimers.delete(scheduled);
|
|
69
|
+
timer = null;
|
|
70
|
+
try {
|
|
71
|
+
const result = handler(event);
|
|
72
|
+
if (result && typeof result.catch === 'function') {
|
|
73
|
+
result.catch((err) => console.error(`[EventBus] Debounced handler error for ${type}:`, err));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
console.error(`[EventBus] Debounced handler error for ${type}:`, err);
|
|
78
|
+
}
|
|
79
|
+
}, delayMs);
|
|
80
|
+
timer = scheduled;
|
|
81
|
+
this.listenerDebounceTimers.add(scheduled);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
getRecentNotices(limit) {
|
|
85
|
+
return this.notices.slice(0, limit);
|
|
86
|
+
}
|
|
87
|
+
destroy() {
|
|
88
|
+
for (const timer of this.debounceTimers.values()) {
|
|
89
|
+
clearTimeout(timer);
|
|
90
|
+
}
|
|
91
|
+
this.debounceTimers.clear();
|
|
92
|
+
for (const timer of this.listenerDebounceTimers.values()) {
|
|
93
|
+
clearTimeout(timer);
|
|
94
|
+
}
|
|
95
|
+
this.listenerDebounceTimers.clear();
|
|
96
|
+
this.listeners.clear();
|
|
97
|
+
this.notices.length = 0;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
exports.AgentEventBus = AgentEventBus;
|
|
101
|
+
//# sourceMappingURL=agent-event-bus.js.map
|