@segmentstream/ontology 0.0.0-stage → 0.92.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +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,287 @@
|
|
|
1
|
+
import { effectivePermissions } from "../permissions.js";
|
|
2
|
+
import { HttpServerResponse } from "effect/unstable/http";
|
|
3
|
+
import { Effect, Layer, Schema } from "effect";
|
|
4
|
+
import { HttpApiBuilder, OpenApi } from "effect/unstable/httpapi";
|
|
5
|
+
import { STORAGE_GROUP } from "../storage/api.js";
|
|
6
|
+
import { Conflict } from "../errors.js";
|
|
7
|
+
import { isValueMatched } from "../manifest.js";
|
|
8
|
+
import { EMAIL_PATTERN } from "../property.js";
|
|
9
|
+
import { EARLIER_QUERY_METRICS_ROUTE } from "../legacy.js";
|
|
10
|
+
import { QUERY_METRICS_ENDPOINT, SERVICE_GROUP, hasMetrics, } from "./api.js";
|
|
11
|
+
import { CurrentPrincipal } from "./authentication.js";
|
|
12
|
+
import { currentCaller } from "./caller-context.js";
|
|
13
|
+
import { invokesAgent, runtimeManifest } from "./mcp/runtime-policy.js";
|
|
14
|
+
import { catalogFor, graphOf } from "./catalog.js";
|
|
15
|
+
import { describeCatalog } from "../render.js";
|
|
16
|
+
import { InvalidRequestBody, SignInCheckLimited, schemaIssues } from "./errors.js";
|
|
17
|
+
import { identityToken, makeOperations, toQuery } from "./operations.js";
|
|
18
|
+
import { clientAddress, fixedWindowLimiter, } from "./rate-limit.js";
|
|
19
|
+
import { OntologyBackend } from "./runtime-contract.js";
|
|
20
|
+
import { ActionEnvelope } from "./schemas.js";
|
|
21
|
+
/** Prune excluded invocation routes and the schemas reachable only from those routes. */
|
|
22
|
+
function runtimeOpenApi(document) {
|
|
23
|
+
const paths = Object.fromEntries(Object.entries(document.paths).filter(([path]) => {
|
|
24
|
+
const match = /^\/api\/ontology\/([^/]+)\/actions\/([^/]+)$/.exec(path);
|
|
25
|
+
return match === null || !invokesAgent({ entity: match[1], action: match[2] });
|
|
26
|
+
}));
|
|
27
|
+
const { schemas = {}, ...components } = document.components;
|
|
28
|
+
const retained = new Set();
|
|
29
|
+
const visit = (value) => {
|
|
30
|
+
if (value === null || typeof value !== "object") {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const reference = value.$ref;
|
|
34
|
+
if (typeof reference === "string" && reference.startsWith("#/components/schemas/")) {
|
|
35
|
+
const name = reference.slice("#/components/schemas/".length);
|
|
36
|
+
if (!retained.has(name)) {
|
|
37
|
+
retained.add(name);
|
|
38
|
+
visit(schemas[name]);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
Object.values(value).forEach(visit);
|
|
42
|
+
};
|
|
43
|
+
visit({ ...document, paths, components });
|
|
44
|
+
return {
|
|
45
|
+
...document,
|
|
46
|
+
paths,
|
|
47
|
+
components: {
|
|
48
|
+
...components,
|
|
49
|
+
schemas: Object.fromEntries(Object.entries(schemas).filter(([name]) => retained.has(name))),
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function dynamicGroup(api, identifier, build) {
|
|
54
|
+
const group = HttpApiBuilder.group;
|
|
55
|
+
return group(api, identifier, build);
|
|
56
|
+
}
|
|
57
|
+
function isJsonMediaType(contentType) {
|
|
58
|
+
if (contentType === undefined || contentType.trim() === "") {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
const mediaType = contentType.split(";")[0]?.trim().toLowerCase() ?? "";
|
|
62
|
+
return mediaType === "application/json" || mediaType.endsWith("+json");
|
|
63
|
+
}
|
|
64
|
+
/** Reads a JSON body: `application/json` or a `+json` type, or no content type at all. */
|
|
65
|
+
function readJson(request) {
|
|
66
|
+
return Effect.gen(function* () {
|
|
67
|
+
if (!isJsonMediaType(request.headers["content-type"])) {
|
|
68
|
+
return yield* new InvalidRequestBody({ reason: "unsupported_media_type", issues: [] });
|
|
69
|
+
}
|
|
70
|
+
const text = yield* Effect.orDie(request.text);
|
|
71
|
+
try {
|
|
72
|
+
return JSON.parse(text);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return yield* new InvalidRequestBody({ reason: "invalid_json", issues: [] });
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
/** Reads `{ input, options? }`. The input itself is validated by `runAction`. */
|
|
80
|
+
function readEnvelope(request) {
|
|
81
|
+
return readJson(request).pipe(Effect.flatMap((body) => Schema.decodeUnknownEffect(ActionEnvelope)(body, { errors: "all" }).pipe(Effect.mapError((error) => new InvalidRequestBody({
|
|
82
|
+
reason: "invalid_request",
|
|
83
|
+
issues: schemaIssues(error.issue),
|
|
84
|
+
})))));
|
|
85
|
+
}
|
|
86
|
+
function entityHandlers(built, planned, operationsOf, metricQueries) {
|
|
87
|
+
// Registered beside the record routes; `query_metrics` and its earlier path are static segments,
|
|
88
|
+
// record ids are UUIDs.
|
|
89
|
+
const withMetricQuery = (handlers) => {
|
|
90
|
+
if (!hasMetrics(planned)) {
|
|
91
|
+
return handlers;
|
|
92
|
+
}
|
|
93
|
+
const handler = queryMetricsHandler(metricQueries.entity(planned.name));
|
|
94
|
+
return handlers
|
|
95
|
+
.handleRaw(QUERY_METRICS_ENDPOINT, handler)
|
|
96
|
+
.handleRaw(EARLIER_QUERY_METRICS_ROUTE, handler);
|
|
97
|
+
};
|
|
98
|
+
return dynamicGroup(built.api, planned.name, (handlers) => Effect.gen(function* () {
|
|
99
|
+
const backend = yield* OntologyBackend;
|
|
100
|
+
const operations = operationsOf(backend);
|
|
101
|
+
let registered = withMetricQuery(handlers)
|
|
102
|
+
.handle("find", (request) => operations.find(planned, toQuery(request.query)))
|
|
103
|
+
.handle("query", (request) => operations.find(planned, toQuery(request.payload)))
|
|
104
|
+
.handle("get", (request) => operations.get(planned, request.params.id));
|
|
105
|
+
if (planned.resolved.entity.definition.source === undefined) {
|
|
106
|
+
registered = registered.handle("history", (request) => operations.history(planned, request.params.id, request.query));
|
|
107
|
+
}
|
|
108
|
+
for (const property of planned.resolved.properties.filter((property) => property.definition.type === "blob")) {
|
|
109
|
+
registered = registered.handle(`blobs.${property.name}`, (request) => Effect.gen(function* () {
|
|
110
|
+
const principal = yield* CurrentPrincipal;
|
|
111
|
+
if (!backend.blobs) {
|
|
112
|
+
return yield* new Conflict({
|
|
113
|
+
entity: planned.name,
|
|
114
|
+
message: "File storage is not configured.",
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
return yield* backend.blobs.download(planned.name, request.params.id, property.name, request.payload, principal);
|
|
118
|
+
}));
|
|
119
|
+
}
|
|
120
|
+
for (const traversal of planned.traversals) {
|
|
121
|
+
registered = registered.handle(`related.${traversal.name}`, (request) => operations.traverse(planned, traversal, request.params.id, toQuery(request.query)));
|
|
122
|
+
}
|
|
123
|
+
for (const action of planned.actions) {
|
|
124
|
+
registered = registered.handleRaw(`actions.${action.name}`, ({ request }) => readEnvelope(request).pipe(Effect.flatMap((envelope) => operations.runAction(planned, action, {
|
|
125
|
+
input: envelope.input,
|
|
126
|
+
validateOnly: envelope.options?.validateOnly === true,
|
|
127
|
+
...(envelope.options === undefined ? {} : { options: envelope.options }),
|
|
128
|
+
identityToken: identityToken(request),
|
|
129
|
+
}))));
|
|
130
|
+
}
|
|
131
|
+
return registered;
|
|
132
|
+
}));
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Sign-in checks one client may make per minute. A person checks once per sign-in, a few times at
|
|
136
|
+
* most; the limit slows down anyone testing addresses to learn who the app's members are.
|
|
137
|
+
*/
|
|
138
|
+
export const SIGN_IN_CHECK_LIMIT = { limit: 10, windowMs: 60_000, maxKeys: 10_000 };
|
|
139
|
+
/**
|
|
140
|
+
* `POST /api/ontology/sign-in/check`, before any authentication: rate limited per client address,
|
|
141
|
+
* then answered by the backend. A malformed address is a 400, so the app can ask for a valid one
|
|
142
|
+
* instead of reporting that nobody invited it.
|
|
143
|
+
*/
|
|
144
|
+
function checkSignIn(backend, limiter) {
|
|
145
|
+
return (request) => Effect.gen(function* () {
|
|
146
|
+
const retryAfterSeconds = limiter.take(clientAddress(request.request));
|
|
147
|
+
if (retryAfterSeconds !== undefined) {
|
|
148
|
+
return yield* new SignInCheckLimited({ retryAfterSeconds });
|
|
149
|
+
}
|
|
150
|
+
const email = request.payload.email.trim();
|
|
151
|
+
if (!EMAIL_PATTERN.test(email.toLowerCase())) {
|
|
152
|
+
return yield* new InvalidRequestBody({
|
|
153
|
+
reason: "invalid_request",
|
|
154
|
+
issues: [{ path: ["email"], message: "Expected an email address." }],
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
return yield* backend.checkSignIn(email);
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* `POST /api/ontology/query_metrics` and `POST /api/ontology/<entity>/query_metrics`, and their
|
|
162
|
+
* earlier paths: the facade's answer is SegmentStream's, so its status and JSON body pass through as
|
|
163
|
+
* they came, with its `Retry-After` on a 429 or a 503.
|
|
164
|
+
*/
|
|
165
|
+
function queryMetricsHandler(queryMetrics) {
|
|
166
|
+
return ({ request }) => readJson(request).pipe(Effect.flatMap(queryMetrics), Effect.map((answer) => HttpServerResponse.text(answer.text, {
|
|
167
|
+
status: answer.status,
|
|
168
|
+
contentType: "application/json",
|
|
169
|
+
...(answer.retryAfter === undefined
|
|
170
|
+
? {}
|
|
171
|
+
: { headers: { "retry-after": answer.retryAfter } }),
|
|
172
|
+
})));
|
|
173
|
+
}
|
|
174
|
+
function serviceHandlers(built, operationsOf, queryMetrics, deployment) {
|
|
175
|
+
const { manifest } = built.plan.ontology;
|
|
176
|
+
const graph = graphOf(manifest);
|
|
177
|
+
const signInLimiter = fixedWindowLimiter(SIGN_IN_CHECK_LIMIT);
|
|
178
|
+
let openApi;
|
|
179
|
+
return dynamicGroup(built.api, SERVICE_GROUP, (handlers) => Effect.gen(function* () {
|
|
180
|
+
const backend = yield* OntologyBackend;
|
|
181
|
+
// `as=me` reads the catalog with the caller's permissions; otherwise it is the whole catalog.
|
|
182
|
+
const permissionsFor = (as) => Effect.gen(function* () {
|
|
183
|
+
if (as !== "me") {
|
|
184
|
+
return undefined;
|
|
185
|
+
}
|
|
186
|
+
const principal = yield* CurrentPrincipal;
|
|
187
|
+
return effectivePermissions(principal);
|
|
188
|
+
});
|
|
189
|
+
return handlers
|
|
190
|
+
.handle("catalog", (request) => Effect.gen(function* () {
|
|
191
|
+
return catalogFor(runtimeManifest(manifest, yield* currentCaller), yield* permissionsFor(request.query.as));
|
|
192
|
+
}))
|
|
193
|
+
.handle("graph", () => Effect.succeed(graph))
|
|
194
|
+
.handle("me", () => operationsOf(backend).caller)
|
|
195
|
+
.handle("openapi", () => Effect.gen(function* () {
|
|
196
|
+
const caller = yield* currentCaller;
|
|
197
|
+
if (openApi === undefined) {
|
|
198
|
+
openApi = OpenApi.fromApi(built.api);
|
|
199
|
+
openApi.components.schemas ??= {};
|
|
200
|
+
for (const entity of manifest.entities) {
|
|
201
|
+
const recordName = `${entity.name
|
|
202
|
+
.split("_")
|
|
203
|
+
.map((part) => part[0].toUpperCase() + part.slice(1))
|
|
204
|
+
.join("")}Record`;
|
|
205
|
+
if (entity.source !== undefined) {
|
|
206
|
+
const document = Schema.toJsonSchemaDocument(built.schemas.get(entity.name).record);
|
|
207
|
+
openApi.components.schemas[entity.name] = {
|
|
208
|
+
...(document.definitions[recordName] ?? document.schema),
|
|
209
|
+
"x-ontology-source": entity.source,
|
|
210
|
+
"x-ontology-metrics": entity.metrics,
|
|
211
|
+
"x-ontology-relationships": entity.relationships,
|
|
212
|
+
};
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
// A value-matched relationship has no key field or route; only this names it.
|
|
216
|
+
const matched = entity.relationships.filter(isValueMatched);
|
|
217
|
+
const record = openApi.components.schemas[recordName];
|
|
218
|
+
if (matched.length > 0 && record !== undefined) {
|
|
219
|
+
openApi.components.schemas[recordName] = {
|
|
220
|
+
...record,
|
|
221
|
+
"x-ontology-relationships": matched,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
if (caller.kind !== "runtime") {
|
|
227
|
+
return openApi;
|
|
228
|
+
}
|
|
229
|
+
return runtimeOpenApi(openApi);
|
|
230
|
+
}))
|
|
231
|
+
.handle("describe", (request) => Effect.gen(function* () {
|
|
232
|
+
return describeCatalog(runtimeManifest(manifest, yield* currentCaller), yield* permissionsFor(request.query.as));
|
|
233
|
+
}))
|
|
234
|
+
.handle("status", () => Effect.map(backend.appliedHash, (appliedHash) => ({
|
|
235
|
+
hash: manifest.hash,
|
|
236
|
+
appliedHash: appliedHash ?? null,
|
|
237
|
+
upToDate: appliedHash === manifest.hash,
|
|
238
|
+
...(deployment ? { deployment } : {}),
|
|
239
|
+
})))
|
|
240
|
+
.handle("signInCheck", checkSignIn(backend, signInLimiter))
|
|
241
|
+
.handleRaw(QUERY_METRICS_ENDPOINT, queryMetricsHandler(queryMetrics))
|
|
242
|
+
.handleRaw(EARLIER_QUERY_METRICS_ROUTE, queryMetricsHandler(queryMetrics));
|
|
243
|
+
}));
|
|
244
|
+
}
|
|
245
|
+
function storageHandlers(built) {
|
|
246
|
+
return dynamicGroup(built.api, STORAGE_GROUP, (handlers) => Effect.gen(function* () {
|
|
247
|
+
const backend = yield* OntologyBackend;
|
|
248
|
+
const configured = () => backend.blobs
|
|
249
|
+
? Effect.succeed(backend.blobs)
|
|
250
|
+
: Effect.fail(new Conflict({ entity: "upload", message: "File storage is not configured." }));
|
|
251
|
+
let registered = handlers.handle("begin", (request) => Effect.gen(function* () {
|
|
252
|
+
const principal = yield* CurrentPrincipal;
|
|
253
|
+
const blobs = yield* configured();
|
|
254
|
+
return yield* blobs.begin(request.payload, principal);
|
|
255
|
+
}));
|
|
256
|
+
registered = registered.handle("list", () => Effect.gen(function* () {
|
|
257
|
+
const principal = yield* CurrentPrincipal;
|
|
258
|
+
const blobs = yield* configured();
|
|
259
|
+
if (!blobs.list) {
|
|
260
|
+
return yield* new Conflict({ entity: "upload", message: "file_listing_unavailable" });
|
|
261
|
+
}
|
|
262
|
+
return yield* blobs.list(principal);
|
|
263
|
+
}));
|
|
264
|
+
for (const method of ["status", "part", "complete", "cancel"]) {
|
|
265
|
+
registered = registered.handle(method, (request) => Effect.gen(function* () {
|
|
266
|
+
const principal = yield* CurrentPrincipal;
|
|
267
|
+
const blobs = yield* configured();
|
|
268
|
+
return yield* blobs[method](request.params.id, principal);
|
|
269
|
+
}));
|
|
270
|
+
}
|
|
271
|
+
return registered.handle("maintain", () => backend.maintainBlobs ??
|
|
272
|
+
Effect.fail(new Conflict({ entity: "upload", message: "File storage is not configured." })));
|
|
273
|
+
}));
|
|
274
|
+
}
|
|
275
|
+
/** The handlers of every group of the API; they require {@link OntologyBackend}. */
|
|
276
|
+
export function handlersLayer(built, hooks, connections, replicate, metricQueries, chatDelivery, deployment) {
|
|
277
|
+
const operationsOf = (backend) => makeOperations(backend, built.plan, hooks, connections, replicate, chatDelivery);
|
|
278
|
+
const layers = [
|
|
279
|
+
serviceHandlers(built, operationsOf, metricQueries.model, deployment),
|
|
280
|
+
...(built.plan.ontology.manifest.entities.some((entity) => entity.properties.some((property) => property.type === "blob"))
|
|
281
|
+
? [storageHandlers(built)]
|
|
282
|
+
: []),
|
|
283
|
+
...built.plan.entities.map((planned) => entityHandlers(built, planned, operationsOf, metricQueries)),
|
|
284
|
+
];
|
|
285
|
+
const [first, ...rest] = layers;
|
|
286
|
+
return Layer.mergeAll(first, ...rest);
|
|
287
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { JsonSchemaObject } from "../../analyze.js";
|
|
2
|
+
import type { OntologyManifest } from "../../manifest.js";
|
|
3
|
+
import type { McpToolAnnotations } from "./tools.js";
|
|
4
|
+
/** Presentation travels with the call, but is never business input or an idempotency key. */
|
|
5
|
+
export declare const CONFIRMATION_ARGUMENT = "_confirmation";
|
|
6
|
+
export declare function needsConfirmation(hints: McpToolAnnotations): boolean;
|
|
7
|
+
export declare function withConfirmation(schema: JsonSchemaObject, hints: McpToolAnnotations): JsonSchemaObject;
|
|
8
|
+
export declare function withoutConfirmation(input: Readonly<Record<string, unknown>>): Record<string, unknown>;
|
|
9
|
+
/**
|
|
10
|
+
* The annotation of a confirmable action's listed tool that carries its {@link ConfirmationFacts}.
|
|
11
|
+
* Eve's approval policy receives a tool's annotations from the listing Eve already holds, but not
|
|
12
|
+
* its input schema: these facts let the agent present the card without reading the ontology's
|
|
13
|
+
* metadata again.
|
|
14
|
+
*/
|
|
15
|
+
export declare const CONFIRMATION_FACTS = "segmentstream/confirmation";
|
|
16
|
+
/**
|
|
17
|
+
* The JSON-RPC method that asks a confirmable action what its person confirms, instead of running
|
|
18
|
+
* it: `{ name, arguments, locale }`, `locale` being the chat's language. It answers as `tools/call`
|
|
19
|
+
* does, with `{ confirmation }` as the action's `confirm` describes it, or fails as the action would
|
|
20
|
+
* refuse the input. Only a tool whose {@link ConfirmationFacts} carry `preview` accepts it; any
|
|
21
|
+
* other tool, and a service without the method, answers with a JSON-RPC error and runs nothing.
|
|
22
|
+
*/
|
|
23
|
+
export declare const CONFIRMATION_PREVIEW_METHOD = "segmentstream/confirmation/preview";
|
|
24
|
+
/** A preview request's chat language, as a lower-case BCP 47 tag; English when it is not one. */
|
|
25
|
+
export declare function previewLocale(locale: unknown): string;
|
|
26
|
+
/** One input field as a confirmation card shows it. */
|
|
27
|
+
export interface ConfirmationField {
|
|
28
|
+
readonly label: string;
|
|
29
|
+
/** The value is a list. */
|
|
30
|
+
readonly list?: true;
|
|
31
|
+
/** The value is the id of a record: the card shows the record's `title` property instead. */
|
|
32
|
+
readonly ref?: {
|
|
33
|
+
readonly entity: string;
|
|
34
|
+
readonly title?: string;
|
|
35
|
+
};
|
|
36
|
+
/** The value is one of these: the card shows its label, and no value without one. */
|
|
37
|
+
readonly options?: Readonly<Record<string, string>>;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The facts of a confirmation card, in the ontology's own labels. Fields that are not listed, such
|
|
41
|
+
* as files, structured values and ids that name no record, are not shown.
|
|
42
|
+
*/
|
|
43
|
+
export interface ConfirmationFacts {
|
|
44
|
+
readonly action: string;
|
|
45
|
+
readonly entity?: string;
|
|
46
|
+
readonly description?: string;
|
|
47
|
+
readonly fields: Readonly<Record<string, ConfirmationField>>;
|
|
48
|
+
/**
|
|
49
|
+
* The action describes its own confirmation: {@link CONFIRMATION_PREVIEW_METHOD} answers what to
|
|
50
|
+
* show, or why the action would refuse.
|
|
51
|
+
*/
|
|
52
|
+
readonly preview?: true;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The card facts of a confirmable action's tool, from its input schema and the ontology's labels:
|
|
56
|
+
* every top-level field except its options, files, structured values and ids that name no record.
|
|
57
|
+
*/
|
|
58
|
+
export declare function confirmationFacts(input: {
|
|
59
|
+
readonly title: string;
|
|
60
|
+
readonly description: string;
|
|
61
|
+
readonly inputSchema: JsonSchemaObject;
|
|
62
|
+
readonly manifest: OntologyManifest;
|
|
63
|
+
readonly entity: string;
|
|
64
|
+
/** Arguments the runtime handles itself, never shown as facts. */
|
|
65
|
+
readonly omit: ReadonlyArray<string>;
|
|
66
|
+
/** The action has `confirm`. */
|
|
67
|
+
readonly preview?: boolean;
|
|
68
|
+
}): ConfirmationFacts;
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { nameToWire } from "../../authoring-names.js";
|
|
2
|
+
import { BLOB_UPLOAD_ANNOTATION } from "../../blob.js";
|
|
3
|
+
import { humanize } from "../../names.js";
|
|
4
|
+
import { REFERENCE_ANNOTATION } from "../../property.js";
|
|
5
|
+
/** Presentation travels with the call, but is never business input or an idempotency key. */
|
|
6
|
+
export const CONFIRMATION_ARGUMENT = "_confirmation";
|
|
7
|
+
export function needsConfirmation(hints) {
|
|
8
|
+
return (hints.readOnlyHint !== true &&
|
|
9
|
+
(hints.destructiveHint === true ||
|
|
10
|
+
hints.irreversibleHint === true ||
|
|
11
|
+
hints.openWorldHint === true ||
|
|
12
|
+
(hints.destructiveHint === undefined && hints.irreversibleHint === undefined)));
|
|
13
|
+
}
|
|
14
|
+
export function withConfirmation(schema, hints) {
|
|
15
|
+
if (!needsConfirmation(hints)) {
|
|
16
|
+
return schema;
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
...schema,
|
|
20
|
+
properties: {
|
|
21
|
+
...schema.properties,
|
|
22
|
+
[CONFIRMATION_ARGUMENT]: {
|
|
23
|
+
description: "Confirmation presentation in the chat's language. Plain single-line text only; " +
|
|
24
|
+
"no IDs, tool names, snake_case, URLs, credentials or markup. The question describes " +
|
|
25
|
+
"this action and its key parameters. The runtime adds trusted facts and fixed markers.",
|
|
26
|
+
// Eve validates the wire schema before execution. Presentation mistakes must reach
|
|
27
|
+
// the SDK's validator so they use the neutral fallback rather than block the action.
|
|
28
|
+
anyOf: [
|
|
29
|
+
{
|
|
30
|
+
type: "object",
|
|
31
|
+
properties: Object.fromEntries([
|
|
32
|
+
"question",
|
|
33
|
+
"confirm",
|
|
34
|
+
"cancel",
|
|
35
|
+
"done",
|
|
36
|
+
"cancelled",
|
|
37
|
+
"failed",
|
|
38
|
+
"expired",
|
|
39
|
+
"interrupted",
|
|
40
|
+
"edit",
|
|
41
|
+
].map((key) => [
|
|
42
|
+
key,
|
|
43
|
+
{ type: "string", minLength: 1, maxLength: key === "question" ? 300 : 24 },
|
|
44
|
+
])),
|
|
45
|
+
required: ["question", "confirm", "cancel", "done", "cancelled", "failed"],
|
|
46
|
+
additionalProperties: false,
|
|
47
|
+
},
|
|
48
|
+
{},
|
|
49
|
+
],
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export function withoutConfirmation(input) {
|
|
55
|
+
return Object.fromEntries(Object.entries(input).filter(([key]) => key !== CONFIRMATION_ARGUMENT));
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The annotation of a confirmable action's listed tool that carries its {@link ConfirmationFacts}.
|
|
59
|
+
* Eve's approval policy receives a tool's annotations from the listing Eve already holds, but not
|
|
60
|
+
* its input schema: these facts let the agent present the card without reading the ontology's
|
|
61
|
+
* metadata again.
|
|
62
|
+
*/
|
|
63
|
+
export const CONFIRMATION_FACTS = "segmentstream/confirmation";
|
|
64
|
+
/**
|
|
65
|
+
* The JSON-RPC method that asks a confirmable action what its person confirms, instead of running
|
|
66
|
+
* it: `{ name, arguments, locale }`, `locale` being the chat's language. It answers as `tools/call`
|
|
67
|
+
* does, with `{ confirmation }` as the action's `confirm` describes it, or fails as the action would
|
|
68
|
+
* refuse the input. Only a tool whose {@link ConfirmationFacts} carry `preview` accepts it; any
|
|
69
|
+
* other tool, and a service without the method, answers with a JSON-RPC error and runs nothing.
|
|
70
|
+
*/
|
|
71
|
+
export const CONFIRMATION_PREVIEW_METHOD = "segmentstream/confirmation/preview";
|
|
72
|
+
/** A preview request's chat language, as a lower-case BCP 47 tag; English when it is not one. */
|
|
73
|
+
export function previewLocale(locale) {
|
|
74
|
+
return typeof locale === "string" && /^[a-z]{2,3}(?:-[a-z0-9]{1,8}){0,3}$/i.test(locale)
|
|
75
|
+
? locale.toLowerCase()
|
|
76
|
+
: "en";
|
|
77
|
+
}
|
|
78
|
+
function record(value) {
|
|
79
|
+
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
80
|
+
? value
|
|
81
|
+
: {};
|
|
82
|
+
}
|
|
83
|
+
function text(value) {
|
|
84
|
+
return typeof value === "string" && value.trim() !== "" ? value : undefined;
|
|
85
|
+
}
|
|
86
|
+
function resolve(value, root, depth = 0) {
|
|
87
|
+
const schema = record(value);
|
|
88
|
+
if (depth > 12) {
|
|
89
|
+
return { schema: {}, choices: [] };
|
|
90
|
+
}
|
|
91
|
+
const reference = typeof schema.$ref === "string" && schema.$ref.startsWith("#/")
|
|
92
|
+
? resolve(schema.$ref
|
|
93
|
+
.slice(2)
|
|
94
|
+
.split("/")
|
|
95
|
+
.reduce((at, key) => record(at)[key.replace(/~1/g, "/").replace(/~0/g, "~")], root), root, depth + 1)
|
|
96
|
+
: undefined;
|
|
97
|
+
const branches = [schema.allOf, schema.anyOf, schema.oneOf]
|
|
98
|
+
.flatMap((items) => (Array.isArray(items) ? items : []))
|
|
99
|
+
.filter((item) => record(item).type !== "null")
|
|
100
|
+
.map((item) => resolve(item, root, depth + 1));
|
|
101
|
+
const values = Array.isArray(schema.enum)
|
|
102
|
+
? schema.enum.filter((item) => typeof item === "string")
|
|
103
|
+
: [];
|
|
104
|
+
// A schema that allows exactly one value is an option, and its title is that option's label.
|
|
105
|
+
const option = typeof schema.const === "string" || values.length === 1;
|
|
106
|
+
const own = typeof schema.const === "string"
|
|
107
|
+
? [{ value: schema.const, title: text(schema.title) }]
|
|
108
|
+
: values.map((item) => ({ value: item, ...(option ? { title: text(schema.title) } : {}) }));
|
|
109
|
+
return {
|
|
110
|
+
schema: Object.assign({}, reference?.schema, ...branches.map(({ schema }) => schema), schema),
|
|
111
|
+
choices: [...(reference?.choices ?? []), ...branches.flatMap(({ choices }) => choices), ...own],
|
|
112
|
+
title: (option ? undefined : text(schema.title)) ??
|
|
113
|
+
reference?.title ??
|
|
114
|
+
(branches.length === 1 ? branches[0].title : undefined),
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* The card facts of a confirmable action's tool, from its input schema and the ontology's labels:
|
|
119
|
+
* every top-level field except its options, files, structured values and ids that name no record.
|
|
120
|
+
*/
|
|
121
|
+
export function confirmationFacts(input) {
|
|
122
|
+
const root = input.inputSchema;
|
|
123
|
+
const owner = input.manifest.entities.find((entity) => entity.name === input.entity);
|
|
124
|
+
const fields = {};
|
|
125
|
+
for (const [name, declared] of Object.entries(record(root.properties))) {
|
|
126
|
+
if (name === CONFIRMATION_ARGUMENT || input.omit.includes(name)) {
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
const field = resolve(declared, root);
|
|
130
|
+
const list = field.schema.type === "array";
|
|
131
|
+
const item = list ? resolve(field.schema.items, root) : field;
|
|
132
|
+
const target = item.schema[REFERENCE_ANNOTATION];
|
|
133
|
+
if (field.schema.writeOnly === true ||
|
|
134
|
+
item.schema.writeOnly === true ||
|
|
135
|
+
item.schema.format === "password" ||
|
|
136
|
+
item.schema.type === "object" ||
|
|
137
|
+
item.schema[BLOB_UPLOAD_ANNOTATION] !== undefined ||
|
|
138
|
+
(typeof target !== "string" && item.schema.format === "uuid")) {
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
const property = owner?.properties.find((candidate) => candidate.name === name);
|
|
142
|
+
const referenced = typeof target === "string"
|
|
143
|
+
? input.manifest.entities.find((entity) => entity.name === target || nameToWire(entity.name) === target)
|
|
144
|
+
: undefined;
|
|
145
|
+
const labels = new Map([
|
|
146
|
+
...(property?.options ?? []).map(({ value, label }) => [value, label]),
|
|
147
|
+
...item.choices.flatMap(({ value, title }) => title === undefined ? [] : [[value, title]]),
|
|
148
|
+
]);
|
|
149
|
+
fields[name] = {
|
|
150
|
+
label: field.title ?? (list ? item.title : undefined) ?? property?.label ?? humanize(name),
|
|
151
|
+
...(list ? { list: true } : {}),
|
|
152
|
+
...(typeof target === "string"
|
|
153
|
+
? {
|
|
154
|
+
ref: {
|
|
155
|
+
entity: target,
|
|
156
|
+
...(referenced === undefined ? {} : { title: referenced.title }),
|
|
157
|
+
},
|
|
158
|
+
}
|
|
159
|
+
: {}),
|
|
160
|
+
...(item.choices.length === 0 && property?.options === undefined
|
|
161
|
+
? {}
|
|
162
|
+
: {
|
|
163
|
+
options: Object.fromEntries([...new Set([...item.choices.map(({ value }) => value), ...labels.keys()])].flatMap((value) => {
|
|
164
|
+
const label = labels.get(value);
|
|
165
|
+
return label === undefined ? [] : [[value, label]];
|
|
166
|
+
})),
|
|
167
|
+
}),
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
const description = text(input.description.split("\n\n")[0]);
|
|
171
|
+
return {
|
|
172
|
+
action: input.title,
|
|
173
|
+
...(owner === undefined ? {} : { entity: owner.label }),
|
|
174
|
+
...(description === undefined ? {} : { description }),
|
|
175
|
+
fields,
|
|
176
|
+
...(input.preview === true ? { preview: true } : {}),
|
|
177
|
+
};
|
|
178
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { JsonSchemaObject } from "../../analyze.js";
|
|
2
|
+
import type { OntologyManifest } from "../../manifest.js";
|
|
3
|
+
/** The query language of `<entity>_find`, in the tool's description, which clients show whole. */
|
|
4
|
+
export declare const FIND_CONDITIONS: string;
|
|
5
|
+
/**
|
|
6
|
+
* The input an MCP client sees for `<entity>_find`. It is the same query as `POST
|
|
7
|
+
* /<entity>/query`, published compactly: each field names its type once, a relationship names
|
|
8
|
+
* its target's fields instead of repeating their filters, and paging, sorting and includes come
|
|
9
|
+
* before the conditions. The server still decodes every call with the closed query schema, so an
|
|
10
|
+
* unknown field or operator is refused with its reason.
|
|
11
|
+
*/
|
|
12
|
+
export declare function findToolInput(manifest: OntologyManifest, entityName: string): JsonSchemaObject;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { findEntityManifest, queryFields, queryJsonSchema, queryLinks, } from "../../query.js";
|
|
2
|
+
/** The JSON types of a bare value of the field, as `eq` takes it. */
|
|
3
|
+
function bareType(field) {
|
|
4
|
+
switch (field.storage) {
|
|
5
|
+
case "integer":
|
|
6
|
+
return "integer";
|
|
7
|
+
case "number":
|
|
8
|
+
return "number";
|
|
9
|
+
case "boolean":
|
|
10
|
+
return "boolean";
|
|
11
|
+
case "json":
|
|
12
|
+
return "unknown";
|
|
13
|
+
default:
|
|
14
|
+
return "string";
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/** What a field's operators and values are, in a few words. */
|
|
18
|
+
function fieldNote(field) {
|
|
19
|
+
if (field.storage === "list") {
|
|
20
|
+
return "A list: has takes a value, has_any a list of values.";
|
|
21
|
+
}
|
|
22
|
+
if (field.storage === "date") {
|
|
23
|
+
return "YYYY-MM-DD.";
|
|
24
|
+
}
|
|
25
|
+
if (field.storage === "timestamp") {
|
|
26
|
+
return "ISO 8601 with a time zone.";
|
|
27
|
+
}
|
|
28
|
+
if (field.storage === "json") {
|
|
29
|
+
return "JSON; eq compares values.";
|
|
30
|
+
}
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* One field's condition: a bare value, null, or an object of operators. The operators are named
|
|
35
|
+
* once, in the `where` description, instead of being spelled out for every field.
|
|
36
|
+
*/
|
|
37
|
+
function fieldCondition(field) {
|
|
38
|
+
const note = fieldNote(field);
|
|
39
|
+
const bare = field.options !== undefined
|
|
40
|
+
? { enum: [...field.options] }
|
|
41
|
+
: bareType(field) === "unknown"
|
|
42
|
+
? {}
|
|
43
|
+
: { type: bareType(field) };
|
|
44
|
+
return {
|
|
45
|
+
anyOf: [bare, { type: "null" }, { type: "object" }],
|
|
46
|
+
...(note === undefined ? {} : { description: note }),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/** The query language of `<entity>_find`, in the tool's description, which clients show whole. */
|
|
50
|
+
export const FIND_CONDITIONS = "where: a field takes a bare value (eq), null (is_null: true) or an object of operators: eq, " +
|
|
51
|
+
"ne, in and is_null; text fields also contains and starts_with, which ignore case; numbers, " +
|
|
52
|
+
"dates and timestamps also gt, gte, lt, lte and between [from, to], which includes both ends. " +
|
|
53
|
+
"ne also matches empty values. Dates are YYYY-MM-DD. A relationship takes conditions on its " +
|
|
54
|
+
"target's fields, one level deep; a to-many one wraps them in some, none or every. and and or " +
|
|
55
|
+
"take lists of conditions; not takes one. Unknown fields and operators are refused.";
|
|
56
|
+
// Clients that shorten schema descriptions keep this first sentence.
|
|
57
|
+
const WHERE_DESCRIPTION = "Operators: eq, ne, in, is_null; text contains, starts_with; ordered gt, gte, lt, lte, " +
|
|
58
|
+
"between. All conditions must hold; the tool description has the rules.";
|
|
59
|
+
/** A target's fields for a relationship's hint: its title and properties first, then its id. */
|
|
60
|
+
function targetFields(manifest, name) {
|
|
61
|
+
const target = findEntityManifest(manifest, name);
|
|
62
|
+
if (target === undefined) {
|
|
63
|
+
return [];
|
|
64
|
+
}
|
|
65
|
+
const system = new Set(["id", "created_at", "updated_at", "created_by", "updated_by"]);
|
|
66
|
+
const fields = queryFields(target)
|
|
67
|
+
.map((field) => field.name)
|
|
68
|
+
.filter((field) => !system.has(field));
|
|
69
|
+
const title = typeof target.title === "string" ? target.title : undefined;
|
|
70
|
+
return [
|
|
71
|
+
...(title !== undefined && fields.includes(title) ? [title] : []),
|
|
72
|
+
...fields.filter((field) => field !== title),
|
|
73
|
+
"id",
|
|
74
|
+
];
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The input an MCP client sees for `<entity>_find`. It is the same query as `POST
|
|
78
|
+
* /<entity>/query`, published compactly: each field names its type once, a relationship names
|
|
79
|
+
* its target's fields instead of repeating their filters, and paging, sorting and includes come
|
|
80
|
+
* before the conditions. The server still decodes every call with the closed query schema, so an
|
|
81
|
+
* unknown field or operator is refused with its reason.
|
|
82
|
+
*/
|
|
83
|
+
export function findToolInput(manifest, entityName) {
|
|
84
|
+
const precise = queryJsonSchema(manifest, entityName, true);
|
|
85
|
+
const properties = precise.properties;
|
|
86
|
+
const entity = findEntityManifest(manifest, entityName);
|
|
87
|
+
const conditions = {};
|
|
88
|
+
for (const field of queryFields(entity)) {
|
|
89
|
+
conditions[field.name] = fieldCondition(field);
|
|
90
|
+
}
|
|
91
|
+
for (const link of queryLinks(manifest, entityName, true)) {
|
|
92
|
+
conditions[link.name] = {
|
|
93
|
+
type: "object",
|
|
94
|
+
description: `${link.cardinality === "many" ? "some, none or every: " : ""}${link.target} ` +
|
|
95
|
+
`fields ${targetFields(manifest, link.target).join(", ")}.`,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
conditions.and = { type: "array", items: { type: "object" } };
|
|
99
|
+
conditions.or = { type: "array", items: { type: "object" } };
|
|
100
|
+
conditions.not = { type: "object" };
|
|
101
|
+
const ordered = {};
|
|
102
|
+
for (const key of ["limit", "after", "include", "order_by", "select"]) {
|
|
103
|
+
if (properties[key] !== undefined) {
|
|
104
|
+
ordered[key] = properties[key];
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
ordered.where = {
|
|
108
|
+
type: "object",
|
|
109
|
+
description: WHERE_DESCRIPTION,
|
|
110
|
+
properties: conditions,
|
|
111
|
+
additionalProperties: false,
|
|
112
|
+
};
|
|
113
|
+
if (JSON.stringify(ordered).includes('"$ref"')) {
|
|
114
|
+
throw new Error(`The compact find input of ${entityName} still refers to definitions.`);
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
type: "object",
|
|
118
|
+
...(typeof precise.description === "string" ? { description: precise.description } : {}),
|
|
119
|
+
properties: ordered,
|
|
120
|
+
additionalProperties: false,
|
|
121
|
+
};
|
|
122
|
+
}
|