@segmentstream/ontology 0.0.0-stage → 0.92.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/NOTICE +2 -0
- package/README.md +1655 -2
- package/dist/action.d.ts +193 -0
- package/dist/action.js +41 -0
- package/dist/agent-chat.d.ts +44 -0
- package/dist/agent-chat.js +91 -0
- package/dist/agent-task-contract.d.ts +64 -0
- package/dist/agent-task-contract.js +15 -0
- package/dist/agent-task.d.ts +39 -0
- package/dist/agent-task.js +112 -0
- package/dist/analyze.d.ts +215 -0
- package/dist/analyze.js +2438 -0
- package/dist/app-feedback.d.ts +167 -0
- package/dist/app-feedback.js +176 -0
- package/dist/authoring-input.d.ts +3 -0
- package/dist/authoring-input.js +107 -0
- package/dist/authoring-names.d.ts +4 -0
- package/dist/authoring-names.js +13 -0
- package/dist/authoring-records.d.ts +35 -0
- package/dist/authoring-records.js +264 -0
- package/dist/authoring.d.ts +15 -0
- package/dist/authoring.js +331 -0
- package/dist/bin/check.d.ts +30 -0
- package/dist/bin/check.js +99 -0
- package/dist/bin/load.d.ts +48 -0
- package/dist/bin/load.js +139 -0
- package/dist/bin/main.d.ts +31 -0
- package/dist/bin/main.js +121 -0
- package/dist/bin/migrate.d.ts +57 -0
- package/dist/bin/migrate.js +170 -0
- package/dist/bin/output.d.ts +31 -0
- package/dist/bin/output.js +84 -0
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +31 -0
- package/dist/blob.d.ts +52 -0
- package/dist/blob.js +87 -0
- package/dist/channel-session.d.ts +16 -0
- package/dist/channel-session.js +16 -0
- package/dist/chat.d.ts +43 -0
- package/dist/chat.js +34 -0
- package/dist/confirmation.d.ts +46 -0
- package/dist/confirmation.js +41 -0
- package/dist/connection.d.ts +213 -0
- package/dist/connection.js +289 -0
- package/dist/deployment.d.ts +35 -0
- package/dist/deployment.js +76 -0
- package/dist/diagnostics.d.ts +27 -0
- package/dist/diagnostics.js +106 -0
- package/dist/emails.d.ts +70 -0
- package/dist/emails.js +221 -0
- package/dist/entity.d.ts +331 -0
- package/dist/entity.js +153 -0
- package/dist/errors.d.ts +154 -0
- package/dist/errors.js +109 -0
- package/dist/feedback-config.d.ts +24 -0
- package/dist/feedback-config.js +126 -0
- package/dist/files.d.ts +39 -0
- package/dist/files.js +4 -0
- package/dist/groups.d.ts +95 -0
- package/dist/groups.js +280 -0
- package/dist/index.d.ts +109 -0
- package/dist/index.js +70 -0
- package/dist/internal/diagnostics.js +594 -0
- package/dist/legacy.d.ts +160 -0
- package/dist/legacy.js +270 -0
- package/dist/manifest-compatibility.d.ts +8 -0
- package/dist/manifest-compatibility.js +87 -0
- package/dist/manifest.d.ts +3329 -0
- package/dist/manifest.js +757 -0
- package/dist/me.d.ts +46 -0
- package/dist/me.js +109 -0
- package/dist/metric-filters.d.ts +48 -0
- package/dist/metric-filters.js +252 -0
- package/dist/metric-routes.d.ts +132 -0
- package/dist/metric-routes.js +498 -0
- package/dist/metric.d.ts +172 -0
- package/dist/metric.js +132 -0
- package/dist/migrate/apply.d.ts +94 -0
- package/dist/migrate/apply.js +526 -0
- package/dist/migrate/errors.d.ts +46 -0
- package/dist/migrate/errors.js +38 -0
- package/dist/migrate/index.d.ts +10 -0
- package/dist/migrate/index.js +7 -0
- package/dist/migrate/model.d.ts +2311 -0
- package/dist/migrate/model.js +148 -0
- package/dist/migrate/plan.d.ts +51 -0
- package/dist/migrate/plan.js +1856 -0
- package/dist/migrate/preview.d.ts +13 -0
- package/dist/migrate/preview.js +65 -0
- package/dist/migrate/storage.d.ts +226 -0
- package/dist/migrate/storage.js +774 -0
- package/dist/model-metrics.d.ts +22 -0
- package/dist/model-metrics.js +545 -0
- package/dist/names.d.ts +49 -0
- package/dist/names.js +110 -0
- package/dist/navigation-artifact.d.ts +13 -0
- package/dist/navigation-artifact.js +11 -0
- package/dist/navigation-catalog.d.ts +55 -0
- package/dist/navigation-catalog.js +297 -0
- package/dist/nitro-navigation.d.ts +3 -0
- package/dist/nitro-navigation.js +64 -0
- package/dist/nitro-workflows.d.ts +108 -0
- package/dist/nitro-workflows.js +286 -0
- package/dist/nitro.d.ts +40 -0
- package/dist/nitro.js +50 -0
- package/dist/ontology.d.ts +41 -0
- package/dist/ontology.js +46 -0
- package/dist/permissions.d.ts +198 -0
- package/dist/permissions.js +272 -0
- package/dist/property.d.ts +188 -0
- package/dist/property.js +301 -0
- package/dist/query.d.ts +245 -0
- package/dist/query.js +615 -0
- package/dist/relationship.d.ts +99 -0
- package/dist/relationship.js +33 -0
- package/dist/render.d.ts +81 -0
- package/dist/render.js +512 -0
- package/dist/replication/baseline.d.ts +51 -0
- package/dist/replication/baseline.js +215 -0
- package/dist/replication/bigquery.d.ts +37 -0
- package/dist/replication/bigquery.js +211 -0
- package/dist/replication/coverage.d.ts +14 -0
- package/dist/replication/coverage.js +53 -0
- package/dist/replication/evolution.d.ts +25 -0
- package/dist/replication/evolution.js +184 -0
- package/dist/replication/identities.d.ts +6 -0
- package/dist/replication/identities.js +47 -0
- package/dist/replication/legacy-baseline.d.ts +27 -0
- package/dist/replication/legacy-baseline.js +109 -0
- package/dist/replication/legacy-store.d.ts +19 -0
- package/dist/replication/legacy-store.js +63 -0
- package/dist/replication/lineage.d.ts +36 -0
- package/dist/replication/lineage.js +72 -0
- package/dist/replication/migrate.d.ts +21 -0
- package/dist/replication/migrate.js +84 -0
- package/dist/replication/model.d.ts +52 -0
- package/dist/replication/model.js +99 -0
- package/dist/replication/scans.d.ts +34 -0
- package/dist/replication/scans.js +158 -0
- package/dist/replication/schema.d.ts +11 -0
- package/dist/replication/schema.js +226 -0
- package/dist/replication/shadow-schema.d.ts +4 -0
- package/dist/replication/shadow-schema.js +61 -0
- package/dist/replication/shadow.d.ts +127 -0
- package/dist/replication/shadow.js +614 -0
- package/dist/replication/source-replacement.d.ts +33 -0
- package/dist/replication/source-replacement.js +76 -0
- package/dist/replication/store.d.ts +36 -0
- package/dist/replication/store.js +382 -0
- package/dist/replication/transaction.d.ts +23 -0
- package/dist/replication/transaction.js +88 -0
- package/dist/role.d.ts +61 -0
- package/dist/role.js +76 -0
- package/dist/runtime/action-deadlocks.d.ts +21 -0
- package/dist/runtime/action-deadlocks.js +130 -0
- package/dist/runtime/action-transactions.d.ts +35 -0
- package/dist/runtime/action-transactions.js +54 -0
- package/dist/runtime/agent-counters.d.ts +26 -0
- package/dist/runtime/agent-counters.js +98 -0
- package/dist/runtime/agent-tasks.d.ts +63 -0
- package/dist/runtime/agent-tasks.js +120 -0
- package/dist/runtime/agents.d.ts +15 -0
- package/dist/runtime/agents.js +457 -0
- package/dist/runtime/batch-diagnostics.d.ts +22 -0
- package/dist/runtime/batch-diagnostics.js +89 -0
- package/dist/runtime/batch.d.ts +52 -0
- package/dist/runtime/batch.js +534 -0
- package/dist/runtime/channel-session-revocation.d.ts +3 -0
- package/dist/runtime/channel-session-revocation.js +5 -0
- package/dist/runtime/channel-sessions.d.ts +4 -0
- package/dist/runtime/channel-sessions.js +61 -0
- package/dist/runtime/confirmations.d.ts +29 -0
- package/dist/runtime/confirmations.js +57 -0
- package/dist/runtime/cursor.d.ts +23 -0
- package/dist/runtime/cursor.js +100 -0
- package/dist/runtime/deployment.d.ts +7 -0
- package/dist/runtime/deployment.js +4 -0
- package/dist/runtime/errors.d.ts +118 -0
- package/dist/runtime/errors.js +109 -0
- package/dist/runtime/federation-tables.d.ts +2 -0
- package/dist/runtime/federation-tables.js +20 -0
- package/dist/runtime/federation.d.ts +42 -0
- package/dist/runtime/federation.js +222 -0
- package/dist/runtime/files.d.ts +39 -0
- package/dist/runtime/files.js +44 -0
- package/dist/runtime/generated-actions.d.ts +37 -0
- package/dist/runtime/generated-actions.js +307 -0
- package/dist/runtime/history.d.ts +91 -0
- package/dist/runtime/history.js +77 -0
- package/dist/runtime/ids.d.ts +6 -0
- package/dist/runtime/ids.js +39 -0
- package/dist/runtime/member-tables.d.ts +8 -0
- package/dist/runtime/member-tables.js +33 -0
- package/dist/runtime/member-writes.d.ts +78 -0
- package/dist/runtime/member-writes.js +202 -0
- package/dist/runtime/metric-query.d.ts +19 -0
- package/dist/runtime/metric-query.js +411 -0
- package/dist/runtime/model.d.ts +67 -0
- package/dist/runtime/model.js +150 -0
- package/dist/runtime/new-user-hook.d.ts +6 -0
- package/dist/runtime/new-user-hook.js +37 -0
- package/dist/runtime/oauth.d.ts +9 -0
- package/dist/runtime/oauth.js +299 -0
- package/dist/runtime/pipeline.d.ts +155 -0
- package/dist/runtime/pipeline.js +597 -0
- package/dist/runtime/postgres-tls.d.ts +10 -0
- package/dist/runtime/postgres-tls.js +14 -0
- package/dist/runtime/principals.d.ts +302 -0
- package/dist/runtime/principals.js +1307 -0
- package/dist/runtime/reads.d.ts +55 -0
- package/dist/runtime/reads.js +313 -0
- package/dist/runtime/records.d.ts +42 -0
- package/dist/runtime/records.js +245 -0
- package/dist/runtime/resolve-agent-identity.d.ts +6 -0
- package/dist/runtime/resolve-agent-identity.js +181 -0
- package/dist/runtime/service-binding.d.ts +18 -0
- package/dist/runtime/service-binding.js +266 -0
- package/dist/runtime/sign-in-links.d.ts +68 -0
- package/dist/runtime/sign-in-links.js +147 -0
- package/dist/runtime/sql-runtime.d.ts +131 -0
- package/dist/runtime/sql-runtime.js +362 -0
- package/dist/runtime/statement.d.ts +18 -0
- package/dist/runtime/statement.js +31 -0
- package/dist/runtime/user-identities.d.ts +66 -0
- package/dist/runtime/user-identities.js +106 -0
- package/dist/runtime/user-identity-sql.d.ts +86 -0
- package/dist/runtime/user-identity-sql.js +297 -0
- package/dist/runtime/user-roles.d.ts +16 -0
- package/dist/runtime/user-roles.js +32 -0
- package/dist/runtime/validation.d.ts +16 -0
- package/dist/runtime/validation.js +26 -0
- package/dist/runtime/where.d.ts +57 -0
- package/dist/runtime/where.js +404 -0
- package/dist/runtime/workflow-admission.d.ts +49 -0
- package/dist/runtime/workflow-admission.js +92 -0
- package/dist/runtime/workflow-argument-codec.d.ts +10 -0
- package/dist/runtime/workflow-argument-codec.js +120 -0
- package/dist/runtime/workflow-arguments.d.ts +17 -0
- package/dist/runtime/workflow-arguments.js +99 -0
- package/dist/runtime/workflow-starts.d.ts +203 -0
- package/dist/runtime/workflow-starts.js +493 -0
- package/dist/runtime/workflow-users.d.ts +9 -0
- package/dist/runtime/workflow-users.js +17 -0
- package/dist/runtime/workload.d.ts +25 -0
- package/dist/runtime/workload.js +24 -0
- package/dist/runtime/writes.d.ts +108 -0
- package/dist/runtime/writes.js +491 -0
- package/dist/runtime-source.d.ts +22 -0
- package/dist/runtime-source.js +28 -0
- package/dist/runtime.d.ts +310 -0
- package/dist/runtime.js +31 -0
- package/dist/server.d.ts +23 -0
- package/dist/server.js +107 -0
- package/dist/service/agent/attachments.d.ts +33 -0
- package/dist/service/agent/attachments.js +228 -0
- package/dist/service/agent/authentication.d.ts +22 -0
- package/dist/service/agent/authentication.js +58 -0
- package/dist/service/agent/confirmations.d.ts +5 -0
- package/dist/service/agent/confirmations.js +73 -0
- package/dist/service/agent/conversation-routes.d.ts +14 -0
- package/dist/service/agent/conversation-routes.js +45 -0
- package/dist/service/agent/conversations.d.ts +40 -0
- package/dist/service/agent/conversations.js +69 -0
- package/dist/service/agent/files.d.ts +12 -0
- package/dist/service/agent/files.js +69 -0
- package/dist/service/agent/protocol.d.ts +90 -0
- package/dist/service/agent/protocol.js +114 -0
- package/dist/service/agent/server.d.ts +28 -0
- package/dist/service/agent/server.js +374 -0
- package/dist/service/agent/task-caller.d.ts +21 -0
- package/dist/service/agent/task-caller.js +35 -0
- package/dist/service/agent/task-start.d.ts +53 -0
- package/dist/service/agent/task-start.js +161 -0
- package/dist/service/agent/tasks.d.ts +40 -0
- package/dist/service/agent/tasks.js +155 -0
- package/dist/service/api.d.ts +50 -0
- package/dist/service/api.js +288 -0
- package/dist/service/authentication.d.ts +227 -0
- package/dist/service/authentication.js +767 -0
- package/dist/service/caller-context.d.ts +24 -0
- package/dist/service/caller-context.js +6 -0
- package/dist/service/catalog.d.ts +42 -0
- package/dist/service/catalog.js +66 -0
- package/dist/service/channel/provider.d.ts +10 -0
- package/dist/service/channel/provider.js +1 -0
- package/dist/service/channel/providers/telegram.d.ts +18 -0
- package/dist/service/channel/providers/telegram.js +108 -0
- package/dist/service/channel/sessions.d.ts +5 -0
- package/dist/service/channel/sessions.js +53 -0
- package/dist/service/channel/sign-in.d.ts +7 -0
- package/dist/service/channel/sign-in.js +78 -0
- package/dist/service/chat/archive.d.ts +64 -0
- package/dist/service/chat/archive.js +62 -0
- package/dist/service/chat/attribution.d.ts +26 -0
- package/dist/service/chat/attribution.js +28 -0
- package/dist/service/chat/delivery.d.ts +18 -0
- package/dist/service/chat/delivery.js +251 -0
- package/dist/service/chat/diagnostics.d.ts +2 -0
- package/dist/service/chat/diagnostics.js +35 -0
- package/dist/service/chat/envelope.d.ts +96 -0
- package/dist/service/chat/envelope.js +39 -0
- package/dist/service/chat/idempotency.d.ts +19 -0
- package/dist/service/chat/idempotency.js +37 -0
- package/dist/service/chat/providers/telegram.d.ts +36 -0
- package/dist/service/chat/providers/telegram.js +133 -0
- package/dist/service/chat/reads.d.ts +25 -0
- package/dist/service/chat/reads.js +75 -0
- package/dist/service/chat/resolve.d.ts +34 -0
- package/dist/service/chat/resolve.js +150 -0
- package/dist/service/chat/routes.d.ts +23 -0
- package/dist/service/chat/routes.js +75 -0
- package/dist/service/chat/schemas.d.ts +43 -0
- package/dist/service/chat/schemas.js +31 -0
- package/dist/service/config.d.ts +218 -0
- package/dist/service/config.js +265 -0
- package/dist/service/connection-stream.d.ts +10 -0
- package/dist/service/connection-stream.js +191 -0
- package/dist/service/connections.d.ts +60 -0
- package/dist/service/connections.js +271 -0
- package/dist/service/decisions.d.ts +35 -0
- package/dist/service/decisions.js +63 -0
- package/dist/service/descriptions.d.ts +8 -0
- package/dist/service/descriptions.js +20 -0
- package/dist/service/discovery-schemas.d.ts +92 -0
- package/dist/service/discovery-schemas.js +59 -0
- package/dist/service/discovery-search.d.ts +30 -0
- package/dist/service/discovery-search.js +95 -0
- package/dist/service/discovery.d.ts +37 -0
- package/dist/service/discovery.js +436 -0
- package/dist/service/docs.d.ts +9 -0
- package/dist/service/docs.js +197 -0
- package/dist/service/errors.d.ts +145 -0
- package/dist/service/errors.js +704 -0
- package/dist/service/federation-provider.d.ts +36 -0
- package/dist/service/federation-provider.js +110 -0
- package/dist/service/federation-server.d.ts +20 -0
- package/dist/service/federation-server.js +249 -0
- package/dist/service/federation-status.d.ts +40 -0
- package/dist/service/federation-status.js +151 -0
- package/dist/service/handlers.d.ts +18 -0
- package/dist/service/handlers.js +287 -0
- package/dist/service/mcp/confirmation.d.ts +68 -0
- package/dist/service/mcp/confirmation.js +178 -0
- package/dist/service/mcp/find-input.d.ts +12 -0
- package/dist/service/mcp/find-input.js +122 -0
- package/dist/service/mcp/input-schema.d.ts +6 -0
- package/dist/service/mcp/input-schema.js +126 -0
- package/dist/service/mcp/listing.d.ts +26 -0
- package/dist/service/mcp/listing.js +92 -0
- package/dist/service/mcp/metric-tools.d.ts +85 -0
- package/dist/service/mcp/metric-tools.js +258 -0
- package/dist/service/mcp/request-log.d.ts +5 -0
- package/dist/service/mcp/request-log.js +53 -0
- package/dist/service/mcp/runtime-policy.d.ts +27 -0
- package/dist/service/mcp/runtime-policy.js +62 -0
- package/dist/service/mcp/server.d.ts +52 -0
- package/dist/service/mcp/server.js +861 -0
- package/dist/service/mcp/tools.d.ts +99 -0
- package/dist/service/mcp/tools.js +938 -0
- package/dist/service/member-file-routes.d.ts +22 -0
- package/dist/service/member-file-routes.js +52 -0
- package/dist/service/member-files.d.ts +245 -0
- package/dist/service/member-files.js +258 -0
- package/dist/service/metric-query-platform.d.ts +77 -0
- package/dist/service/metric-query-platform.js +198 -0
- package/dist/service/metric-query-scopes.d.ts +43 -0
- package/dist/service/metric-query-scopes.js +147 -0
- package/dist/service/metric-query.d.ts +48 -0
- package/dist/service/metric-query.js +200 -0
- package/dist/service/name-suggestions.d.ts +3 -0
- package/dist/service/name-suggestions.js +38 -0
- package/dist/service/navigation-schemas.d.ts +80 -0
- package/dist/service/navigation-schemas.js +49 -0
- package/dist/service/navigation.d.ts +20 -0
- package/dist/service/navigation.js +165 -0
- package/dist/service/oauth/protocol.d.ts +70 -0
- package/dist/service/oauth/protocol.js +157 -0
- package/dist/service/oauth/refresh-replay.d.ts +2 -0
- package/dist/service/oauth/refresh-replay.js +20 -0
- package/dist/service/oauth/server.d.ts +28 -0
- package/dist/service/oauth/server.js +769 -0
- package/dist/service/operations.d.ts +170 -0
- package/dist/service/operations.js +392 -0
- package/dist/service/plan.d.ts +57 -0
- package/dist/service/plan.js +96 -0
- package/dist/service/rate-limit.d.ts +22 -0
- package/dist/service/rate-limit.js +52 -0
- package/dist/service/record-reads.d.ts +21 -0
- package/dist/service/record-reads.js +155 -0
- package/dist/service/replication.d.ts +5 -0
- package/dist/service/replication.js +39 -0
- package/dist/service/runtime-contract.d.ts +508 -0
- package/dist/service/runtime-contract.js +18 -0
- package/dist/service/runtime-identity.d.ts +71 -0
- package/dist/service/runtime-identity.js +122 -0
- package/dist/service/schemas.d.ts +961 -0
- package/dist/service/schemas.js +639 -0
- package/dist/service/service.d.ts +21 -0
- package/dist/service/service.js +526 -0
- package/dist/service/warehouse-platform.d.ts +17 -0
- package/dist/service/warehouse-platform.js +122 -0
- package/dist/service/warehouse-query.d.ts +24 -0
- package/dist/service/warehouse-query.js +280 -0
- package/dist/service/webhooks.d.ts +106 -0
- package/dist/service/webhooks.js +233 -0
- package/dist/service/workflow-admission-provider.d.ts +31 -0
- package/dist/service/workflow-admission-provider.js +205 -0
- package/dist/service/workflow-argument-serialization.d.ts +2 -0
- package/dist/service/workflow-argument-serialization.js +14 -0
- package/dist/service/workflow-callback.d.ts +22 -0
- package/dist/service/workflow-callback.js +75 -0
- package/dist/service/workflow-deployment.d.ts +8 -0
- package/dist/service/workflow-deployment.js +131 -0
- package/dist/service/workflow-diagnostics.d.ts +23 -0
- package/dist/service/workflow-diagnostics.js +263 -0
- package/dist/service/workflow-errors.d.ts +26 -0
- package/dist/service/workflow-errors.js +181 -0
- package/dist/service/workflow-logging.d.ts +2 -0
- package/dist/service/workflow-logging.js +50 -0
- package/dist/service/workflow-queue-fence.d.ts +6 -0
- package/dist/service/workflow-queue-fence.js +66 -0
- package/dist/service/workflows.d.ts +200 -0
- package/dist/service/workflows.js +1549 -0
- package/dist/sign-in.d.ts +58 -0
- package/dist/sign-in.js +57 -0
- package/dist/source.d.ts +30 -0
- package/dist/source.js +107 -0
- package/dist/start-recovery-contract.d.ts +49 -0
- package/dist/start-recovery-contract.js +26 -0
- package/dist/start-recovery.d.ts +27 -0
- package/dist/start-recovery.js +81 -0
- package/dist/storage/api.d.ts +4 -0
- package/dist/storage/api.js +40 -0
- package/dist/storage/attachments.d.ts +146 -0
- package/dist/storage/attachments.js +733 -0
- package/dist/storage/authorization.d.ts +38 -0
- package/dist/storage/authorization.js +83 -0
- package/dist/storage/file-access.d.ts +17 -0
- package/dist/storage/file-access.js +8 -0
- package/dist/storage/limits.d.ts +12 -0
- package/dist/storage/limits.js +17 -0
- package/dist/storage/maintenance-auth.d.ts +20 -0
- package/dist/storage/maintenance-auth.js +24 -0
- package/dist/storage/maintenance.d.ts +11 -0
- package/dist/storage/maintenance.js +67 -0
- package/dist/storage/neon.d.ts +4 -0
- package/dist/storage/neon.js +318 -0
- package/dist/storage/operator.d.ts +11 -0
- package/dist/storage/operator.js +30 -0
- package/dist/storage/provider.d.ts +93 -0
- package/dist/storage/provider.js +36 -0
- package/dist/storage/sessions.d.ts +184 -0
- package/dist/storage/sessions.js +688 -0
- package/dist/storage/tables.d.ts +54 -0
- package/dist/storage/tables.js +205 -0
- package/dist/storage/transfers.d.ts +16 -0
- package/dist/storage/transfers.js +153 -0
- package/dist/storage/writes.d.ts +7 -0
- package/dist/storage/writes.js +88 -0
- package/dist/telegram.d.ts +35 -0
- package/dist/telegram.js +173 -0
- package/dist/user-identity.d.ts +28 -0
- package/dist/user-identity.js +106 -0
- package/dist/user.d.ts +75 -0
- package/dist/user.js +111 -0
- package/dist/warehouse-backed.d.ts +6 -0
- package/dist/warehouse-backed.js +495 -0
- package/dist/webhook-token.d.ts +11 -0
- package/dist/webhook-token.js +18 -0
- package/dist/webhooks.d.ts +40 -0
- package/dist/webhooks.js +55 -0
- package/dist/wire.d.ts +10 -0
- package/dist/wire.js +35 -0
- package/dist/workflow-runtime.d.ts +116 -0
- package/dist/workflow-runtime.js +109 -0
- package/dist/workflow-topics.d.ts +28 -0
- package/dist/workflow-topics.js +28 -0
- package/dist/workflow.d.ts +284 -0
- package/dist/workflow.js +259 -0
- package/dist/workflows.d.ts +24 -0
- package/dist/workflows.js +18 -0
- package/package.json +127 -4
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { Data } from "effect";
|
|
3
|
+
import { encodeManifest } from "../manifest.js";
|
|
4
|
+
import { effectivePermissions, isAllowed, permissionOf, READ_VERB, } from "../permissions.js";
|
|
5
|
+
import { metricDescription, metricsFor, modelMetricDescription, modelMetricsFor, } from "../render.js";
|
|
6
|
+
import { compareRefs, normalizeSearch, searchDocuments, } from "./discovery-search.js";
|
|
7
|
+
import { visibleTools } from "./mcp/tools.js";
|
|
8
|
+
export const DISCOVERY_RESULT_BYTES = 16 * 1024;
|
|
9
|
+
/** Expected metadata errors retain their public reason without exposing excluded definitions. */
|
|
10
|
+
export class DiscoveryError extends Data.TaggedError("DiscoveryError") {
|
|
11
|
+
}
|
|
12
|
+
function object(value) {
|
|
13
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
14
|
+
}
|
|
15
|
+
function digest(value) {
|
|
16
|
+
return createHash("sha256").update(JSON.stringify(value)).digest("hex");
|
|
17
|
+
}
|
|
18
|
+
function preview(text, maximum) {
|
|
19
|
+
return Array.from(text).slice(0, maximum).join("");
|
|
20
|
+
}
|
|
21
|
+
function summary(ref, name, label, description) {
|
|
22
|
+
const shortLabel = preview(label, 120);
|
|
23
|
+
const shortDescription = preview(description, 240);
|
|
24
|
+
return {
|
|
25
|
+
ref,
|
|
26
|
+
name,
|
|
27
|
+
label: shortLabel,
|
|
28
|
+
description: shortDescription,
|
|
29
|
+
summary_truncated: shortLabel !== label || shortDescription !== description,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/** At this probability or above, the decision model thinks the request concerns an entity. */
|
|
33
|
+
const RELEVANT = 0.5;
|
|
34
|
+
/** A ranking the model has not answered by then falls back to word matching. */
|
|
35
|
+
const DECISION_TIMEOUT_MS = 8000;
|
|
36
|
+
/** One yes-or-no question for the decision model: whether the request concerns this entity. */
|
|
37
|
+
function concerns(entity) {
|
|
38
|
+
const description = preview(entity.description, 240);
|
|
39
|
+
return (`Does the request concern ${entity.label} records (${entity.name})?` +
|
|
40
|
+
(description === "" ? "" : ` ${entity.label}: ${description}`));
|
|
41
|
+
}
|
|
42
|
+
/** Exactly the successful MCP result envelope, including JSON's escaped text representation. */
|
|
43
|
+
export function discoveryResultBytes(result) {
|
|
44
|
+
return Buffer.byteLength(JSON.stringify({
|
|
45
|
+
content: [{ type: "text", text: JSON.stringify(result) }],
|
|
46
|
+
structuredContent: result,
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
49
|
+
function checkHash(hash, expected) {
|
|
50
|
+
if (expected !== undefined && expected !== hash) {
|
|
51
|
+
throw new DiscoveryError({
|
|
52
|
+
error: "ontology_version_mismatch",
|
|
53
|
+
detail: "The ontology changed. Repeat the relevant discovery or inspection with the current hash.",
|
|
54
|
+
hash,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function invalidCursor() {
|
|
59
|
+
throw new DiscoveryError({
|
|
60
|
+
error: "invalid_cursor",
|
|
61
|
+
detail: "Restart this index or search; its cursor is invalid.",
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
function page(input) {
|
|
65
|
+
const scope = digest([...new Set(input.permissions)].sort(compareRefs));
|
|
66
|
+
const request = digest(input.request);
|
|
67
|
+
let start = 0;
|
|
68
|
+
if (input.after !== undefined) {
|
|
69
|
+
let cursor;
|
|
70
|
+
try {
|
|
71
|
+
if (!/^[A-Za-z0-9_-]+$/.test(input.after)) {
|
|
72
|
+
return invalidCursor();
|
|
73
|
+
}
|
|
74
|
+
cursor = JSON.parse(Buffer.from(input.after, "base64url").toString("utf8"));
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
if (error instanceof DiscoveryError) {
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
return invalidCursor();
|
|
81
|
+
}
|
|
82
|
+
if (!object(cursor) || typeof cursor.hash !== "string") {
|
|
83
|
+
return invalidCursor();
|
|
84
|
+
}
|
|
85
|
+
checkHash(input.hash, cursor.hash);
|
|
86
|
+
if (cursor.scope !== scope || cursor.request !== request || typeof cursor.last !== "string") {
|
|
87
|
+
return invalidCursor();
|
|
88
|
+
}
|
|
89
|
+
const position = input.items.findIndex(({ ref }) => ref === cursor.last);
|
|
90
|
+
if (position < 0) {
|
|
91
|
+
return invalidCursor();
|
|
92
|
+
}
|
|
93
|
+
start = position + 1;
|
|
94
|
+
}
|
|
95
|
+
const cursorAfter = (last) => Buffer.from(JSON.stringify({ hash: input.hash, scope, request, last })).toString("base64url");
|
|
96
|
+
const selected = [];
|
|
97
|
+
let result = input.result(selected, null);
|
|
98
|
+
for (const item of input.items.slice(start, start + input.limit)) {
|
|
99
|
+
const candidate = [...selected, item];
|
|
100
|
+
const more = start + candidate.length < input.items.length;
|
|
101
|
+
const next = input.result(candidate, more ? cursorAfter(item.ref) : null);
|
|
102
|
+
if (discoveryResultBytes(next) > DISCOVERY_RESULT_BYTES) {
|
|
103
|
+
if (selected.length === 0) {
|
|
104
|
+
throw new DiscoveryError({
|
|
105
|
+
error: "discovery_too_large",
|
|
106
|
+
detail: "This discovery entry exceeds the response budget.",
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
selected.push(item);
|
|
112
|
+
result = next;
|
|
113
|
+
}
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
function textFields(value, prefix = "", weight = 10) {
|
|
117
|
+
return ["name", "label", "plural", "description"].flatMap((key) => {
|
|
118
|
+
const text = value[key];
|
|
119
|
+
return typeof text === "string"
|
|
120
|
+
? [{ path: prefix + key, text, weight: key === "description" ? weight : weight + 10 }]
|
|
121
|
+
: [];
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
/** JSON Schema field descriptions, including nested properties and local definitions. */
|
|
125
|
+
function inputFields(schema, prefix = "input") {
|
|
126
|
+
const fields = [];
|
|
127
|
+
for (const [key, value] of Object.entries(schema)) {
|
|
128
|
+
if (key === "description" && typeof value === "string") {
|
|
129
|
+
fields.push({ path: `${prefix}.description`, text: value, weight: 10 });
|
|
130
|
+
}
|
|
131
|
+
else if (key === "properties" && object(value)) {
|
|
132
|
+
for (const [name, property] of Object.entries(value)) {
|
|
133
|
+
fields.push({ path: `${prefix}.properties.${name}.name`, text: name, weight: 20 });
|
|
134
|
+
if (object(property)) {
|
|
135
|
+
fields.push(...inputFields(property, `${prefix}.properties.${name}`));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
else if (object(value)) {
|
|
140
|
+
fields.push(...inputFields(value, `${prefix}.${key}`));
|
|
141
|
+
}
|
|
142
|
+
else if (Array.isArray(value)) {
|
|
143
|
+
value.forEach((branch, index) => {
|
|
144
|
+
if (object(branch)) {
|
|
145
|
+
fields.push(...inputFields(branch, `${prefix}.${key}.${index}`));
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return fields;
|
|
151
|
+
}
|
|
152
|
+
/** Immutable deployment metadata; authorization and projections are recomputed for every caller. */
|
|
153
|
+
export function createDiscovery(built, tools) {
|
|
154
|
+
const { manifest } = built.plan.ontology;
|
|
155
|
+
const wire = encodeManifest(manifest);
|
|
156
|
+
const wireEntities = new Map(wire.entities.map((entity) => [entity.name, entity]));
|
|
157
|
+
const actionDefinitions = new Map();
|
|
158
|
+
const incoming = new Map();
|
|
159
|
+
for (const source of manifest.entities) {
|
|
160
|
+
source.relationships.forEach((relationship, index) => {
|
|
161
|
+
const edges = incoming.get(relationship.to) ?? [];
|
|
162
|
+
edges.push({ source, relationship, index });
|
|
163
|
+
incoming.set(relationship.to, edges);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
for (const tool of tools) {
|
|
167
|
+
if (tool.target.kind !== "action") {
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
const { planned, action } = tool.target;
|
|
171
|
+
actionDefinitions.set(`action:${planned.name}.${action.name}`, {
|
|
172
|
+
name: action.name,
|
|
173
|
+
entity: { ref: `entity:${planned.name}` },
|
|
174
|
+
tool_name: tool.name,
|
|
175
|
+
generated: action.generated,
|
|
176
|
+
description: action.action.description,
|
|
177
|
+
tool_description: tool.description,
|
|
178
|
+
permissions: tool.permissions,
|
|
179
|
+
input_schema: tool.inputSchema,
|
|
180
|
+
annotations: tool.annotations,
|
|
181
|
+
connections: action.action.connections.map(({ key, description }) => ({ key, description })),
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
function projection(principal, caller) {
|
|
185
|
+
const permissions = effectivePermissions(principal);
|
|
186
|
+
const holder = { permissions };
|
|
187
|
+
const visibleEntities = new Map(manifest.entities
|
|
188
|
+
.filter((entity) => entity.source === undefined ||
|
|
189
|
+
isAllowed(entity.permissions?.read ?? permissionOf(entity.name, READ_VERB), holder))
|
|
190
|
+
.map((entity) => [entity.name, entity]));
|
|
191
|
+
const actions = new Map();
|
|
192
|
+
for (const tool of visibleTools(tools, principal, caller)) {
|
|
193
|
+
if (tool.target.kind === "action") {
|
|
194
|
+
const ref = `action:${tool.target.planned.name}.${tool.target.action.name}`;
|
|
195
|
+
actions.set(ref, actionDefinitions.get(ref));
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
const metrics = new Map();
|
|
199
|
+
for (const { name, entity, metric } of metricsFor(manifest, permissions)) {
|
|
200
|
+
const encoded = wireEntities.get(entity.name)?.metrics;
|
|
201
|
+
metrics.set(`metric:${name}`, {
|
|
202
|
+
...encoded.find((candidate) => candidate.name === metric.name),
|
|
203
|
+
name,
|
|
204
|
+
entity: { ref: `entity:${entity.name}` },
|
|
205
|
+
explanation: metricDescription(entity, metric),
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
const model = wire.metrics;
|
|
209
|
+
for (const metric of modelMetricsFor(manifest, permissions)) {
|
|
210
|
+
metrics.set(`metric:${metric.name}`, {
|
|
211
|
+
...model?.find((candidate) => candidate.name === metric.name),
|
|
212
|
+
explanation: modelMetricDescription(metric),
|
|
213
|
+
input_refs: metric.inputs.map((name) => `metric:${name}`),
|
|
214
|
+
computation: "Computed on the combined results of its input entity metrics; " +
|
|
215
|
+
"division by zero and missing inputs remain null.",
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
function relationships(entity) {
|
|
219
|
+
const declared = entity.relationships.map((relationship, index) => ({
|
|
220
|
+
...(wireEntities.get(entity.name)?.relationships)[index],
|
|
221
|
+
direction: "declared",
|
|
222
|
+
target: {
|
|
223
|
+
ref: `entity:${relationship.to}`,
|
|
224
|
+
inspectable: visibleEntities.has(relationship.to),
|
|
225
|
+
},
|
|
226
|
+
}));
|
|
227
|
+
const inverse = (incoming.get(entity.name) ?? []).flatMap(({ source, relationship, index }) => {
|
|
228
|
+
const encoded = (wireEntities.get(source.name)?.relationships)[index];
|
|
229
|
+
return [
|
|
230
|
+
{
|
|
231
|
+
name: relationship.inverse,
|
|
232
|
+
inverse: relationship.name,
|
|
233
|
+
to: source.name,
|
|
234
|
+
cardinality: "many",
|
|
235
|
+
optional: true,
|
|
236
|
+
direction: "inverse",
|
|
237
|
+
description: relationship.description,
|
|
238
|
+
phrase: [relationship.phrase[1], relationship.phrase[0]],
|
|
239
|
+
declaration: { entity: { ref: `entity:${source.name}` }, relationship: encoded },
|
|
240
|
+
...(relationship.on === undefined
|
|
241
|
+
? {}
|
|
242
|
+
: {
|
|
243
|
+
on: {
|
|
244
|
+
property: relationship.on.targetProperty,
|
|
245
|
+
target_property: relationship.on.property,
|
|
246
|
+
},
|
|
247
|
+
}),
|
|
248
|
+
target: {
|
|
249
|
+
ref: `entity:${source.name}`,
|
|
250
|
+
inspectable: visibleEntities.has(source.name),
|
|
251
|
+
},
|
|
252
|
+
},
|
|
253
|
+
];
|
|
254
|
+
});
|
|
255
|
+
return [...declared, ...inverse];
|
|
256
|
+
}
|
|
257
|
+
function documents() {
|
|
258
|
+
const documents = [];
|
|
259
|
+
for (const entity of visibleEntities.values()) {
|
|
260
|
+
const fields = textFields(entity, "", 50);
|
|
261
|
+
entity.properties.forEach((property) => {
|
|
262
|
+
fields.push(...textFields(property, `properties.${property.name}.`));
|
|
263
|
+
property.options?.forEach((option, index) => {
|
|
264
|
+
fields.push(...textFields(option, `properties.${property.name}.options.${index}.`));
|
|
265
|
+
fields.push({
|
|
266
|
+
path: `properties.${property.name}.options.${index}.value`,
|
|
267
|
+
text: option.value,
|
|
268
|
+
weight: 20,
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
for (const relationship of relationships(entity)) {
|
|
273
|
+
const prefix = `relationships.${relationship.name}.`;
|
|
274
|
+
fields.push(...textFields(relationship, prefix));
|
|
275
|
+
relationship.phrase.forEach((text, index) => {
|
|
276
|
+
fields.push({ path: `${prefix}phrase.${index}`, text, weight: 10 });
|
|
277
|
+
});
|
|
278
|
+
const target = visibleEntities.get(relationship.to);
|
|
279
|
+
if (target !== undefined) {
|
|
280
|
+
fields.push({ path: `${prefix}target.label`, text: target.label, weight: 10 });
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
documents.push({
|
|
284
|
+
summary: {
|
|
285
|
+
...summary(`entity:${entity.name}`, entity.name, entity.label, entity.description),
|
|
286
|
+
kind: "entity",
|
|
287
|
+
entity: entity.name,
|
|
288
|
+
},
|
|
289
|
+
fields,
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
for (const [ref, action] of actions) {
|
|
293
|
+
const owner = action.entity.ref.slice("entity:".length);
|
|
294
|
+
const name = `${owner}.${action.name}`;
|
|
295
|
+
documents.push({
|
|
296
|
+
summary: {
|
|
297
|
+
...summary(ref, name, name, action.description),
|
|
298
|
+
kind: "action",
|
|
299
|
+
entity: owner,
|
|
300
|
+
},
|
|
301
|
+
fields: [
|
|
302
|
+
...textFields({ ...action, name }, "", 50),
|
|
303
|
+
...inputFields(action.input_schema),
|
|
304
|
+
],
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
for (const [ref, metric] of metrics) {
|
|
308
|
+
const owner = object(metric.entity)
|
|
309
|
+
? metric.entity.ref.slice("entity:".length)
|
|
310
|
+
: undefined;
|
|
311
|
+
documents.push({
|
|
312
|
+
summary: {
|
|
313
|
+
...summary(ref, metric.name, metric.label, metric.description),
|
|
314
|
+
kind: "metric",
|
|
315
|
+
...(owner === undefined ? {} : { entity: owner }),
|
|
316
|
+
},
|
|
317
|
+
fields: textFields(metric, "", 50),
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
return documents;
|
|
321
|
+
}
|
|
322
|
+
return {
|
|
323
|
+
permissions,
|
|
324
|
+
visibleEntities,
|
|
325
|
+
actions,
|
|
326
|
+
metrics,
|
|
327
|
+
documents,
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
return {
|
|
331
|
+
discover(input, principal, caller = { kind: "unverified" }) {
|
|
332
|
+
checkHash(manifest.hash, input.expected_hash);
|
|
333
|
+
const view = projection(principal, caller);
|
|
334
|
+
const matches = searchDocuments(view.documents(), input);
|
|
335
|
+
const total = matches.length;
|
|
336
|
+
const limit = input.limit ?? 10;
|
|
337
|
+
return page({
|
|
338
|
+
hash: manifest.hash,
|
|
339
|
+
permissions: view.permissions,
|
|
340
|
+
request: {
|
|
341
|
+
kind: "search",
|
|
342
|
+
runtime: caller.kind === "runtime",
|
|
343
|
+
query: normalizeSearch(input.query),
|
|
344
|
+
filter: input.kind,
|
|
345
|
+
entity: input.entity,
|
|
346
|
+
mode: input.mode ?? "auto",
|
|
347
|
+
limit,
|
|
348
|
+
},
|
|
349
|
+
after: input.after,
|
|
350
|
+
limit,
|
|
351
|
+
items: matches,
|
|
352
|
+
result: (matches, next_cursor) => ({
|
|
353
|
+
hash: manifest.hash,
|
|
354
|
+
kind: "search",
|
|
355
|
+
query: input.query,
|
|
356
|
+
total,
|
|
357
|
+
matches,
|
|
358
|
+
next_cursor,
|
|
359
|
+
}),
|
|
360
|
+
});
|
|
361
|
+
},
|
|
362
|
+
/**
|
|
363
|
+
* `discover` ranked by meaning: the ontology's decision model answers, for each entity the
|
|
364
|
+
* caller may see and use, whether the request concerns it. The likely ones come back most
|
|
365
|
+
* likely first, with the caller's tools and metrics for them, on one page. A model failure is
|
|
366
|
+
* thrown for the caller to fall back to `discover`; a stale `expected_hash` is refused as there.
|
|
367
|
+
*/
|
|
368
|
+
async discoverByMeaning(input, principal, caller, ranking) {
|
|
369
|
+
checkHash(manifest.hash, input.expected_hash);
|
|
370
|
+
const view = projection(principal, caller);
|
|
371
|
+
const owned = new Map();
|
|
372
|
+
const withMetrics = new Map();
|
|
373
|
+
for (const tool of visibleTools(tools, principal, caller)) {
|
|
374
|
+
if ("planned" in tool.target) {
|
|
375
|
+
const owner = tool.target.planned.name;
|
|
376
|
+
owned.set(owner, [...(owned.get(owner) ?? []), tool.name]);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
for (const ref of view.metrics.keys()) {
|
|
380
|
+
const name = ref.slice("metric:".length);
|
|
381
|
+
if (name.includes(".")) {
|
|
382
|
+
const owner = name.split(".")[0];
|
|
383
|
+
withMetrics.set(owner, [...(withMetrics.get(owner) ?? []), name]);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
const candidates = [...view.visibleEntities.values()].filter((entity) => (input.entity === undefined || entity.name === input.entity) &&
|
|
387
|
+
(owned.has(entity.name) || withMetrics.has(entity.name)));
|
|
388
|
+
const answers = candidates.length === 0
|
|
389
|
+
? {}
|
|
390
|
+
: await ranking.decide({
|
|
391
|
+
model: ranking.model,
|
|
392
|
+
state: input.query,
|
|
393
|
+
questions: Object.fromEntries(candidates.map((entity, index) => [`entity_${index}`, concerns(entity)])),
|
|
394
|
+
signal: AbortSignal.timeout(DECISION_TIMEOUT_MS),
|
|
395
|
+
});
|
|
396
|
+
const likely = candidates
|
|
397
|
+
.map((entity, index) => ({ entity, relevance: answers[`entity_${index}`] ?? 0 }))
|
|
398
|
+
.filter(({ relevance }) => relevance >= RELEVANT)
|
|
399
|
+
.sort((a, b) => b.relevance - a.relevance || compareRefs(a.entity.name, b.entity.name));
|
|
400
|
+
const ranked = likely.slice(0, input.limit ?? 10).map(({ entity, relevance }) => ({
|
|
401
|
+
...summary(`entity:${entity.name}`, entity.name, entity.label, entity.description),
|
|
402
|
+
kind: "entity",
|
|
403
|
+
entity: entity.name,
|
|
404
|
+
matched_on: [],
|
|
405
|
+
relevance: Math.round(relevance * 100) / 100,
|
|
406
|
+
tools: owned.get(entity.name) ?? [],
|
|
407
|
+
metrics: withMetrics.get(entity.name) ?? [],
|
|
408
|
+
}));
|
|
409
|
+
const result = (matches) => ({
|
|
410
|
+
hash: manifest.hash,
|
|
411
|
+
kind: "search",
|
|
412
|
+
ranking: "meaning",
|
|
413
|
+
query: input.query,
|
|
414
|
+
total: likely.length,
|
|
415
|
+
matches,
|
|
416
|
+
next_cursor: null,
|
|
417
|
+
});
|
|
418
|
+
// The same response budget as a page of word matches: the likeliest that fit.
|
|
419
|
+
let fitted = result([]);
|
|
420
|
+
for (let count = 1; count <= ranked.length; count++) {
|
|
421
|
+
const next = result(ranked.slice(0, count));
|
|
422
|
+
if (discoveryResultBytes(next) > DISCOVERY_RESULT_BYTES) {
|
|
423
|
+
if (count === 1) {
|
|
424
|
+
throw new DiscoveryError({
|
|
425
|
+
error: "discovery_too_large",
|
|
426
|
+
detail: "This discovery entry exceeds the response budget.",
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
break;
|
|
430
|
+
}
|
|
431
|
+
fitted = next;
|
|
432
|
+
}
|
|
433
|
+
return fitted;
|
|
434
|
+
},
|
|
435
|
+
};
|
|
436
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { HttpRouter } from "effect/unstable/http";
|
|
2
|
+
/** The API reference page: `GET /api/ontology/docs`. */
|
|
3
|
+
export declare const DOCS_PATH = "/api/ontology/docs";
|
|
4
|
+
/**
|
|
5
|
+
* The API reference at `/api/ontology/docs`: Scalar over the service's own `openapi.json`. The page
|
|
6
|
+
* is public and holds no part of the ontology: it loads the document as the reader, with the app's
|
|
7
|
+
* session cookie when they are signed in to the app, or with a token they paste.
|
|
8
|
+
*/
|
|
9
|
+
export declare const DocsRoute: import("effect/Layer").Layer<never, never, HttpRouter.HttpRouter>;
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { HttpRouter, HttpServerResponse } from "effect/unstable/http";
|
|
3
|
+
import { BASE_PATH } from "./api.js";
|
|
4
|
+
/** The API reference page: `GET /api/ontology/docs`. */
|
|
5
|
+
export const DOCS_PATH = `${BASE_PATH}/docs`;
|
|
6
|
+
const OPENAPI_PATH = `${BASE_PATH}/openapi.json`;
|
|
7
|
+
/**
|
|
8
|
+
* Scalar's API reference, pinned with its integrity hash: a different file never runs. Bump both
|
|
9
|
+
* together: `curl -sL <url> | openssl dgst -sha384 -binary | openssl base64 -A`.
|
|
10
|
+
*/
|
|
11
|
+
const SCALAR_SCRIPT = {
|
|
12
|
+
src: "https://cdn.jsdelivr.net/npm/@scalar/api-reference@1.73.1/dist/browser/standalone.js",
|
|
13
|
+
integrity: "sha384-kYDGzV91Jnn3TbHINV3nt54riK2uMJDfN5Al8dAkz4FssELTBWbD8rgw32sTKfOi",
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Scalar without its hosted extras: no telemetry, AI agent, MCP button, developer tools or fonts
|
|
17
|
+
* from scalar.com. Requests from the page go to the ontology itself, never through Scalar's proxy.
|
|
18
|
+
*/
|
|
19
|
+
const SCALAR_CONFIGURATION = {
|
|
20
|
+
telemetry: false,
|
|
21
|
+
agent: { disabled: true },
|
|
22
|
+
mcp: { disabled: true },
|
|
23
|
+
showDeveloperTools: "never",
|
|
24
|
+
withDefaultFonts: false,
|
|
25
|
+
hideClientButton: true,
|
|
26
|
+
documentDownloadType: "json",
|
|
27
|
+
};
|
|
28
|
+
/** The key the page keeps a pasted token under, for this tab only. */
|
|
29
|
+
const TOKEN_STORAGE_KEY = "segmentstream-ontology-docs-token";
|
|
30
|
+
/** JSON inside a `<script>`: nothing in it can close the element. */
|
|
31
|
+
function scriptJson(value) {
|
|
32
|
+
return JSON.stringify(value).replace(/</g, "\\u003c");
|
|
33
|
+
}
|
|
34
|
+
function contentSecurityPolicy(nonce) {
|
|
35
|
+
return [
|
|
36
|
+
"default-src 'none'",
|
|
37
|
+
`script-src 'nonce-${nonce}' https://cdn.jsdelivr.net`,
|
|
38
|
+
// Scalar injects its styles at runtime.
|
|
39
|
+
"style-src 'self' 'unsafe-inline'",
|
|
40
|
+
"img-src 'self' data: blob: https:",
|
|
41
|
+
"font-src 'self' data:",
|
|
42
|
+
"connect-src 'self'",
|
|
43
|
+
"worker-src 'self' blob:",
|
|
44
|
+
"base-uri 'none'",
|
|
45
|
+
"form-action 'none'",
|
|
46
|
+
"frame-ancestors 'none'",
|
|
47
|
+
].join("; ");
|
|
48
|
+
}
|
|
49
|
+
function page(nonce) {
|
|
50
|
+
const settings = scriptJson({
|
|
51
|
+
openapi: OPENAPI_PATH,
|
|
52
|
+
storageKey: TOKEN_STORAGE_KEY,
|
|
53
|
+
configuration: SCALAR_CONFIGURATION,
|
|
54
|
+
});
|
|
55
|
+
return `<!doctype html>
|
|
56
|
+
<html lang="en">
|
|
57
|
+
<head>
|
|
58
|
+
<meta charset="utf-8" />
|
|
59
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
60
|
+
<meta name="robots" content="noindex" />
|
|
61
|
+
<title>Ontology API</title>
|
|
62
|
+
<style>
|
|
63
|
+
#sign-in {
|
|
64
|
+
font: 14px/1.5 system-ui, sans-serif;
|
|
65
|
+
max-width: 28rem;
|
|
66
|
+
margin: 15vh auto;
|
|
67
|
+
padding: 0 1.5rem;
|
|
68
|
+
color: #18181b;
|
|
69
|
+
}
|
|
70
|
+
#sign-in h1 { font-size: 1.25rem; margin: 0 0 .5rem; }
|
|
71
|
+
#sign-in p { margin: 0 0 1rem; color: #52525b; }
|
|
72
|
+
#sign-in label { display: block; font-weight: 500; margin-bottom: .25rem; }
|
|
73
|
+
#sign-in input {
|
|
74
|
+
box-sizing: border-box;
|
|
75
|
+
width: 100%;
|
|
76
|
+
padding: .5rem .625rem;
|
|
77
|
+
border: 1px solid #d4d4d8;
|
|
78
|
+
border-radius: .375rem;
|
|
79
|
+
font: inherit;
|
|
80
|
+
}
|
|
81
|
+
#sign-in button {
|
|
82
|
+
margin-top: .75rem;
|
|
83
|
+
padding: .5rem .875rem;
|
|
84
|
+
border: 0;
|
|
85
|
+
border-radius: .375rem;
|
|
86
|
+
background: #18181b;
|
|
87
|
+
color: #fff;
|
|
88
|
+
font: inherit;
|
|
89
|
+
cursor: pointer;
|
|
90
|
+
}
|
|
91
|
+
#sign-in [role="alert"] { margin-top: .75rem; color: #b91c1c; }
|
|
92
|
+
</style>
|
|
93
|
+
</head>
|
|
94
|
+
<body>
|
|
95
|
+
<main id="sign-in" hidden>
|
|
96
|
+
<form>
|
|
97
|
+
<h1>Ontology API</h1>
|
|
98
|
+
<p>Sign in to the app in this browser, or paste a bearer token or an API key (ssk_…).</p>
|
|
99
|
+
<label for="token">Token or API key</label>
|
|
100
|
+
<input id="token" type="password" autocomplete="off" spellcheck="false" required />
|
|
101
|
+
<button type="submit">Open the reference</button>
|
|
102
|
+
<p role="alert"></p>
|
|
103
|
+
</form>
|
|
104
|
+
</main>
|
|
105
|
+
<div id="app"></div>
|
|
106
|
+
<script
|
|
107
|
+
nonce="${nonce}"
|
|
108
|
+
src="${SCALAR_SCRIPT.src}"
|
|
109
|
+
integrity="${SCALAR_SCRIPT.integrity}"
|
|
110
|
+
crossorigin="anonymous"
|
|
111
|
+
></script>
|
|
112
|
+
<script nonce="${nonce}">
|
|
113
|
+
(() => {
|
|
114
|
+
const settings = ${settings};
|
|
115
|
+
const signIn = document.getElementById("sign-in");
|
|
116
|
+
const form = signIn.querySelector("form");
|
|
117
|
+
const input = document.getElementById("token");
|
|
118
|
+
const alert = signIn.querySelector("[role=alert]");
|
|
119
|
+
|
|
120
|
+
async function load(token) {
|
|
121
|
+
const response = await fetch(settings.openapi, {
|
|
122
|
+
credentials: "same-origin",
|
|
123
|
+
headers: token ? { authorization: "Bearer " + token } : {},
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
if (response.ok) {
|
|
127
|
+
return { spec: await response.json() };
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const body = await response.json().catch(() => ({}));
|
|
131
|
+
|
|
132
|
+
return { status: response.status, detail: body.detail };
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function show(spec, token) {
|
|
136
|
+
signIn.hidden = true;
|
|
137
|
+
window.Scalar.createApiReference(document.getElementById("app"), {
|
|
138
|
+
...settings.configuration,
|
|
139
|
+
content: spec,
|
|
140
|
+
authentication: {
|
|
141
|
+
preferredSecurityScheme: "bearer",
|
|
142
|
+
...(token ? { securitySchemes: { bearer: { token } } } : {}),
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
async function open(token) {
|
|
148
|
+
let result;
|
|
149
|
+
|
|
150
|
+
try {
|
|
151
|
+
result = await load(token);
|
|
152
|
+
} catch {
|
|
153
|
+
result = { status: 0 };
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (result.spec !== undefined) {
|
|
157
|
+
if (token) {
|
|
158
|
+
sessionStorage.setItem(settings.storageKey, token);
|
|
159
|
+
}
|
|
160
|
+
show(result.spec, token);
|
|
161
|
+
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
sessionStorage.removeItem(settings.storageKey);
|
|
166
|
+
signIn.hidden = false;
|
|
167
|
+
alert.textContent =
|
|
168
|
+
!token && result.status === 401
|
|
169
|
+
? ""
|
|
170
|
+
: (result.detail ?? "The reference could not be loaded. Try again shortly.");
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
form.addEventListener("submit", (event) => {
|
|
174
|
+
event.preventDefault();
|
|
175
|
+
open(input.value.trim());
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
open(sessionStorage.getItem(settings.storageKey) ?? "");
|
|
179
|
+
})();
|
|
180
|
+
</script>
|
|
181
|
+
</body>
|
|
182
|
+
</html>
|
|
183
|
+
`;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* The API reference at `/api/ontology/docs`: Scalar over the service's own `openapi.json`. The page
|
|
187
|
+
* is public and holds no part of the ontology: it loads the document as the reader, with the app's
|
|
188
|
+
* session cookie when they are signed in to the app, or with a token they paste.
|
|
189
|
+
*/
|
|
190
|
+
export const DocsRoute = HttpRouter.add("GET", DOCS_PATH, Effect.sync(() => {
|
|
191
|
+
const nonce = crypto.randomUUID().replaceAll("-", "");
|
|
192
|
+
return HttpServerResponse.html(page(nonce)).pipe(HttpServerResponse.setHeaders({
|
|
193
|
+
"content-security-policy": contentSecurityPolicy(nonce),
|
|
194
|
+
"referrer-policy": "no-referrer",
|
|
195
|
+
"x-content-type-options": "nosniff",
|
|
196
|
+
}));
|
|
197
|
+
}));
|