@askdkc/kiokuko 0.1.16 → 0.1.19
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.ja.md +91 -112
- package/README.ko.md +90 -102
- package/README.md +103 -260
- package/README.zh-CN.md +88 -102
- package/dist/agent-file/atomic-write.d.ts +90 -3
- package/dist/agent-file/atomic-write.d.ts.map +1 -1
- package/dist/agent-file/atomic-write.js +990 -14
- package/dist/agent-file/atomic-write.js.map +1 -1
- package/dist/agent-file/managed-block.d.ts +12 -1
- package/dist/agent-file/managed-block.d.ts.map +1 -1
- package/dist/agent-file/managed-block.js +49 -4
- package/dist/agent-file/managed-block.js.map +1 -1
- package/dist/agent-file/render.d.ts +1 -1
- package/dist/agent-file/render.d.ts.map +1 -1
- package/dist/agent-file/render.js +10 -7
- package/dist/agent-file/render.js.map +1 -1
- package/dist/akinator/agent-task.d.ts +14 -24
- package/dist/akinator/agent-task.d.ts.map +1 -1
- package/dist/akinator/agent-task.js +460 -103
- package/dist/akinator/agent-task.js.map +1 -1
- package/dist/akinator/capabilities.d.ts +52 -7
- package/dist/akinator/capabilities.d.ts.map +1 -1
- package/dist/akinator/capabilities.js +226 -28
- package/dist/akinator/capabilities.js.map +1 -1
- package/dist/akinator/capability-binding.d.ts +11 -0
- package/dist/akinator/capability-binding.d.ts.map +1 -0
- package/dist/akinator/capability-binding.js +56 -0
- package/dist/akinator/capability-binding.js.map +1 -0
- package/dist/akinator/domain.js +2 -2
- package/dist/akinator/domain.js.map +1 -1
- package/dist/akinator/knowledge-path.d.ts.map +1 -1
- package/dist/akinator/knowledge-path.js +409 -39
- package/dist/akinator/knowledge-path.js.map +1 -1
- package/dist/akinator/orchestrator.d.ts +3 -4
- package/dist/akinator/orchestrator.d.ts.map +1 -1
- package/dist/akinator/orchestrator.js +1 -4
- package/dist/akinator/orchestrator.js.map +1 -1
- package/dist/akinator/service.d.ts +0 -4
- package/dist/akinator/service.d.ts.map +1 -1
- package/dist/akinator/service.js +19 -35
- package/dist/akinator/service.js.map +1 -1
- package/dist/akinator/skill-discovery-attempt.d.ts +20 -0
- package/dist/akinator/skill-discovery-attempt.d.ts.map +1 -0
- package/dist/akinator/skill-discovery-attempt.js +390 -0
- package/dist/akinator/skill-discovery-attempt.js.map +1 -0
- package/dist/akinator/store.d.ts.map +1 -1
- package/dist/akinator/store.js +107 -52
- package/dist/akinator/store.js.map +1 -1
- package/dist/akinator/types.d.ts +0 -12
- package/dist/akinator/types.d.ts.map +1 -1
- package/dist/bin/kiokuko.js +0 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +561 -144
- package/dist/cli.js.map +1 -1
- package/dist/client/server-client.d.ts +5 -3
- package/dist/client/server-client.d.ts.map +1 -1
- package/dist/client/server-client.js +486 -181
- package/dist/client/server-client.js.map +1 -1
- package/dist/commands/agent.d.ts +2 -0
- package/dist/commands/agent.d.ts.map +1 -1
- package/dist/commands/agent.js +861 -86
- package/dist/commands/agent.js.map +1 -1
- package/dist/commands/backup.d.ts +2 -1
- package/dist/commands/backup.d.ts.map +1 -1
- package/dist/commands/backup.js +64 -8
- package/dist/commands/backup.js.map +1 -1
- package/dist/commands/doctor.d.ts +5 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +70 -26
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/export.d.ts +0 -4
- package/dist/commands/export.d.ts.map +1 -1
- package/dist/commands/export.js +191 -32
- package/dist/commands/export.js.map +1 -1
- package/dist/commands/import.d.ts +10 -1
- package/dist/commands/import.d.ts.map +1 -1
- package/dist/commands/import.js +592 -113
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/init.d.ts +19 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +569 -22
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/purge.d.ts.map +1 -1
- package/dist/commands/purge.js +3 -0
- package/dist/commands/purge.js.map +1 -1
- package/dist/commands/setup.d.ts +34 -8
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +418 -86
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/skills.d.ts +9 -0
- package/dist/commands/skills.d.ts.map +1 -0
- package/dist/commands/skills.js +317 -0
- package/dist/commands/skills.js.map +1 -0
- package/dist/commands/use.d.ts +10 -2
- package/dist/commands/use.d.ts.map +1 -1
- package/dist/commands/use.js +851 -73
- package/dist/commands/use.js.map +1 -1
- package/dist/config/paths.d.ts +11 -1
- package/dist/config/paths.d.ts.map +1 -1
- package/dist/config/paths.js +64 -29
- package/dist/config/paths.js.map +1 -1
- package/dist/config/project-config.d.ts +1 -0
- package/dist/config/project-config.d.ts.map +1 -1
- package/dist/config/project-config.js +70 -32
- package/dist/config/project-config.js.map +1 -1
- package/dist/context/broker.d.ts +30 -14
- package/dist/context/broker.d.ts.map +1 -1
- package/dist/context/broker.js +628 -150
- package/dist/context/broker.js.map +1 -1
- package/dist/context/delivery.d.ts +8 -22
- package/dist/context/delivery.d.ts.map +1 -1
- package/dist/context/delivery.js +204 -152
- package/dist/context/delivery.js.map +1 -1
- package/dist/context/feedback.d.ts +11 -12
- package/dist/context/feedback.d.ts.map +1 -1
- package/dist/context/feedback.js +250 -268
- package/dist/context/feedback.js.map +1 -1
- package/dist/context/origin.d.ts +9 -0
- package/dist/context/origin.d.ts.map +1 -0
- package/dist/context/origin.js +15 -0
- package/dist/context/origin.js.map +1 -0
- package/dist/context/ranking.d.ts +4 -13
- package/dist/context/ranking.d.ts.map +1 -1
- package/dist/context/ranking.js +21 -5
- package/dist/context/ranking.js.map +1 -1
- package/dist/context/recommendations.d.ts +0 -5
- package/dist/context/recommendations.d.ts.map +1 -1
- package/dist/context/recommendations.js +0 -1
- package/dist/context/recommendations.js.map +1 -1
- package/dist/context/run-state.d.ts +26 -0
- package/dist/context/run-state.d.ts.map +1 -0
- package/dist/context/run-state.js +399 -0
- package/dist/context/run-state.js.map +1 -0
- package/dist/context/scoped-broker.d.ts +19 -6
- package/dist/context/scoped-broker.d.ts.map +1 -1
- package/dist/context/scoped-broker.js +530 -131
- package/dist/context/scoped-broker.js.map +1 -1
- package/dist/context/selection-state.d.ts +19 -0
- package/dist/context/selection-state.d.ts.map +1 -0
- package/dist/context/selection-state.js +250 -0
- package/dist/context/selection-state.js.map +1 -0
- package/dist/db/adapter.d.ts +5 -3
- package/dist/db/adapter.d.ts.map +1 -1
- package/dist/db/adapter.js +6 -3
- package/dist/db/adapter.js.map +1 -1
- package/dist/db/capabilities.d.ts.map +1 -1
- package/dist/db/capabilities.js +34 -16
- package/dist/db/capabilities.js.map +1 -1
- package/dist/db/connection.d.ts +8 -0
- package/dist/db/connection.d.ts.map +1 -1
- package/dist/db/connection.js +55 -26
- package/dist/db/connection.js.map +1 -1
- package/dist/db/migrate.d.ts +28 -7
- package/dist/db/migrate.d.ts.map +1 -1
- package/dist/db/migrate.js +106 -78
- package/dist/db/migrate.js.map +1 -1
- package/dist/db/sqlite-retry.d.ts +11 -0
- package/dist/db/sqlite-retry.d.ts.map +1 -0
- package/dist/db/sqlite-retry.js +66 -0
- package/dist/db/sqlite-retry.js.map +1 -0
- package/dist/db/transaction.d.ts +13 -0
- package/dist/db/transaction.d.ts.map +1 -1
- package/dist/db/transaction.js +53 -24
- package/dist/db/transaction.js.map +1 -1
- package/dist/db/upgrade-backup.d.ts +58 -2
- package/dist/db/upgrade-backup.d.ts.map +1 -1
- package/dist/db/upgrade-backup.js +757 -28
- package/dist/db/upgrade-backup.js.map +1 -1
- package/dist/errors.js +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/gateway/agent-service.d.ts +4 -1
- package/dist/gateway/agent-service.d.ts.map +1 -1
- package/dist/gateway/agent-service.js +71 -58
- package/dist/gateway/agent-service.js.map +1 -1
- package/dist/gateway/checkpoint-service.d.ts +1 -0
- package/dist/gateway/checkpoint-service.d.ts.map +1 -1
- package/dist/gateway/checkpoint-service.js +47 -24
- package/dist/gateway/checkpoint-service.js.map +1 -1
- package/dist/ledger/archive.d.ts +1 -4
- package/dist/ledger/archive.d.ts.map +1 -1
- package/dist/ledger/archive.js +134 -54
- package/dist/ledger/archive.js.map +1 -1
- package/dist/ledger/maintenance.d.ts +0 -11
- package/dist/ledger/maintenance.d.ts.map +1 -1
- package/dist/ledger/maintenance.js +41 -44
- package/dist/ledger/maintenance.js.map +1 -1
- package/dist/ledger/projection.d.ts +0 -1
- package/dist/ledger/projection.d.ts.map +1 -1
- package/dist/ledger/projection.js.map +1 -1
- package/dist/ledger/promotion.d.ts +0 -9
- package/dist/ledger/promotion.d.ts.map +1 -1
- package/dist/ledger/promotion.js.map +1 -1
- package/dist/ledger/query.d.ts +1 -15
- package/dist/ledger/query.d.ts.map +1 -1
- package/dist/ledger/query.js.map +1 -1
- package/dist/ledger/store.d.ts +0 -1
- package/dist/ledger/store.d.ts.map +1 -1
- package/dist/ledger/store.js +11 -8
- package/dist/ledger/store.js.map +1 -1
- package/dist/ledger/types.d.ts +0 -4
- package/dist/ledger/types.d.ts.map +1 -1
- package/dist/ledger/types.js.map +1 -1
- package/dist/ledger/validate.d.ts.map +1 -1
- package/dist/ledger/validate.js +0 -5
- package/dist/ledger/validate.js.map +1 -1
- package/dist/mcp/bounded-stdio-transport.d.ts +23 -0
- package/dist/mcp/bounded-stdio-transport.d.ts.map +1 -0
- package/dist/mcp/bounded-stdio-transport.js +109 -0
- package/dist/mcp/bounded-stdio-transport.js.map +1 -0
- package/dist/mcp/server.d.ts +4 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +111 -75
- package/dist/mcp/server.js.map +1 -1
- package/dist/memory/audit.d.ts +0 -1
- package/dist/memory/audit.d.ts.map +1 -1
- package/dist/memory/audit.js +0 -1
- package/dist/memory/audit.js.map +1 -1
- package/dist/memory/curator.d.ts +45 -1
- package/dist/memory/curator.d.ts.map +1 -1
- package/dist/memory/curator.js +290 -68
- package/dist/memory/curator.js.map +1 -1
- package/dist/memory/entries.d.ts +12 -2
- package/dist/memory/entries.d.ts.map +1 -1
- package/dist/memory/entries.js +198 -114
- package/dist/memory/entries.js.map +1 -1
- package/dist/memory/federated-retrieval.d.ts +78 -0
- package/dist/memory/federated-retrieval.d.ts.map +1 -0
- package/dist/memory/federated-retrieval.js +441 -0
- package/dist/memory/federated-retrieval.js.map +1 -0
- package/dist/memory/hybrid-retrieval.d.ts +5 -11
- package/dist/memory/hybrid-retrieval.d.ts.map +1 -1
- package/dist/memory/hybrid-retrieval.js +78 -58
- package/dist/memory/hybrid-retrieval.js.map +1 -1
- package/dist/memory/lifecycle.d.ts.map +1 -1
- package/dist/memory/lifecycle.js +17 -13
- package/dist/memory/lifecycle.js.map +1 -1
- package/dist/memory/portability.d.ts +10 -0
- package/dist/memory/portability.d.ts.map +1 -0
- package/dist/memory/portability.js +44 -0
- package/dist/memory/portability.js.map +1 -0
- package/dist/memory/rebuild-search.d.ts +5 -0
- package/dist/memory/rebuild-search.d.ts.map +1 -1
- package/dist/memory/rebuild-search.js +101 -76
- package/dist/memory/rebuild-search.js.map +1 -1
- package/dist/memory/retrieval-query.d.ts +0 -5
- package/dist/memory/retrieval-query.d.ts.map +1 -1
- package/dist/memory/retrieval-query.js +0 -5
- package/dist/memory/retrieval-query.js.map +1 -1
- package/dist/memory/retrieval.d.ts +11 -0
- package/dist/memory/retrieval.d.ts.map +1 -1
- package/dist/memory/retrieval.js +34 -120
- package/dist/memory/retrieval.js.map +1 -1
- package/dist/memory/revisions.d.ts +76 -1
- package/dist/memory/revisions.d.ts.map +1 -1
- package/dist/memory/revisions.js +539 -35
- package/dist/memory/revisions.js.map +1 -1
- package/dist/memory/scoped-memory.d.ts +22 -13
- package/dist/memory/scoped-memory.d.ts.map +1 -1
- package/dist/memory/scoped-memory.js +248 -139
- package/dist/memory/scoped-memory.js.map +1 -1
- package/dist/memory/secrets.d.ts +2 -0
- package/dist/memory/secrets.d.ts.map +1 -1
- package/dist/memory/secrets.js +36 -0
- package/dist/memory/secrets.js.map +1 -1
- package/dist/memory/structured-memory.d.ts +8 -1
- package/dist/memory/structured-memory.d.ts.map +1 -1
- package/dist/memory/structured-memory.js +74 -20
- package/dist/memory/structured-memory.js.map +1 -1
- package/dist/memory/workspaces.d.ts +9 -0
- package/dist/memory/workspaces.d.ts.map +1 -1
- package/dist/memory/workspaces.js +67 -0
- package/dist/memory/workspaces.js.map +1 -1
- package/dist/package-version.d.ts +2 -0
- package/dist/package-version.d.ts.map +1 -0
- package/dist/package-version.js +7 -0
- package/dist/package-version.js.map +1 -0
- package/dist/repository/binding.d.ts +5 -0
- package/dist/repository/binding.d.ts.map +1 -1
- package/dist/repository/binding.js +117 -17
- package/dist/repository/binding.js.map +1 -1
- package/dist/repository/framework-version.d.ts +8 -0
- package/dist/repository/framework-version.d.ts.map +1 -0
- package/dist/repository/framework-version.js +29 -0
- package/dist/repository/framework-version.js.map +1 -0
- package/dist/repository/identity-value.d.ts +4 -0
- package/dist/repository/identity-value.d.ts.map +1 -0
- package/dist/repository/identity-value.js +24 -0
- package/dist/repository/identity-value.js.map +1 -0
- package/dist/repository/identity.d.ts.map +1 -1
- package/dist/repository/identity.js +2 -0
- package/dist/repository/identity.js.map +1 -1
- package/dist/repository/project-fingerprint.d.ts +33 -0
- package/dist/repository/project-fingerprint.d.ts.map +1 -0
- package/dist/repository/project-fingerprint.js +429 -0
- package/dist/repository/project-fingerprint.js.map +1 -0
- package/dist/repository/remote-url.d.ts +0 -1
- package/dist/repository/remote-url.d.ts.map +1 -1
- package/dist/repository/remote-url.js +0 -1
- package/dist/repository/remote-url.js.map +1 -1
- package/dist/runtime-version.d.ts +2 -1
- package/dist/runtime-version.d.ts.map +1 -1
- package/dist/runtime-version.js +21 -4
- package/dist/runtime-version.js.map +1 -1
- package/dist/serialization/boundary-json.d.ts +20 -0
- package/dist/serialization/boundary-json.d.ts.map +1 -0
- package/dist/serialization/boundary-json.js +129 -0
- package/dist/serialization/boundary-json.js.map +1 -0
- package/dist/serialization/envelope.js +1 -1
- package/dist/serialization/envelope.js.map +1 -1
- package/dist/serialization/validate.d.ts +7 -0
- package/dist/serialization/validate.d.ts.map +1 -1
- package/dist/serialization/validate.js +53 -13
- package/dist/serialization/validate.js.map +1 -1
- package/dist/server/app.js +1 -1
- package/dist/server/app.js.map +1 -1
- package/dist/server/http.d.ts +4 -3
- package/dist/server/http.d.ts.map +1 -1
- package/dist/server/http.js +90 -50
- package/dist/server/http.js.map +1 -1
- package/dist/server/idempotency.d.ts +0 -6
- package/dist/server/idempotency.d.ts.map +1 -1
- package/dist/server/idempotency.js.map +1 -1
- package/dist/server/router.d.ts.map +1 -1
- package/dist/server/router.js +21 -4
- package/dist/server/router.js.map +1 -1
- package/dist/server/routes/agent-capability-gate.d.ts +40 -0
- package/dist/server/routes/agent-capability-gate.d.ts.map +1 -0
- package/dist/server/routes/agent-capability-gate.js +182 -0
- package/dist/server/routes/agent-capability-gate.js.map +1 -0
- package/dist/server/routes/agent-events.d.ts.map +1 -1
- package/dist/server/routes/agent-events.js +8 -1
- package/dist/server/routes/agent-events.js.map +1 -1
- package/dist/server/routes/agent-intake.d.ts.map +1 -1
- package/dist/server/routes/agent-intake.js +10 -2
- package/dist/server/routes/agent-intake.js.map +1 -1
- package/dist/server/routes/agent-promotions.d.ts.map +1 -1
- package/dist/server/routes/agent-promotions.js +5 -2
- package/dist/server/routes/agent-promotions.js.map +1 -1
- package/dist/server/routes/agent-runs.d.ts.map +1 -1
- package/dist/server/routes/agent-runs.js +18 -4
- package/dist/server/routes/agent-runs.js.map +1 -1
- package/dist/server/routes/request-binding.d.ts +5 -0
- package/dist/server/routes/request-binding.d.ts.map +1 -0
- package/dist/server/routes/request-binding.js +49 -0
- package/dist/server/routes/request-binding.js.map +1 -0
- package/dist/server/routes/task5-support.d.ts +1 -8
- package/dist/server/routes/task5-support.d.ts.map +1 -1
- package/dist/server/routes/task5-support.js +1 -17
- package/dist/server/routes/task5-support.js.map +1 -1
- package/dist/server/routes/task5.d.ts.map +1 -1
- package/dist/server/routes/task5.js +106 -36
- package/dist/server/routes/task5.js.map +1 -1
- package/dist/server/write-queue.js +2 -2
- package/dist/server/write-queue.js.map +1 -1
- package/dist/setup/claude-config.d.ts +2 -1
- package/dist/setup/claude-config.d.ts.map +1 -1
- package/dist/setup/claude-config.js +54 -4
- package/dist/setup/claude-config.js.map +1 -1
- package/dist/setup/client-detection.d.ts +7 -2
- package/dist/setup/client-detection.d.ts.map +1 -1
- package/dist/setup/client-detection.js +27 -9
- package/dist/setup/client-detection.js.map +1 -1
- package/dist/setup/hermes-config.d.ts +2 -1
- package/dist/setup/hermes-config.d.ts.map +1 -1
- package/dist/setup/hermes-config.js +53 -12
- package/dist/setup/hermes-config.js.map +1 -1
- package/dist/setup/legacy-client-cleanup.d.ts +6 -0
- package/dist/setup/legacy-client-cleanup.d.ts.map +1 -0
- package/dist/setup/legacy-client-cleanup.js +152 -0
- package/dist/setup/legacy-client-cleanup.js.map +1 -0
- package/dist/setup/managed-text.d.ts.map +1 -1
- package/dist/setup/managed-text.js +11 -1
- package/dist/setup/managed-text.js.map +1 -1
- package/dist/setup/opencode-config.d.ts +2 -1
- package/dist/setup/opencode-config.d.ts.map +1 -1
- package/dist/setup/opencode-config.js +57 -5
- package/dist/setup/opencode-config.js.map +1 -1
- package/dist/setup/render.d.ts +2 -1
- package/dist/setup/render.d.ts.map +1 -1
- package/dist/setup/render.js +91 -17
- package/dist/setup/render.js.map +1 -1
- package/dist/setup/standard-skills.d.ts +16 -2
- package/dist/setup/standard-skills.d.ts.map +1 -1
- package/dist/setup/standard-skills.js +37 -13
- package/dist/setup/standard-skills.js.map +1 -1
- package/dist/setup/strict-json.d.ts +7 -0
- package/dist/setup/strict-json.d.ts.map +1 -0
- package/dist/setup/strict-json.js +98 -0
- package/dist/setup/strict-json.js.map +1 -0
- package/dist/setup/strict-toml.d.ts +7 -0
- package/dist/setup/strict-toml.d.ts.map +1 -0
- package/dist/setup/strict-toml.js +470 -0
- package/dist/setup/strict-toml.js.map +1 -0
- package/dist/skills/cache.d.ts +15 -0
- package/dist/skills/cache.d.ts.map +1 -0
- package/dist/skills/cache.js +19 -0
- package/dist/skills/cache.js.map +1 -0
- package/dist/skills/candidate-ranking.d.ts +15 -0
- package/dist/skills/candidate-ranking.d.ts.map +1 -0
- package/dist/skills/candidate-ranking.js +52 -0
- package/dist/skills/candidate-ranking.js.map +1 -0
- package/dist/skills/chunking.d.ts +11 -0
- package/dist/skills/chunking.d.ts.map +1 -0
- package/dist/skills/chunking.js +291 -0
- package/dist/skills/chunking.js.map +1 -0
- package/dist/skills/config.d.ts +19 -0
- package/dist/skills/config.d.ts.map +1 -0
- package/dist/skills/config.js +103 -0
- package/dist/skills/config.js.map +1 -0
- package/dist/skills/discovery-service.d.ts +26 -0
- package/dist/skills/discovery-service.d.ts.map +1 -0
- package/dist/skills/discovery-service.js +921 -0
- package/dist/skills/discovery-service.js.map +1 -0
- package/dist/skills/external-transport.d.ts +2 -0
- package/dist/skills/external-transport.d.ts.map +1 -0
- package/dist/skills/external-transport.js +30 -0
- package/dist/skills/external-transport.js.map +1 -0
- package/dist/skills/find.d.ts +16 -0
- package/dist/skills/find.d.ts.map +1 -0
- package/dist/skills/find.js +58 -0
- package/dist/skills/find.js.map +1 -0
- package/dist/skills/gap-detection.d.ts +23 -0
- package/dist/skills/gap-detection.d.ts.map +1 -0
- package/dist/skills/gap-detection.js +62 -0
- package/dist/skills/gap-detection.js.map +1 -0
- package/dist/skills/import-preparation.d.ts +4 -0
- package/dist/skills/import-preparation.d.ts.map +1 -0
- package/dist/skills/import-preparation.js +20 -0
- package/dist/skills/import-preparation.js.map +1 -0
- package/dist/skills/materialization-authority.d.ts +11 -0
- package/dist/skills/materialization-authority.d.ts.map +1 -0
- package/dist/skills/materialization-authority.js +92 -0
- package/dist/skills/materialization-authority.js.map +1 -0
- package/dist/skills/materialization-service.d.ts +22 -0
- package/dist/skills/materialization-service.d.ts.map +1 -0
- package/dist/skills/materialization-service.js +101 -0
- package/dist/skills/materialization-service.js.map +1 -0
- package/dist/skills/official-catalog.d.ts +31 -0
- package/dist/skills/official-catalog.d.ts.map +1 -0
- package/dist/skills/official-catalog.js +110 -0
- package/dist/skills/official-catalog.js.map +1 -0
- package/dist/skills/providers/schema.d.ts +30 -0
- package/dist/skills/providers/schema.d.ts.map +1 -0
- package/dist/skills/providers/schema.js +354 -0
- package/dist/skills/providers/schema.js.map +1 -0
- package/dist/skills/providers/skills-sh-compat.d.ts +17 -0
- package/dist/skills/providers/skills-sh-compat.d.ts.map +1 -0
- package/dist/skills/providers/skills-sh-compat.js +71 -0
- package/dist/skills/providers/skills-sh-compat.js.map +1 -0
- package/dist/skills/providers/skills-sh-v1.d.ts +23 -0
- package/dist/skills/providers/skills-sh-v1.d.ts.map +1 -0
- package/dist/skills/providers/skills-sh-v1.js +134 -0
- package/dist/skills/providers/skills-sh-v1.js.map +1 -0
- package/dist/skills/query-builder.d.ts +18 -0
- package/dist/skills/query-builder.d.ts.map +1 -0
- package/dist/skills/query-builder.js +93 -0
- package/dist/skills/query-builder.js.map +1 -0
- package/dist/skills/source/errors.d.ts +9 -0
- package/dist/skills/source/errors.d.ts.map +1 -0
- package/dist/skills/source/errors.js +15 -0
- package/dist/skills/source/errors.js.map +1 -0
- package/dist/skills/source/frontmatter.d.ts +9 -0
- package/dist/skills/source/frontmatter.d.ts.map +1 -0
- package/dist/skills/source/frontmatter.js +77 -0
- package/dist/skills/source/frontmatter.js.map +1 -0
- package/dist/skills/source/github-fetcher.d.ts +20 -0
- package/dist/skills/source/github-fetcher.d.ts.map +1 -0
- package/dist/skills/source/github-fetcher.js +292 -0
- package/dist/skills/source/github-fetcher.js.map +1 -0
- package/dist/skills/source/snapshot-validator.d.ts +28 -0
- package/dist/skills/source/snapshot-validator.d.ts.map +1 -0
- package/dist/skills/source/snapshot-validator.js +186 -0
- package/dist/skills/source/snapshot-validator.js.map +1 -0
- package/dist/skills/store.d.ts +181 -0
- package/dist/skills/store.d.ts.map +1 -0
- package/dist/skills/store.js +1710 -0
- package/dist/skills/store.js.map +1 -0
- package/dist/skills/types.d.ts +169 -0
- package/dist/skills/types.d.ts.map +1 -0
- package/dist/skills/types.js +2 -0
- package/dist/skills/types.js.map +1 -0
- package/dist/web/i18n.d.ts +56 -8
- package/dist/web/i18n.d.ts.map +1 -1
- package/dist/web/i18n.js +224 -32
- package/dist/web/i18n.js.map +1 -1
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +458 -42
- package/dist/web/server.js.map +1 -1
- package/dist/web/ui.d.ts +4 -0
- package/dist/web/ui.d.ts.map +1 -1
- package/dist/web/ui.js +697 -61
- package/dist/web/ui.js.map +1 -1
- package/migrations/008_federated_memory.sql +46 -0
- package/migrations/009_external_skill_discovery.sql +126 -0
- package/package.json +6 -3
- package/skills/kiokuko-single-purpose-functions/SKILL.md +288 -0
- package/skills/kiokuko-single-purpose-functions/references/kiokuko-patterns.md +344 -0
- package/skills/kiokuko-single-purpose-functions/references/review-checklist.md +97 -0
- package/skills/kiokuko-ui-design-soul/SKILL.md +1186 -28
- package/templates/AGENTS.md +8 -7
- package/dist/client/runtime-discovery.d.ts +0 -15
- package/dist/client/runtime-discovery.d.ts.map +0 -1
- package/dist/client/runtime-discovery.js +0 -45
- package/dist/client/runtime-discovery.js.map +0 -1
- package/dist/commands/call.d.ts +0 -7
- package/dist/commands/call.d.ts.map +0 -1
- package/dist/commands/call.js +0 -10
- package/dist/commands/call.js.map +0 -1
- package/dist/commands/link.d.ts +0 -6
- package/dist/commands/link.d.ts.map +0 -1
- package/dist/commands/link.js +0 -6
- package/dist/commands/link.js.map +0 -1
- package/dist/commands/promote.d.ts +0 -6
- package/dist/commands/promote.d.ts.map +0 -1
- package/dist/commands/promote.js +0 -6
- package/dist/commands/promote.js.map +0 -1
- package/dist/commands/read.d.ts +0 -6
- package/dist/commands/read.d.ts.map +0 -1
- package/dist/commands/read.js +0 -4
- package/dist/commands/read.js.map +0 -1
- package/dist/commands/recall.d.ts +0 -6
- package/dist/commands/recall.d.ts.map +0 -1
- package/dist/commands/recall.js +0 -4
- package/dist/commands/recall.js.map +0 -1
- package/dist/commands/record.d.ts +0 -6
- package/dist/commands/record.d.ts.map +0 -1
- package/dist/commands/record.js +0 -4
- package/dist/commands/record.js.map +0 -1
- package/dist/commands/search.d.ts +0 -6
- package/dist/commands/search.d.ts.map +0 -1
- package/dist/commands/search.js +0 -4
- package/dist/commands/search.js.map +0 -1
- package/dist/commands/supersede.d.ts +0 -6
- package/dist/commands/supersede.d.ts.map +0 -1
- package/dist/commands/supersede.js +0 -6
- package/dist/commands/supersede.js.map +0 -1
- package/dist/knowledge/sources.d.ts +0 -72
- package/dist/knowledge/sources.d.ts.map +0 -1
- package/dist/knowledge/sources.js +0 -388
- package/dist/knowledge/sources.js.map +0 -1
- package/dist/setup/opencode-evidence.d.ts +0 -37
- package/dist/setup/opencode-evidence.d.ts.map +0 -1
- package/dist/setup/opencode-evidence.js +0 -58
- package/dist/setup/opencode-evidence.js.map +0 -1
- package/dist/setup/opencode-loop-guard.d.ts +0 -9
- package/dist/setup/opencode-loop-guard.d.ts.map +0 -1
- package/dist/setup/opencode-loop-guard.js +0 -248
- package/dist/setup/opencode-loop-guard.js.map +0 -1
package/dist/context/broker.js
CHANGED
|
@@ -1,20 +1,103 @@
|
|
|
1
|
-
import { createHash, randomUUID } from 'node:crypto';
|
|
2
1
|
import { KiokukoError } from '../errors.js';
|
|
3
|
-
import {
|
|
4
|
-
import { listContextDeliveries, readContextDelivery,
|
|
5
|
-
import {
|
|
2
|
+
import { withImmediateTransaction } from '../db/transaction.js';
|
|
3
|
+
import { listContextDeliveries, readContextDelivery, recordContextDeliveryInTransaction, } from './delivery.js';
|
|
4
|
+
import { contextFeedbackSignals } from './feedback.js';
|
|
6
5
|
import { buildRecommendations, RECOMMENDATION_POLICY_VERSION } from './recommendations.js';
|
|
7
|
-
import { CONTEXT_RANKING_VERSION, rankContextCandidates } from './ranking.js';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
6
|
+
import { CONTEXT_RANKING_VERSION, CONTEXT_SELECTION_REASON_ORDER, rankContextCandidates } from './ranking.js';
|
|
7
|
+
import { rankedEntryHits } from '../memory/retrieval.js';
|
|
8
|
+
import { readEntry } from '../memory/entries.js';
|
|
9
|
+
import { decodeStoredStructuredScope, readEntryRevision } from '../memory/revisions.js';
|
|
10
|
+
import { federatedEntries } from '../memory/federated-retrieval.js';
|
|
11
|
+
import { isRetrievableEntry } from '../memory/hybrid-retrieval.js';
|
|
12
|
+
import { GLOBAL_WORKSPACE } from '../memory/workspaces.js';
|
|
13
|
+
import { effectiveRetrievalScope, hasExplicitApplicability } from '../memory/structured-memory.js';
|
|
14
|
+
import { canonicalContentHash, compareCanonicalStrings } from '../serialization/validate.js';
|
|
15
|
+
import { entryOriginMatchesWorkspace } from './origin.js';
|
|
16
|
+
import { isExternalSkillReference } from '../skills/store.js';
|
|
17
|
+
import { contextRetrievalStateHash } from './selection-state.js';
|
|
18
|
+
import { readContextRunRetrievalState } from './run-state.js';
|
|
19
|
+
import { captureProjectManifestSnapshot, resolveProjectFingerprint, } from '../repository/project-fingerprint.js';
|
|
13
20
|
export const CONTEXT_BROKER_POLICY_VERSION = `${CONTEXT_RANKING_VERSION}+${RECOMMENDATION_POLICY_VERSION}`;
|
|
14
21
|
export const CONTEXT_BROKER_DEFAULT_LIMIT = 20;
|
|
15
22
|
export const CONTEXT_BROKER_MAX_LIMIT = 100;
|
|
16
23
|
export const CONTEXT_BROKER_DEFAULT_CHARACTER_BUDGET = 8_000;
|
|
17
24
|
export const CONTEXT_BROKER_MAX_CHARACTER_BUDGET = 100_000;
|
|
25
|
+
function normalizedGateDecision(value) {
|
|
26
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
27
|
+
throw new TypeError('Context broker gate returned an invalid decision');
|
|
28
|
+
}
|
|
29
|
+
const prototype = Object.getPrototypeOf(value);
|
|
30
|
+
const keys = Reflect.ownKeys(value);
|
|
31
|
+
if ((prototype !== Object.prototype && prototype !== null)
|
|
32
|
+
|| keys.some((key) => typeof key !== 'string'
|
|
33
|
+
|| key !== 'persist' && key !== 'value' && key !== 'assertBeforePersist')
|
|
34
|
+
|| !keys.includes('persist')
|
|
35
|
+
|| !keys.includes('value')) {
|
|
36
|
+
throw new TypeError('Context broker gate returned an invalid decision');
|
|
37
|
+
}
|
|
38
|
+
const persistDescriptor = Object.getOwnPropertyDescriptor(value, 'persist');
|
|
39
|
+
const resultDescriptor = Object.getOwnPropertyDescriptor(value, 'value');
|
|
40
|
+
const assertionDescriptor = Object.getOwnPropertyDescriptor(value, 'assertBeforePersist');
|
|
41
|
+
if (persistDescriptor === undefined
|
|
42
|
+
|| !Object.hasOwn(persistDescriptor, 'value')
|
|
43
|
+
|| typeof persistDescriptor.value !== 'boolean'
|
|
44
|
+
|| resultDescriptor === undefined
|
|
45
|
+
|| !Object.hasOwn(resultDescriptor, 'value')
|
|
46
|
+
|| assertionDescriptor !== undefined
|
|
47
|
+
&& (!Object.hasOwn(assertionDescriptor, 'value') || typeof assertionDescriptor.value !== 'function')) {
|
|
48
|
+
throw new TypeError('Context broker gate returned an invalid decision');
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
persist: persistDescriptor.value,
|
|
52
|
+
value: resultDescriptor.value,
|
|
53
|
+
...(assertionDescriptor === undefined
|
|
54
|
+
? {}
|
|
55
|
+
: { assertBeforePersist: assertionDescriptor.value }),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function contextDeliverySnapshotHash(delivery) {
|
|
59
|
+
return canonicalContentHash({
|
|
60
|
+
workspace: delivery.workspace,
|
|
61
|
+
deliveryId: delivery.deliveryId,
|
|
62
|
+
runId: delivery.runId,
|
|
63
|
+
throughSequence: delivery.throughSequence,
|
|
64
|
+
intakeSessionId: delivery.intakeSessionId,
|
|
65
|
+
taskProfileHash: delivery.taskProfileHash,
|
|
66
|
+
queryHash: delivery.queryHash,
|
|
67
|
+
policyVersion: delivery.policyVersion,
|
|
68
|
+
charBudget: delivery.charBudget,
|
|
69
|
+
charCount: delivery.charCount,
|
|
70
|
+
truncated: delivery.truncated,
|
|
71
|
+
createdAt: delivery.createdAt,
|
|
72
|
+
scoreSchemaVersion: delivery.scoreSchemaVersion ?? 1,
|
|
73
|
+
items: delivery.items.map((item) => ({
|
|
74
|
+
entryId: item.entryId,
|
|
75
|
+
entryRevision: item.entryRevision,
|
|
76
|
+
rank: item.rank,
|
|
77
|
+
scoreComponents: item.scoreComponents,
|
|
78
|
+
selectionReasons: item.selectionReasons,
|
|
79
|
+
...(item.origin === undefined ? {} : { origin: item.origin }),
|
|
80
|
+
})),
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
function assertReplayDeliveryUnchanged(database, expected) {
|
|
84
|
+
let current;
|
|
85
|
+
try {
|
|
86
|
+
current = readContextDelivery(database, {
|
|
87
|
+
workspace: expected.workspace,
|
|
88
|
+
deliveryId: expected.deliveryId,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
if (error instanceof KiokukoError && error.code === 'NOT_FOUND') {
|
|
93
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Stored context delivery disappeared during replay');
|
|
94
|
+
}
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
if (contextDeliverySnapshotHash(current) !== contextDeliverySnapshotHash(expected)) {
|
|
98
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Stored context delivery changed during replay');
|
|
99
|
+
}
|
|
100
|
+
}
|
|
18
101
|
function invalid() {
|
|
19
102
|
throw new KiokukoError('VALIDATION_ERROR', 'Context query input is invalid');
|
|
20
103
|
}
|
|
@@ -72,58 +155,50 @@ function normalizeInput(input) {
|
|
|
72
155
|
...(value.characterBudget === undefined ? {} : { characterBudget: value.characterBudget }),
|
|
73
156
|
};
|
|
74
157
|
}
|
|
75
|
-
function
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
158
|
+
function normalizePersistence(value) {
|
|
159
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
160
|
+
throw new TypeError('Context broker persistence adapter is invalid');
|
|
161
|
+
}
|
|
162
|
+
const object = value;
|
|
163
|
+
const prototype = Object.getPrototypeOf(object);
|
|
164
|
+
const keys = Reflect.ownKeys(object);
|
|
165
|
+
const descriptor = Object.getOwnPropertyDescriptor(object, 'enqueueWrite');
|
|
166
|
+
if ((prototype !== Object.prototype && prototype !== null)
|
|
167
|
+
|| keys.some((key) => key !== 'enqueueWrite')
|
|
168
|
+
|| descriptor !== undefined && !Object.hasOwn(descriptor, 'value')) {
|
|
169
|
+
throw new TypeError('Context broker persistence adapter is invalid');
|
|
170
|
+
}
|
|
171
|
+
const enqueueWrite = descriptor?.value;
|
|
172
|
+
if (enqueueWrite !== undefined && typeof enqueueWrite !== 'function') {
|
|
173
|
+
throw new TypeError('Context broker persistence adapter is invalid');
|
|
174
|
+
}
|
|
175
|
+
return enqueueWrite === undefined
|
|
176
|
+
? {}
|
|
177
|
+
: { enqueueWrite: enqueueWrite };
|
|
93
178
|
}
|
|
94
179
|
function currentRunContext(database, runId) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
notFound();
|
|
98
|
-
const link = readRunIntakeLink(database, { workspace: run.workspace, runId });
|
|
99
|
-
const session = readAkinatorSession(database, { workspace: run.workspace, sessionId: link.sessionId });
|
|
100
|
-
const status = session.status;
|
|
101
|
-
if (status === 'active') {
|
|
102
|
-
return {
|
|
103
|
-
run,
|
|
104
|
-
profile: session.profile,
|
|
105
|
-
profileHash: link.initialProfileHash ?? canonicalContentHash(session.profile),
|
|
106
|
-
recommendedTags: [...link.recommendedTags],
|
|
107
|
-
intakeSessionId: link.sessionId,
|
|
108
|
-
intakeStatus: status,
|
|
109
|
-
projection: null,
|
|
110
|
-
};
|
|
180
|
+
try {
|
|
181
|
+
return readContextRunRetrievalState(database, runId);
|
|
111
182
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
183
|
+
catch (error) {
|
|
184
|
+
if (error instanceof KiokukoError
|
|
185
|
+
&& error.code === 'NOT_FOUND'
|
|
186
|
+
&& error.message === 'Context run was not found') {
|
|
187
|
+
notFound();
|
|
188
|
+
}
|
|
189
|
+
throw error;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
/** Read the same authoritative run/intake/profile snapshot used to rank broker context. */
|
|
193
|
+
export function readContextBrokerRunState(database, runId) {
|
|
194
|
+
const current = currentRunContext(database, runId);
|
|
119
195
|
return {
|
|
120
|
-
run,
|
|
121
|
-
|
|
122
|
-
profileHash:
|
|
123
|
-
recommendedTags: [...
|
|
124
|
-
intakeSessionId:
|
|
125
|
-
intakeStatus:
|
|
126
|
-
projection,
|
|
196
|
+
run: current.run,
|
|
197
|
+
taskProfile: { ...current.profile },
|
|
198
|
+
profileHash: current.profileHash,
|
|
199
|
+
recommendedTags: [...current.recommendedTags],
|
|
200
|
+
intakeSessionId: current.intakeSessionId,
|
|
201
|
+
status: current.intakeStatus === 'active' ? 'needs_answer' : current.intakeStatus,
|
|
127
202
|
};
|
|
128
203
|
}
|
|
129
204
|
function preparedQuery(database, input) {
|
|
@@ -136,6 +211,21 @@ function preparedQuery(database, input) {
|
|
|
136
211
|
const throughSequence = runContext?.run.lastSequence ?? 0;
|
|
137
212
|
const taskProfileHash = runContext?.profileHash ?? canonicalContentHash(profile);
|
|
138
213
|
const recommendedTags = runContext?.recommendedTags ?? input.recommendedTags ?? [];
|
|
214
|
+
const workspace = runContext?.run.workspace ?? requestedWorkspace;
|
|
215
|
+
const project = projectForWorkspace(database, workspace);
|
|
216
|
+
const projectState = project === undefined
|
|
217
|
+
? null
|
|
218
|
+
: {
|
|
219
|
+
project,
|
|
220
|
+
fingerprint: resolveProjectFingerprint(database, project, captureProjectManifestSnapshot(project)),
|
|
221
|
+
};
|
|
222
|
+
const includeEcosystem = projectState !== null;
|
|
223
|
+
const selectionWorkspaces = !includeEcosystem
|
|
224
|
+
? [workspace]
|
|
225
|
+
: [workspace, GLOBAL_WORKSPACE];
|
|
226
|
+
const retrievalStateHash = runContext === null || runContext.intakeStatus !== 'active'
|
|
227
|
+
? contextRetrievalStateHash(database, selectionWorkspaces, { includeEcosystem })
|
|
228
|
+
: null;
|
|
139
229
|
const queryShape = {
|
|
140
230
|
runId: input.runId ?? null,
|
|
141
231
|
workspace: input.runId === undefined ? requestedWorkspace : null,
|
|
@@ -147,10 +237,15 @@ function preparedQuery(database, input) {
|
|
|
147
237
|
throughSequence,
|
|
148
238
|
characterBudget: input.characterBudget ?? CONTEXT_BROKER_DEFAULT_CHARACTER_BUDGET,
|
|
149
239
|
limit: input.limit ?? CONTEXT_BROKER_DEFAULT_LIMIT,
|
|
240
|
+
projectState,
|
|
241
|
+
retrievalStateHash,
|
|
242
|
+
runStateHash: runContext?.stateHash ?? null,
|
|
150
243
|
};
|
|
151
244
|
const queryHash = canonicalContentHash(queryShape);
|
|
152
245
|
return {
|
|
153
|
-
workspace
|
|
246
|
+
workspace,
|
|
247
|
+
selectionWorkspaces,
|
|
248
|
+
includeEcosystem,
|
|
154
249
|
run: runContext?.run ?? null,
|
|
155
250
|
taskProfile: profile,
|
|
156
251
|
profileHash: taskProfileHash,
|
|
@@ -164,11 +259,16 @@ function preparedQuery(database, input) {
|
|
|
164
259
|
intakeSessionId: runContext?.intakeSessionId ?? null,
|
|
165
260
|
projection: runContext?.projection ?? null,
|
|
166
261
|
runStatus: runContext === null ? 'unbound' : runContext.intakeStatus === 'active' ? 'needs_answer' : runContext.intakeStatus,
|
|
262
|
+
projectState,
|
|
263
|
+
retrievalStateHash,
|
|
264
|
+
runStateHash: runContext?.stateHash ?? null,
|
|
265
|
+
deliveryHistoryStateHash: null,
|
|
266
|
+
deliveryHistoryExcludeQueryHash: null,
|
|
167
267
|
queryHash,
|
|
168
|
-
deliveryId:
|
|
268
|
+
deliveryId: null,
|
|
169
269
|
};
|
|
170
270
|
}
|
|
171
|
-
function entrySnapshot(entry) {
|
|
271
|
+
function entrySnapshot(entry, origin, selectionReasons = []) {
|
|
172
272
|
return {
|
|
173
273
|
id: entry.id,
|
|
174
274
|
revision: entry.revision,
|
|
@@ -182,69 +282,213 @@ function entrySnapshot(entry) {
|
|
|
182
282
|
tags: [...entry.tags],
|
|
183
283
|
scope: entry.scope,
|
|
184
284
|
updatedAt: entry.updatedAt,
|
|
285
|
+
selectionReasons: [...selectionReasons],
|
|
286
|
+
...(origin === undefined ? {} : { origin }),
|
|
185
287
|
};
|
|
186
288
|
}
|
|
187
289
|
function retrievalQuery(query) {
|
|
188
290
|
const values = [query.task, query.taskProfile.target, query.taskProfile.expected, ...query.recommendedTags].filter((value) => value !== null && value.length > 0);
|
|
189
291
|
return values.join(' ').slice(0, 16_384) || 'kiokuko';
|
|
190
292
|
}
|
|
191
|
-
|
|
293
|
+
const APPLICABILITY_DETAIL_REASONS = new Set([
|
|
294
|
+
'language_match',
|
|
295
|
+
'database_match',
|
|
296
|
+
'runtime_match',
|
|
297
|
+
'tool_match',
|
|
298
|
+
'platform_match',
|
|
299
|
+
'framework_exact_match',
|
|
300
|
+
'framework_match',
|
|
301
|
+
]);
|
|
302
|
+
function canonicalRetrievedReasons(reasons) {
|
|
303
|
+
const normalized = reasons.map((reason) => {
|
|
304
|
+
if (APPLICABILITY_DETAIL_REASONS.has(reason))
|
|
305
|
+
return 'applicability_match';
|
|
306
|
+
if (CONTEXT_SELECTION_REASON_ORDER.includes(reason))
|
|
307
|
+
return reason;
|
|
308
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Retrieval returned an unknown selection reason');
|
|
309
|
+
});
|
|
310
|
+
const rank = (reason) => CONTEXT_SELECTION_REASON_ORDER.indexOf(reason);
|
|
311
|
+
return [...new Set(normalized)].sort((left, right) => rank(left) - rank(right) || compareCanonicalStrings(left, right));
|
|
312
|
+
}
|
|
313
|
+
function addRetrievedEntry(entries, value) {
|
|
314
|
+
const existing = entries.get(value.entry.id);
|
|
315
|
+
entries.set(value.entry.id, {
|
|
316
|
+
...value,
|
|
317
|
+
selectionReasons: canonicalRetrievedReasons([...(existing?.selectionReasons ?? []), ...value.selectionReasons]),
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
function projectForWorkspace(database, workspace) {
|
|
321
|
+
const row = database.prepare(`
|
|
322
|
+
SELECT r.repository_id AS repositoryId, r.workspace, l.canonical_root AS repositoryRoot
|
|
323
|
+
FROM repositories AS r JOIN repository_locations AS l ON l.repository_id = r.repository_id
|
|
324
|
+
WHERE r.workspace = ? ORDER BY l.last_seen_at DESC, l.canonical_root ASC LIMIT 1
|
|
325
|
+
`).get(workspace);
|
|
326
|
+
if (row === undefined)
|
|
327
|
+
return undefined;
|
|
328
|
+
const { repositoryId, repositoryRoot, workspace: storedWorkspace } = row;
|
|
329
|
+
if (typeof repositoryId !== 'string' || repositoryId.length === 0
|
|
330
|
+
|| typeof storedWorkspace !== 'string' || storedWorkspace !== workspace
|
|
331
|
+
|| typeof repositoryRoot !== 'string' || repositoryRoot.length === 0) {
|
|
332
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Stored context project binding is invalid');
|
|
333
|
+
}
|
|
334
|
+
return { repositoryRoot, repositoryId, workspace: storedWorkspace, source: 'location' };
|
|
335
|
+
}
|
|
336
|
+
async function retrieveEntries(database, query) {
|
|
192
337
|
const terms = [query.task, query.taskProfile.target, query.taskProfile.expected, ...query.recommendedTags]
|
|
193
338
|
.filter((value) => value !== null && value.length > 0)
|
|
194
339
|
.map((value) => value.slice(0, 2_000));
|
|
195
340
|
const queries = [retrievalQuery(query), ...terms];
|
|
196
341
|
const entries = new Map();
|
|
197
342
|
for (const value of queries) {
|
|
198
|
-
|
|
199
|
-
|
|
343
|
+
if (query.projectState !== null) {
|
|
344
|
+
for (const hit of await federatedEntries(database, {
|
|
345
|
+
project: query.projectState.project,
|
|
346
|
+
fingerprint: query.projectState.fingerprint,
|
|
347
|
+
query: value,
|
|
348
|
+
limit: 500,
|
|
349
|
+
})) {
|
|
350
|
+
addRetrievedEntry(entries, { entry: hit.entry, origin: hit.origin, selectionReasons: hit.selectionReasons });
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
else {
|
|
354
|
+
for (const hit of rankedEntryHits(database, { workspace: query.workspace, query: value, limit: 500, includeSuperseded: false }).hits) {
|
|
355
|
+
addRetrievedEntry(entries, {
|
|
356
|
+
entry: readEntry(database, { workspace: query.workspace, entryId: hit.entryId }),
|
|
357
|
+
origin: 'project',
|
|
358
|
+
selectionReasons: ['project_origin', ...hit.reasons],
|
|
359
|
+
});
|
|
360
|
+
}
|
|
200
361
|
}
|
|
201
362
|
}
|
|
202
363
|
return [...entries.values()];
|
|
203
364
|
}
|
|
204
|
-
function
|
|
365
|
+
function assertPreparedProjectState(database, query) {
|
|
366
|
+
const currentProject = projectForWorkspace(database, query.workspace);
|
|
367
|
+
if (query.projectState === null) {
|
|
368
|
+
if (currentProject !== undefined) {
|
|
369
|
+
throw new KiokukoError('CONFLICT', 'Context project state changed after ranking');
|
|
370
|
+
}
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
if (currentProject === undefined
|
|
374
|
+
|| canonicalContentHash(currentProject) !== canonicalContentHash(query.projectState.project)) {
|
|
375
|
+
throw new KiokukoError('CONFLICT', 'Context project state changed after ranking');
|
|
376
|
+
}
|
|
377
|
+
const manifestSnapshot = captureProjectManifestSnapshot(currentProject);
|
|
378
|
+
if (manifestSnapshot.manifestDigest !== query.projectState.fingerprint.manifestDigest) {
|
|
379
|
+
throw new KiokukoError('CONFLICT', 'Context project state changed after ranking');
|
|
380
|
+
}
|
|
381
|
+
const currentFingerprint = resolveProjectFingerprint(database, currentProject, manifestSnapshot, { readOnly: true });
|
|
382
|
+
if (canonicalContentHash(currentFingerprint) !== canonicalContentHash(query.projectState.fingerprint)) {
|
|
383
|
+
throw new KiokukoError('CONFLICT', 'Context project state changed after ranking');
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
async function rank(database, query, prior) {
|
|
387
|
+
const entries = await retrieveEntries(database, query);
|
|
388
|
+
const feedback = entries.flatMap(({ entry }) => contextFeedbackSignals(database, entry.id).flatMap((signal) => Array.from({ length: signal.boundedInfluence }, () => ({ entryId: entry.id, verdict: signal.verdict }))));
|
|
389
|
+
return rankContextCandidates({
|
|
390
|
+
taskProfile: query.taskProfile,
|
|
391
|
+
recommendedTags: query.recommendedTags,
|
|
392
|
+
changedPaths: query.changedPaths,
|
|
393
|
+
errorSignatures: query.errorSignatures,
|
|
394
|
+
priorDelivered: prior.delivered,
|
|
395
|
+
feedback,
|
|
396
|
+
candidates: entries.map(({ entry, origin, selectionReasons }) => entrySnapshot(entry, origin, selectionReasons)),
|
|
397
|
+
limit: query.limit,
|
|
398
|
+
characterBudget: query.characterBudget,
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
function priorData(database, query, options = {}) {
|
|
205
402
|
if (query.run === null)
|
|
206
|
-
return { delivered: [],
|
|
403
|
+
return { delivered: [], stale: [], stateHash: null };
|
|
207
404
|
const deliveries = [];
|
|
208
405
|
let cursor;
|
|
406
|
+
let complete = false;
|
|
209
407
|
for (let page = 0; page < 10; page += 1) {
|
|
210
408
|
const result = listContextDeliveries(database, { workspace: query.workspace, runId: query.run.runId, limit: 100, ...(cursor === undefined ? {} : { cursor }) });
|
|
211
409
|
deliveries.push(...result.items);
|
|
212
|
-
if (result.nextCursor === null)
|
|
410
|
+
if (result.nextCursor === null) {
|
|
411
|
+
complete = true;
|
|
213
412
|
break;
|
|
413
|
+
}
|
|
214
414
|
cursor = result.nextCursor;
|
|
215
415
|
}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
const
|
|
416
|
+
if (!complete) {
|
|
417
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Context delivery history exceeds the broker policy bound');
|
|
418
|
+
}
|
|
419
|
+
for (const delivery of deliveries) {
|
|
420
|
+
for (const item of delivery.items) {
|
|
421
|
+
currentRetrievableDeliveryEntry(database, query.workspace, item);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
const stateDeliveries = deliveries.filter((delivery) => delivery.deliveryId !== options.excludeDeliveryId);
|
|
425
|
+
const delivered = stateDeliveries
|
|
426
|
+
.filter((delivery) => delivery.queryHash !== options.excludeDeliveredQueryHash)
|
|
427
|
+
.flatMap((delivery) => delivery.items.flatMap((item) => contextFeedbackSignals(database, item.entryId)
|
|
428
|
+
.some((signal) => signal.verdict === 'helpful')
|
|
429
|
+
? []
|
|
430
|
+
: [{ entryId: item.entryId, revision: item.entryRevision }]));
|
|
431
|
+
const stale = stateDeliveries.flatMap((delivery) => delivery.items.flatMap((item) => {
|
|
220
432
|
const current = database.prepare('SELECT current_revision FROM entries WHERE id = ?').get(item.entryId);
|
|
221
433
|
return current && Number(current.current_revision) > item.entryRevision ? [{ entryId: item.entryId, deliveredRevision: item.entryRevision, currentRevision: Number(current.current_revision), stale: true }] : [];
|
|
222
434
|
}));
|
|
223
|
-
return {
|
|
435
|
+
return {
|
|
436
|
+
delivered,
|
|
437
|
+
stale,
|
|
438
|
+
stateHash: canonicalContentHash({
|
|
439
|
+
runId: query.run.runId,
|
|
440
|
+
excludeDeliveredQueryHash: options.excludeDeliveredQueryHash ?? null,
|
|
441
|
+
deliveries: stateDeliveries.map(contextDeliverySnapshotHash),
|
|
442
|
+
delivered,
|
|
443
|
+
stale,
|
|
444
|
+
}),
|
|
445
|
+
};
|
|
224
446
|
}
|
|
225
|
-
function
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
447
|
+
function historyAttestedDeliveryId(query, historyStateHash, excludeDeliveredQueryHash) {
|
|
448
|
+
return `context-${canonicalContentHash({
|
|
449
|
+
kind: 'context-delivery-history-attestation-v1',
|
|
450
|
+
queryHash: query.queryHash,
|
|
451
|
+
historyStateHash,
|
|
452
|
+
excludeDeliveredQueryHash,
|
|
453
|
+
})}`;
|
|
454
|
+
}
|
|
455
|
+
function deliveryHistoryExclusionForReplay(database, query, deliveryId) {
|
|
456
|
+
if (query.run === null)
|
|
457
|
+
return null;
|
|
458
|
+
const priorSameQuery = database.prepare(`
|
|
459
|
+
SELECT 1 AS present
|
|
460
|
+
FROM context_deliveries
|
|
461
|
+
WHERE run_id = ? AND query_hash = ? AND delivery_id <> ?
|
|
462
|
+
LIMIT 1
|
|
463
|
+
`).get(query.run.runId, query.queryHash, deliveryId);
|
|
464
|
+
if (priorSameQuery === undefined)
|
|
465
|
+
return null;
|
|
466
|
+
if (priorSameQuery.present !== 1) {
|
|
467
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Stored context delivery history is invalid');
|
|
468
|
+
}
|
|
469
|
+
return query.queryHash;
|
|
470
|
+
}
|
|
471
|
+
function deliveryHistoryIsAttested(database, query, delivery) {
|
|
472
|
+
const excludeDeliveredQueryHash = deliveryHistoryExclusionForReplay(database, query, delivery.deliveryId);
|
|
473
|
+
const history = priorData(database, query, {
|
|
474
|
+
...(excludeDeliveredQueryHash === null ? {} : { excludeDeliveredQueryHash }),
|
|
475
|
+
excludeDeliveryId: delivery.deliveryId,
|
|
237
476
|
});
|
|
477
|
+
if (history.stateHash === null) {
|
|
478
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Stored context delivery history is invalid');
|
|
479
|
+
}
|
|
480
|
+
return delivery.deliveryId === historyAttestedDeliveryId(query, history.stateHash, excludeDeliveredQueryHash);
|
|
238
481
|
}
|
|
239
482
|
function outputContext(query, items, delivery) {
|
|
240
483
|
const sourceItems = items.map((item, index) => ({
|
|
241
484
|
entryId: item.entryId,
|
|
242
485
|
entryRevision: item.revision,
|
|
243
486
|
rank: index + 1,
|
|
244
|
-
scoreComponents: item.scoreComponents,
|
|
487
|
+
scoreComponents: { ...item.scoreComponents },
|
|
245
488
|
selectionReasons: [...item.selectionReasons],
|
|
246
|
-
content: item.content,
|
|
489
|
+
content: { ...item.content },
|
|
247
490
|
untrusted: true,
|
|
491
|
+
...(item.origin === undefined ? {} : { origin: item.origin }),
|
|
248
492
|
}));
|
|
249
493
|
return {
|
|
250
494
|
deliveryId: delivery?.deliveryId ?? query.deliveryId,
|
|
@@ -257,13 +501,14 @@ function outputContext(query, items, delivery) {
|
|
|
257
501
|
untrusted: true,
|
|
258
502
|
};
|
|
259
503
|
}
|
|
260
|
-
function deliveryInput(query, ranked
|
|
504
|
+
function deliveryInput(query, ranked) {
|
|
261
505
|
const items = ranked.map((item, index) => ({
|
|
262
506
|
entryId: item.entryId,
|
|
263
507
|
entryRevision: item.revision,
|
|
264
508
|
rank: index + 1,
|
|
265
|
-
scoreComponents: item.scoreComponents,
|
|
509
|
+
scoreComponents: { ...item.scoreComponents },
|
|
266
510
|
selectionReasons: [...item.selectionReasons],
|
|
511
|
+
...(item.origin === undefined ? {} : { origin: item.origin }),
|
|
267
512
|
}));
|
|
268
513
|
const charCount = ranked.reduce((sum, item) => sum + item.content.characterCount, 0);
|
|
269
514
|
const truncated = ranked.some((item) => item.content.truncated);
|
|
@@ -276,7 +521,6 @@ function deliveryInput(query, ranked, summary) {
|
|
|
276
521
|
taskProfileHash: query.profileHash,
|
|
277
522
|
queryHash: query.queryHash,
|
|
278
523
|
policyVersion: CONTEXT_BROKER_POLICY_VERSION,
|
|
279
|
-
externalSyncSummary: summary,
|
|
280
524
|
charBudget: query.characterBudget,
|
|
281
525
|
charCount,
|
|
282
526
|
truncated,
|
|
@@ -284,19 +528,74 @@ function deliveryInput(query, ranked, summary) {
|
|
|
284
528
|
items,
|
|
285
529
|
};
|
|
286
530
|
}
|
|
287
|
-
function
|
|
288
|
-
|
|
531
|
+
function currentRetrievableDeliveryEntry(database, runWorkspace, item) {
|
|
532
|
+
const candidate = database.prepare('SELECT workspace FROM entries WHERE id = ?')
|
|
533
|
+
.get(item.entryId);
|
|
534
|
+
if (candidate === undefined) {
|
|
535
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Stored context entry is missing');
|
|
536
|
+
}
|
|
537
|
+
if (typeof candidate.workspace !== 'string' || candidate.workspace.length === 0) {
|
|
538
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Stored context entry is invalid');
|
|
539
|
+
}
|
|
540
|
+
const origin = item.origin ?? 'project';
|
|
541
|
+
let deliveredRevision;
|
|
542
|
+
try {
|
|
543
|
+
deliveredRevision = readEntryRevision(database, {
|
|
544
|
+
workspace: candidate.workspace,
|
|
545
|
+
entryId: item.entryId,
|
|
546
|
+
revision: item.entryRevision,
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
catch (error) {
|
|
550
|
+
if (error instanceof KiokukoError && error.code === 'NOT_FOUND') {
|
|
551
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Stored context entry revision is missing');
|
|
552
|
+
}
|
|
553
|
+
throw error;
|
|
554
|
+
}
|
|
555
|
+
const deliveredScope = decodeStoredStructuredScope(deliveredRevision.scope, origin !== 'project').canonicalScope;
|
|
556
|
+
if (!entryOriginMatchesWorkspace({ origin, runWorkspace, entryWorkspace: deliveredRevision.workspace })) {
|
|
557
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Stored context entry origin is invalid');
|
|
558
|
+
}
|
|
559
|
+
if (origin === 'global'
|
|
560
|
+
&& (deliveredScope.visibility !== 'global' || effectiveRetrievalScope(deliveredScope) !== 'global')) {
|
|
561
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Stored context entry scope is invalid');
|
|
562
|
+
}
|
|
563
|
+
if (origin === 'ecosystem'
|
|
564
|
+
&& (!Object.hasOwn(deliveredScope, 'retrievalScope')
|
|
565
|
+
|| effectiveRetrievalScope(deliveredScope) !== 'ecosystem'
|
|
566
|
+
|| !hasExplicitApplicability(deliveredScope))) {
|
|
567
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Stored context entry scope is invalid');
|
|
568
|
+
}
|
|
569
|
+
if (isExternalSkillReference(deliveredRevision)) {
|
|
570
|
+
const mappings = database.prepare('SELECT COUNT(*) AS count FROM external_skill_entries WHERE entry_id = ?')
|
|
571
|
+
.get(item.entryId)?.count;
|
|
572
|
+
if (typeof mappings !== 'number' || !Number.isSafeInteger(mappings) || mappings < 1) {
|
|
573
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Stored context external entry mapping is missing');
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
const entry = readEntry(database, { workspace: candidate.workspace, entryId: item.entryId }, { requireStructuredScope: origin !== 'project' });
|
|
577
|
+
const retrievable = isRetrievableEntry(database, entry);
|
|
578
|
+
if (entry.revision !== item.entryRevision)
|
|
579
|
+
return null;
|
|
580
|
+
if (!retrievable)
|
|
581
|
+
return null;
|
|
582
|
+
if (entry.status === 'superseded')
|
|
583
|
+
return null;
|
|
584
|
+
return entry;
|
|
289
585
|
}
|
|
290
586
|
function storedContext(database, query, delivery) {
|
|
291
587
|
let remaining = query.characterBudget;
|
|
588
|
+
let totalCharacterCount = 0;
|
|
589
|
+
let anyTruncated = false;
|
|
292
590
|
const items = delivery.items.map((item) => {
|
|
293
|
-
const
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
591
|
+
const current = currentRetrievableDeliveryEntry(database, query.workspace, item);
|
|
592
|
+
if (current === null)
|
|
593
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Stored context entry is no longer retrievable');
|
|
594
|
+
const entry = readEntryRevision(database, {
|
|
595
|
+
entryId: item.entryId,
|
|
596
|
+
workspace: current.workspace,
|
|
597
|
+
revision: item.entryRevision,
|
|
598
|
+
});
|
|
300
599
|
const take = (value, budget) => Array.from(value).slice(0, Math.max(0, budget)).join('');
|
|
301
600
|
const count = (value) => Array.from(value).length;
|
|
302
601
|
const title = take(entry.title, remaining);
|
|
@@ -305,6 +604,12 @@ function storedContext(database, query, delivery) {
|
|
|
305
604
|
remaining -= count(summary ?? '');
|
|
306
605
|
const bodyPreview = take(entry.body, remaining);
|
|
307
606
|
remaining -= count(bodyPreview);
|
|
607
|
+
const characterCount = count(title) + count(summary ?? '') + count(bodyPreview);
|
|
608
|
+
const truncated = count(title) < count(entry.title)
|
|
609
|
+
|| (entry.summary !== null && count(summary ?? '') < count(entry.summary))
|
|
610
|
+
|| count(bodyPreview) < count(entry.body);
|
|
611
|
+
totalCharacterCount += characterCount;
|
|
612
|
+
anyTruncated ||= truncated;
|
|
308
613
|
return {
|
|
309
614
|
entryId: item.entryId,
|
|
310
615
|
entryRevision: item.entryRevision,
|
|
@@ -315,12 +620,16 @@ function storedContext(database, query, delivery) {
|
|
|
315
620
|
title,
|
|
316
621
|
summary,
|
|
317
622
|
bodyPreview,
|
|
318
|
-
characterCount
|
|
319
|
-
truncated
|
|
623
|
+
characterCount,
|
|
624
|
+
truncated,
|
|
320
625
|
},
|
|
321
626
|
untrusted: true,
|
|
627
|
+
...(item.origin === undefined ? {} : { origin: item.origin }),
|
|
322
628
|
};
|
|
323
629
|
});
|
|
630
|
+
if (totalCharacterCount !== delivery.charCount || anyTruncated !== delivery.truncated) {
|
|
631
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Stored context character accounting is invalid');
|
|
632
|
+
}
|
|
324
633
|
return {
|
|
325
634
|
deliveryId: delivery.deliveryId,
|
|
326
635
|
runId: delivery.runId,
|
|
@@ -332,13 +641,87 @@ function storedContext(database, query, delivery) {
|
|
|
332
641
|
untrusted: true,
|
|
333
642
|
};
|
|
334
643
|
}
|
|
644
|
+
function storedDeliveryIsRetrievable(database, query, delivery) {
|
|
645
|
+
if (delivery.throughSequence !== query.throughSequence) {
|
|
646
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Stored context delivery sequence is invalid');
|
|
647
|
+
}
|
|
648
|
+
if (!delivery.items.every((item) => currentRetrievableDeliveryEntry(database, query.workspace, item) !== null))
|
|
649
|
+
return false;
|
|
650
|
+
return !(delivery.taskProfileHash !== query.profileHash
|
|
651
|
+
|| delivery.queryHash !== query.queryHash
|
|
652
|
+
|| delivery.policyVersion !== CONTEXT_BROKER_POLICY_VERSION
|
|
653
|
+
|| (delivery.scoreSchemaVersion ?? 1) !== 1
|
|
654
|
+
|| delivery.charBudget !== query.characterBudget
|
|
655
|
+
|| delivery.items.length > query.limit);
|
|
656
|
+
}
|
|
657
|
+
function assertPreparedSelectedEntries(database, query, result) {
|
|
658
|
+
if (result.context !== null
|
|
659
|
+
&& result.context.items.some((item) => currentRetrievableDeliveryEntry(database, query.workspace, item) === null)) {
|
|
660
|
+
throw new KiokukoError('CONFLICT', 'Context delivery selection changed before return');
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
function assertPreparedBrokerState(database, query, result, expectedHistoryStateHash = query.deliveryHistoryStateHash) {
|
|
664
|
+
assertPreparedProjectState(database, query);
|
|
665
|
+
if (query.run === null) {
|
|
666
|
+
if (query.retrievalStateHash !== null
|
|
667
|
+
&& contextRetrievalStateHash(database, query.selectionWorkspaces, { includeEcosystem: query.includeEcosystem }) !== query.retrievalStateHash) {
|
|
668
|
+
throw new KiokukoError('CONFLICT', 'Context selection state changed after ranking');
|
|
669
|
+
}
|
|
670
|
+
return;
|
|
671
|
+
}
|
|
672
|
+
const current = currentRunContext(database, query.run.runId);
|
|
673
|
+
const currentStatus = current.intakeStatus === 'active' ? 'needs_answer' : current.intakeStatus;
|
|
674
|
+
if (query.runStateHash === null
|
|
675
|
+
|| current.stateHash !== query.runStateHash
|
|
676
|
+
|| current.run.workspace !== query.workspace
|
|
677
|
+
|| current.run.status !== query.run.status
|
|
678
|
+
|| current.run.lastSequence !== query.throughSequence
|
|
679
|
+
|| current.intakeSessionId !== query.intakeSessionId
|
|
680
|
+
|| currentStatus !== query.runStatus
|
|
681
|
+
|| current.profileHash !== query.profileHash
|
|
682
|
+
|| canonicalContentHash([...current.recommendedTags].sort()) !== canonicalContentHash([...query.recommendedTags].sort())) {
|
|
683
|
+
throw new KiokukoError('CONFLICT', 'Context delivery conflicts with current run state');
|
|
684
|
+
}
|
|
685
|
+
if (result.context !== null && query.run.status !== 'active') {
|
|
686
|
+
throw new KiokukoError('CONFLICT', 'Context delivery conflicts with current run state');
|
|
687
|
+
}
|
|
688
|
+
assertPreparedSelectedEntries(database, query, result);
|
|
689
|
+
if (query.retrievalStateHash !== null
|
|
690
|
+
&& contextRetrievalStateHash(database, query.selectionWorkspaces, { includeEcosystem: query.includeEcosystem }) !== query.retrievalStateHash) {
|
|
691
|
+
throw new KiokukoError('CONFLICT', 'Context selection state changed after ranking');
|
|
692
|
+
}
|
|
693
|
+
if (expectedHistoryStateHash !== null) {
|
|
694
|
+
const currentHistory = priorData(database, query, query.deliveryHistoryExcludeQueryHash === null
|
|
695
|
+
? {}
|
|
696
|
+
: { excludeDeliveredQueryHash: query.deliveryHistoryExcludeQueryHash });
|
|
697
|
+
if (currentHistory.stateHash !== expectedHistoryStateHash) {
|
|
698
|
+
throw new KiokukoError('CONFLICT', 'Context delivery history changed after ranking');
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
function replayableDelivery(database, query) {
|
|
703
|
+
if (query.run === null)
|
|
704
|
+
return { delivery: null, found: false };
|
|
705
|
+
const rows = database.prepare(`
|
|
706
|
+
SELECT delivery_id AS deliveryId
|
|
707
|
+
FROM context_deliveries
|
|
708
|
+
WHERE run_id = ? AND query_hash = ?
|
|
709
|
+
ORDER BY delivery_id ASC
|
|
710
|
+
`).all(query.run.runId, query.queryHash);
|
|
711
|
+
for (const row of rows) {
|
|
712
|
+
const delivery = readContextDelivery(database, { workspace: query.workspace, deliveryId: row.deliveryId });
|
|
713
|
+
if (storedDeliveryIsRetrievable(database, query, delivery)
|
|
714
|
+
&& deliveryHistoryIsAttested(database, query, delivery)) {
|
|
715
|
+
return { delivery, found: true };
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
return { delivery: null, found: rows.length > 0 };
|
|
719
|
+
}
|
|
335
720
|
export class ContextBroker {
|
|
336
721
|
database;
|
|
337
|
-
options;
|
|
338
722
|
inFlight = new Map();
|
|
339
|
-
constructor(database
|
|
723
|
+
constructor(database) {
|
|
340
724
|
this.database = database;
|
|
341
|
-
this.options = options;
|
|
342
725
|
}
|
|
343
726
|
listDeliveries(input) {
|
|
344
727
|
const context = currentRunContext(this.database, input.runId);
|
|
@@ -353,6 +736,20 @@ export class ContextBroker {
|
|
|
353
736
|
};
|
|
354
737
|
}
|
|
355
738
|
async query(rawInput, persistence = {}) {
|
|
739
|
+
return this.execute(rawInput, normalizePersistence(persistence));
|
|
740
|
+
}
|
|
741
|
+
async queryGated(rawInput, decide, persistence = {}) {
|
|
742
|
+
const normalizedPersistence = normalizePersistence(persistence);
|
|
743
|
+
const input = normalizeInput(rawInput);
|
|
744
|
+
const query = preparedQuery(this.database, input);
|
|
745
|
+
const prepared = await this.prepareResult(query);
|
|
746
|
+
const decision = normalizedGateDecision(decide(prepared.result));
|
|
747
|
+
const broker = decision.persist
|
|
748
|
+
? await this.persistPrepared(prepared, normalizedPersistence, query, decision.assertBeforePersist)
|
|
749
|
+
: this.validatePrepared(prepared, query, decision.assertBeforePersist);
|
|
750
|
+
return { broker, value: decision.value };
|
|
751
|
+
}
|
|
752
|
+
async execute(rawInput, persistence) {
|
|
356
753
|
const input = normalizeInput(rawInput);
|
|
357
754
|
const query = preparedQuery(this.database, input);
|
|
358
755
|
const previous = this.inFlight.get(query.queryHash);
|
|
@@ -369,6 +766,10 @@ export class ContextBroker {
|
|
|
369
766
|
}
|
|
370
767
|
}
|
|
371
768
|
async queryPrepared(query, persistence) {
|
|
769
|
+
const prepared = await this.prepareResult(query);
|
|
770
|
+
return this.persistPrepared(prepared, persistence, query);
|
|
771
|
+
}
|
|
772
|
+
async prepareResult(query) {
|
|
372
773
|
const base = {
|
|
373
774
|
status: query.runStatus,
|
|
374
775
|
taskProfile: { ...query.taskProfile },
|
|
@@ -379,63 +780,140 @@ export class ContextBroker {
|
|
|
379
780
|
projection: query.projection,
|
|
380
781
|
context: null,
|
|
381
782
|
recommendations: query.projection === null ? [] : buildRecommendations({ projection: query.projection, broker: {} }),
|
|
382
|
-
externalSyncSummary: emptyExternalSummary(),
|
|
383
783
|
};
|
|
384
784
|
if (query.runStatus === 'needs_answer')
|
|
385
|
-
return base;
|
|
386
|
-
const
|
|
387
|
-
const
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
throw error;
|
|
395
|
-
}
|
|
396
|
-
})();
|
|
397
|
-
if (existing) {
|
|
785
|
+
return { result: base, replayDelivery: null, pendingDelivery: null };
|
|
786
|
+
const replay = replayableDelivery(this.database, query);
|
|
787
|
+
const excludeDeliveredQueryHash = replay.delivery === null && replay.found ? query.queryHash : undefined;
|
|
788
|
+
const prior = priorData(this.database, query, excludeDeliveredQueryHash === undefined
|
|
789
|
+
? {}
|
|
790
|
+
: { excludeDeliveredQueryHash });
|
|
791
|
+
query.deliveryHistoryStateHash = prior.stateHash;
|
|
792
|
+
query.deliveryHistoryExcludeQueryHash = excludeDeliveredQueryHash ?? null;
|
|
793
|
+
if (replay.delivery !== null) {
|
|
398
794
|
return {
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
795
|
+
result: {
|
|
796
|
+
...base,
|
|
797
|
+
context: storedContext(this.database, query, replay.delivery),
|
|
798
|
+
recommendations: query.projection === null ? [] : buildRecommendations({ projection: query.projection, broker: { staleDeliveredEntries: prior.stale } }),
|
|
799
|
+
},
|
|
800
|
+
replayDelivery: replay.delivery,
|
|
801
|
+
pendingDelivery: null,
|
|
403
802
|
};
|
|
404
803
|
}
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
const prepared = await prepareOfficialSourceSync({
|
|
409
|
-
workspace: query.workspace,
|
|
410
|
-
task: query.task,
|
|
411
|
-
profile: query.taskProfile,
|
|
412
|
-
recommendedTags: query.recommendedTags,
|
|
413
|
-
...(this.options.fetchImpl === undefined ? {} : { fetchImpl: this.options.fetchImpl }),
|
|
414
|
-
});
|
|
415
|
-
const result = persistence.persistSources === undefined
|
|
416
|
-
? persistOfficialSourceSync(this.database, { workspace: query.workspace, prepared })
|
|
417
|
-
: await persistence.persistSources(query.workspace, prepared);
|
|
418
|
-
externalSyncSummary = { attempted: result.attempted, imported: result.imported, sources: result.sources };
|
|
419
|
-
ranked = rank(this.database, query, priorData(this.database, query));
|
|
804
|
+
const ranked = await rank(this.database, query, prior);
|
|
805
|
+
if (query.run !== null && prior.stateHash === null) {
|
|
806
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Stored context delivery history is invalid');
|
|
420
807
|
}
|
|
808
|
+
const deliveryQuery = query.run === null
|
|
809
|
+
? query
|
|
810
|
+
: {
|
|
811
|
+
...query,
|
|
812
|
+
deliveryId: historyAttestedDeliveryId(query, prior.stateHash, query.deliveryHistoryExcludeQueryHash),
|
|
813
|
+
};
|
|
421
814
|
const recommendations = query.projection === null
|
|
422
815
|
? []
|
|
423
816
|
: buildRecommendations({ projection: query.projection, broker: { staleDeliveredEntries: prior.stale } });
|
|
424
|
-
const context = outputContext(
|
|
425
|
-
if (
|
|
426
|
-
return { ...base, context, recommendations,
|
|
817
|
+
const context = outputContext(deliveryQuery, ranked, null);
|
|
818
|
+
if (deliveryQuery.deliveryId === null || deliveryQuery.run === null) {
|
|
819
|
+
return { result: { ...base, context, recommendations }, replayDelivery: null, pendingDelivery: null };
|
|
427
820
|
}
|
|
428
|
-
const deliveryRequest = deliveryInput(
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
:
|
|
432
|
-
|
|
821
|
+
const deliveryRequest = deliveryInput(deliveryQuery, ranked);
|
|
822
|
+
return {
|
|
823
|
+
result: { ...base, context, recommendations },
|
|
824
|
+
replayDelivery: null,
|
|
825
|
+
pendingDelivery: { query: deliveryQuery, ranked, input: deliveryRequest },
|
|
826
|
+
};
|
|
827
|
+
}
|
|
828
|
+
async persistPrepared(prepared, persistence, query, assertBeforePersist) {
|
|
829
|
+
if (prepared.pendingDelivery === null) {
|
|
830
|
+
return withImmediateTransaction(this.database, () => {
|
|
831
|
+
if (prepared.replayDelivery !== null) {
|
|
832
|
+
assertPreparedSelectedEntries(this.database, query, prepared.result);
|
|
833
|
+
assertReplayDeliveryUnchanged(this.database, prepared.replayDelivery);
|
|
834
|
+
}
|
|
835
|
+
assertPreparedBrokerState(this.database, query, prepared.result);
|
|
836
|
+
if (assertBeforePersist !== undefined) {
|
|
837
|
+
assertBeforePersist();
|
|
838
|
+
if (prepared.replayDelivery !== null) {
|
|
839
|
+
assertPreparedSelectedEntries(this.database, query, prepared.result);
|
|
840
|
+
assertReplayDeliveryUnchanged(this.database, prepared.replayDelivery);
|
|
841
|
+
}
|
|
842
|
+
assertPreparedBrokerState(this.database, query, prepared.result);
|
|
843
|
+
}
|
|
844
|
+
return prepared.result;
|
|
845
|
+
});
|
|
846
|
+
}
|
|
847
|
+
const pendingDelivery = prepared.pendingDelivery;
|
|
848
|
+
let committedDelivery = null;
|
|
849
|
+
let committedHistoryStateHash = null;
|
|
850
|
+
let invocationCount = 0;
|
|
851
|
+
let acceptingInvocation = true;
|
|
852
|
+
const persist = () => {
|
|
853
|
+
if (!acceptingInvocation) {
|
|
854
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Context broker write adapter invoked persistence outside its queue operation');
|
|
855
|
+
}
|
|
856
|
+
invocationCount += 1;
|
|
857
|
+
if (invocationCount !== 1) {
|
|
858
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Context broker write adapter invoked persistence more than once');
|
|
859
|
+
}
|
|
860
|
+
committedDelivery = withImmediateTransaction(this.database, () => {
|
|
861
|
+
assertPreparedBrokerState(this.database, query, prepared.result);
|
|
862
|
+
if (assertBeforePersist !== undefined) {
|
|
863
|
+
assertBeforePersist();
|
|
864
|
+
assertPreparedBrokerState(this.database, query, prepared.result);
|
|
865
|
+
}
|
|
866
|
+
const delivery = recordContextDeliveryInTransaction(this.database, pendingDelivery.input);
|
|
867
|
+
committedHistoryStateHash = priorData(this.database, query, query.deliveryHistoryExcludeQueryHash === null
|
|
868
|
+
? {}
|
|
869
|
+
: { excludeDeliveredQueryHash: query.deliveryHistoryExcludeQueryHash }).stateHash;
|
|
870
|
+
return delivery;
|
|
871
|
+
});
|
|
872
|
+
return committedDelivery;
|
|
873
|
+
};
|
|
874
|
+
let returned;
|
|
875
|
+
try {
|
|
876
|
+
returned = persistence.enqueueWrite === undefined
|
|
877
|
+
? persist()
|
|
878
|
+
: await persistence.enqueueWrite(persist);
|
|
879
|
+
}
|
|
880
|
+
finally {
|
|
881
|
+
acceptingInvocation = false;
|
|
882
|
+
}
|
|
883
|
+
const committed = committedDelivery;
|
|
884
|
+
const committedHistory = committedHistoryStateHash;
|
|
885
|
+
if (invocationCount !== 1 || committed === null || committedHistory === null || returned !== committed) {
|
|
886
|
+
throw new KiokukoError('INTEGRITY_ERROR', 'Context broker write adapter returned an invalid result');
|
|
887
|
+
}
|
|
888
|
+
withImmediateTransaction(this.database, () => {
|
|
889
|
+
assertReplayDeliveryUnchanged(this.database, committed);
|
|
890
|
+
if (!deliveryHistoryIsAttested(this.database, query, committed)) {
|
|
891
|
+
throw new KiokukoError('CONFLICT', 'Context delivery history changed after ranking');
|
|
892
|
+
}
|
|
893
|
+
assertPreparedBrokerState(this.database, query, prepared.result, committedHistory);
|
|
894
|
+
});
|
|
895
|
+
return {
|
|
896
|
+
...prepared.result,
|
|
897
|
+
context: outputContext(pendingDelivery.query, pendingDelivery.ranked, committed),
|
|
898
|
+
};
|
|
899
|
+
}
|
|
900
|
+
validatePrepared(prepared, query, assertBeforeReturn) {
|
|
901
|
+
return withImmediateTransaction(this.database, () => {
|
|
902
|
+
if (prepared.replayDelivery !== null) {
|
|
903
|
+
assertPreparedSelectedEntries(this.database, query, prepared.result);
|
|
904
|
+
assertReplayDeliveryUnchanged(this.database, prepared.replayDelivery);
|
|
905
|
+
}
|
|
906
|
+
assertPreparedBrokerState(this.database, query, prepared.result);
|
|
907
|
+
if (assertBeforeReturn !== undefined) {
|
|
908
|
+
assertBeforeReturn();
|
|
909
|
+
if (prepared.replayDelivery !== null) {
|
|
910
|
+
assertPreparedSelectedEntries(this.database, query, prepared.result);
|
|
911
|
+
assertReplayDeliveryUnchanged(this.database, prepared.replayDelivery);
|
|
912
|
+
}
|
|
913
|
+
assertPreparedBrokerState(this.database, query, prepared.result);
|
|
914
|
+
}
|
|
915
|
+
return prepared.result;
|
|
916
|
+
});
|
|
433
917
|
}
|
|
434
|
-
}
|
|
435
|
-
export function contextBrokerQueryHash(input) {
|
|
436
|
-
return createHash('sha256').update(JSON.stringify(input), 'utf8').digest('hex');
|
|
437
|
-
}
|
|
438
|
-
export function newContextDeliveryId() {
|
|
439
|
-
return `context-${randomUUID()}`;
|
|
440
918
|
}
|
|
441
919
|
//# sourceMappingURL=broker.js.map
|