@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,228 @@
|
|
|
1
|
+
import { PermissionDenied } from "../../errors.js";
|
|
2
|
+
import { consumeChatEnvelope } from "../chat/envelope.js";
|
|
3
|
+
import { Cause, Effect, Layer, Result, Schema } from "effect";
|
|
4
|
+
import { HttpRouter, HttpServerResponse } from "effect/unstable/http";
|
|
5
|
+
import { ATTACHMENT_SOURCES, } from "../../storage/attachments.js";
|
|
6
|
+
import { schemaIssues } from "../../runtime/validation.js";
|
|
7
|
+
import { CurrentPrincipal } from "../authentication.js";
|
|
8
|
+
import { RequestId, errorBodyForWire, failureResponse } from "../errors.js";
|
|
9
|
+
import { identityToken, makeOperations } from "../operations.js";
|
|
10
|
+
import { OntologyBackend } from "../runtime-contract.js";
|
|
11
|
+
import { authenticateAgentCaller } from "./authentication.js";
|
|
12
|
+
import { checkRuntimeOperation } from "../mcp/runtime-policy.js";
|
|
13
|
+
import { AGENT_PATH } from "./server.js";
|
|
14
|
+
export { CONVERSATION_HEADER, SESSION_HEADER } from "./authentication.js";
|
|
15
|
+
/**
|
|
16
|
+
* The agent's temporary attachments over HTTP (`docs/agent.md`, "Attachments"). Only the
|
|
17
|
+
* deployment's runtime token reaches these routes, acting as the member in `X-SegmentStream-Act-As`
|
|
18
|
+
* while they are active. The chat and the agent session come from the agent's runtime in
|
|
19
|
+
* `X-SegmentStream-Agent-Conversation` and `X-SegmentStream-Agent-Session`, never from the model's
|
|
20
|
+
* tool arguments. Storage checks current group participation or chat administration; private files
|
|
21
|
+
* remain confined to their sender and session.
|
|
22
|
+
*/
|
|
23
|
+
export const ATTACHMENTS_PATH = `${AGENT_PATH}/attachments`;
|
|
24
|
+
const NO_STORE = { "cache-control": "no-store" };
|
|
25
|
+
const Received = Schema.Struct({
|
|
26
|
+
source: Schema.Literals(ATTACHMENT_SOURCES),
|
|
27
|
+
source_ref: Schema.String,
|
|
28
|
+
filename: Schema.String,
|
|
29
|
+
content_type: Schema.String,
|
|
30
|
+
size: Schema.Int,
|
|
31
|
+
sha256: Schema.String,
|
|
32
|
+
});
|
|
33
|
+
const Promotion = Schema.Struct({
|
|
34
|
+
_meta: Schema.optionalKey(Schema.Struct({ _segmentstream: Schema.optionalKey(Schema.Unknown) })),
|
|
35
|
+
entity: Schema.String,
|
|
36
|
+
action: Schema.String,
|
|
37
|
+
input: Schema.optionalKey(Schema.Record(Schema.String, Schema.Unknown)),
|
|
38
|
+
field: Schema.optionalKey(Schema.String),
|
|
39
|
+
record_id: Schema.optionalKey(Schema.String),
|
|
40
|
+
});
|
|
41
|
+
function json(body, status = 200) {
|
|
42
|
+
return HttpServerResponse.jsonUnsafe(body, { status, headers: NO_STORE });
|
|
43
|
+
}
|
|
44
|
+
function attachmentForWire(attachment) {
|
|
45
|
+
return {
|
|
46
|
+
id: attachment.id,
|
|
47
|
+
filename: attachment.filename,
|
|
48
|
+
content_type: attachment.contentType,
|
|
49
|
+
size: attachment.size,
|
|
50
|
+
sha256: attachment.sha256,
|
|
51
|
+
state: attachment.state,
|
|
52
|
+
created_at: attachment.createdAt,
|
|
53
|
+
expires_at: attachment.expiresAt,
|
|
54
|
+
promotion: attachment.promotion,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function grantForWire(grant) {
|
|
58
|
+
return {
|
|
59
|
+
url: grant.url,
|
|
60
|
+
method: grant.method,
|
|
61
|
+
headers: grant.headers,
|
|
62
|
+
expires_at: grant.expiresAt,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function decodeBody(schema, request) {
|
|
66
|
+
return Effect.gen(function* () {
|
|
67
|
+
const text = yield* Effect.orDie(request.text);
|
|
68
|
+
let body;
|
|
69
|
+
try {
|
|
70
|
+
body = JSON.parse(text);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
body = undefined;
|
|
74
|
+
}
|
|
75
|
+
const decoded = yield* Effect.result(Schema.decodeUnknownEffect(schema)(body, { errors: "all", onExcessProperty: "error" }));
|
|
76
|
+
return Result.isFailure(decoded)
|
|
77
|
+
? { ok: false, issues: schemaIssues(decoded.failure) }
|
|
78
|
+
: { ok: true, value: decoded.success };
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
function invalidBody(requestId, issues) {
|
|
82
|
+
return HttpServerResponse.jsonUnsafe(errorBodyForWire({
|
|
83
|
+
error: "invalid_request",
|
|
84
|
+
detail: "The request body is invalid.",
|
|
85
|
+
requestId,
|
|
86
|
+
issues: issues,
|
|
87
|
+
}), { status: 400 });
|
|
88
|
+
}
|
|
89
|
+
/** Answers a failure the way every other route does: expected ones by status, the rest as 500. */
|
|
90
|
+
function answered(effect) {
|
|
91
|
+
return Effect.gen(function* () {
|
|
92
|
+
const requestId = yield* RequestId;
|
|
93
|
+
return yield* effect.pipe(Effect.catchCause((cause) => Cause.hasInterruptsOnly(cause)
|
|
94
|
+
? Effect.failCause(cause)
|
|
95
|
+
: failureResponse(cause, requestId)));
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* The attachment routes. Without file storage or the agent tables, or while runtime authentication
|
|
100
|
+
* is disabled, it serves nothing.
|
|
101
|
+
*/
|
|
102
|
+
export function attachmentsLayer(options) {
|
|
103
|
+
return Layer.effectDiscard(Effect.gen(function* () {
|
|
104
|
+
const router = yield* HttpRouter.HttpRouter;
|
|
105
|
+
const backend = yield* OntologyBackend;
|
|
106
|
+
const attachments = backend.attachments;
|
|
107
|
+
const agents = backend.agents;
|
|
108
|
+
const verifyRuntime = options.verifyRuntime;
|
|
109
|
+
if (attachments === undefined || agents === undefined || verifyRuntime === undefined) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const operations = makeOperations(backend, options.plan, options.hooks, options.connections, options.replicate);
|
|
113
|
+
/** Authenticates the runtime, then the member it acts for, the chat and the session. */
|
|
114
|
+
const asAgent = (answer) => (request) => Effect.gen(function* () {
|
|
115
|
+
const authenticated = yield* authenticateAgentCaller({
|
|
116
|
+
request,
|
|
117
|
+
agents,
|
|
118
|
+
verify: verifyRuntime,
|
|
119
|
+
allowUnpairedMember: true,
|
|
120
|
+
});
|
|
121
|
+
return authenticated.ok
|
|
122
|
+
? yield* answer(request, authenticated.caller, attachments)
|
|
123
|
+
: authenticated.response;
|
|
124
|
+
});
|
|
125
|
+
const idOf = Effect.map(HttpRouter.params, (params) => params.id ?? "");
|
|
126
|
+
yield* router.add("POST", ATTACHMENTS_PATH, asAgent((request, caller, runtime) => answered(Effect.gen(function* () {
|
|
127
|
+
const requestId = yield* RequestId;
|
|
128
|
+
const body = yield* decodeBody(Received, request);
|
|
129
|
+
if (!body.ok) {
|
|
130
|
+
return invalidBody(requestId, body.issues);
|
|
131
|
+
}
|
|
132
|
+
const received = yield* runtime.receive({
|
|
133
|
+
source: body.value.source,
|
|
134
|
+
sourceRef: body.value.source_ref,
|
|
135
|
+
filename: body.value.filename,
|
|
136
|
+
contentType: body.value.content_type,
|
|
137
|
+
size: body.value.size,
|
|
138
|
+
sha256: body.value.sha256,
|
|
139
|
+
}, caller);
|
|
140
|
+
return json({
|
|
141
|
+
attachment: attachmentForWire(received.attachment),
|
|
142
|
+
...(received.upload ? { upload: grantForWire(received.upload) } : {}),
|
|
143
|
+
}, 201);
|
|
144
|
+
}))));
|
|
145
|
+
yield* router.add("POST", `${ATTACHMENTS_PATH}/:id/complete`, asAgent((_, caller, runtime) => answered(Effect.gen(function* () {
|
|
146
|
+
const attachment = yield* runtime.complete(yield* idOf, caller);
|
|
147
|
+
return json({ attachment: attachmentForWire(attachment) });
|
|
148
|
+
}))));
|
|
149
|
+
yield* router.add("GET", ATTACHMENTS_PATH, asAgent((_, caller, runtime) => answered(Effect.gen(function* () {
|
|
150
|
+
const listed = yield* runtime.list(caller);
|
|
151
|
+
return json({ attachments: listed.map(attachmentForWire) });
|
|
152
|
+
}))));
|
|
153
|
+
yield* router.add("GET", `${ATTACHMENTS_PATH}/:id`, asAgent((_, caller, runtime) => answered(Effect.gen(function* () {
|
|
154
|
+
const { attachment, download } = yield* runtime.read(yield* idOf, caller);
|
|
155
|
+
return json({
|
|
156
|
+
attachment: attachmentForWire(attachment),
|
|
157
|
+
download: grantForWire(download),
|
|
158
|
+
});
|
|
159
|
+
}))));
|
|
160
|
+
yield* router.add("POST", `${ATTACHMENTS_PATH}/:id/discard`, asAgent((_, caller, runtime) => answered(Effect.gen(function* () {
|
|
161
|
+
const attachment = yield* runtime.discard(yield* idOf, caller);
|
|
162
|
+
return json({ attachment: attachmentForWire(attachment) });
|
|
163
|
+
}))));
|
|
164
|
+
yield* router.add("POST", `${ATTACHMENTS_PATH}/:id/promote`, asAgent((request, caller, runtime) => answered(Effect.gen(function* () {
|
|
165
|
+
const requestId = yield* RequestId;
|
|
166
|
+
const body = yield* decodeBody(Promotion, request);
|
|
167
|
+
if (!body.ok) {
|
|
168
|
+
return invalidBody(requestId, body.issues);
|
|
169
|
+
}
|
|
170
|
+
const promotion = body.value;
|
|
171
|
+
const metadata = yield* consumeChatEnvelope(promotion._meta ?? {}, {
|
|
172
|
+
kind: "runtime",
|
|
173
|
+
subjectId: caller.principal.id,
|
|
174
|
+
});
|
|
175
|
+
const attachmentId = yield* idOf;
|
|
176
|
+
const { attachments: sourceAttachments, ...sourceFields } = metadata.envelope?.source ?? {};
|
|
177
|
+
const matchingAttachments = sourceAttachments?.filter((attachment) => attachment.staged_id === attachmentId);
|
|
178
|
+
const source = metadata.envelope?.source === undefined
|
|
179
|
+
? undefined
|
|
180
|
+
: {
|
|
181
|
+
...metadata.envelope.source,
|
|
182
|
+
...sourceFields,
|
|
183
|
+
attachments: matchingAttachments?.length ? matchingAttachments : undefined,
|
|
184
|
+
};
|
|
185
|
+
const principal = source === undefined
|
|
186
|
+
? caller.principal
|
|
187
|
+
: yield* agents.actingMember(caller.principal.id, source.provider);
|
|
188
|
+
if (principal === undefined) {
|
|
189
|
+
return yield* new PermissionDenied({
|
|
190
|
+
message: "Runtime attachment provenance requires a current channel pairing.",
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
// This file route permits unpaired members; do not grant posting provenance.
|
|
194
|
+
// It is nevertheless a verified runtime path and cannot invoke the agent.
|
|
195
|
+
yield* checkRuntimeOperation({ kind: "runtime", subjectId: caller.principal.id }, promotion);
|
|
196
|
+
const promoted = yield* runtime.promote(yield* idOf, {
|
|
197
|
+
entity: promotion.entity,
|
|
198
|
+
action: promotion.action,
|
|
199
|
+
input: promotion.input ?? {},
|
|
200
|
+
...(promotion.field === undefined ? {} : { field: promotion.field }),
|
|
201
|
+
...(promotion.record_id === undefined ? {} : { recordId: promotion.record_id }),
|
|
202
|
+
}, { ...caller, principal }, (call) => Effect.gen(function* () {
|
|
203
|
+
const planned = options.plan.entities.find((entity) => entity.name === call.entity);
|
|
204
|
+
const action = planned?.actions.find((item) => item.name === call.action);
|
|
205
|
+
if (planned === undefined || action === undefined) {
|
|
206
|
+
return yield* Effect.die(new Error("The promotion's action was not planned."));
|
|
207
|
+
}
|
|
208
|
+
// The action runs as the member, with the after-commit hooks and connections
|
|
209
|
+
// of any other call.
|
|
210
|
+
const answer = yield* operations
|
|
211
|
+
.runAction(planned, action, {
|
|
212
|
+
input: call.input,
|
|
213
|
+
...(source === undefined ? {} : { runtime: { source } }),
|
|
214
|
+
validateOnly: false,
|
|
215
|
+
options: call.options,
|
|
216
|
+
identityToken: identityToken(request),
|
|
217
|
+
})
|
|
218
|
+
.pipe(Effect.provideService(CurrentPrincipal, principal), Effect.provideService(RequestId, requestId));
|
|
219
|
+
return { result: answer.result, edits: answer.edits };
|
|
220
|
+
}));
|
|
221
|
+
return json({
|
|
222
|
+
attachment: attachmentForWire(promoted.attachment),
|
|
223
|
+
deduplicated: promoted.deduplicated,
|
|
224
|
+
result: promoted.result,
|
|
225
|
+
});
|
|
226
|
+
}))));
|
|
227
|
+
}));
|
|
228
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { HttpServerRequest } from "effect/unstable/http";
|
|
3
|
+
import type { AttachmentCaller } from "../../storage/attachments.js";
|
|
4
|
+
import { RequestId } from "../errors.js";
|
|
5
|
+
import type { AgentStore } from "../runtime-contract.js";
|
|
6
|
+
import { type RuntimeTokenVerifier } from "../runtime-identity.js";
|
|
7
|
+
export declare const CONVERSATION_HEADER = "x-segmentstream-agent-conversation";
|
|
8
|
+
export declare const SESSION_HEADER = "x-segmentstream-agent-session";
|
|
9
|
+
/** Authenticate the runtime and resolve its member; attachment storage also checks chat access. */
|
|
10
|
+
export declare function authenticateAgentCaller(input: {
|
|
11
|
+
readonly request: HttpServerRequest.HttpServerRequest;
|
|
12
|
+
readonly agents: AgentStore;
|
|
13
|
+
readonly verify: RuntimeTokenVerifier;
|
|
14
|
+
/** Temporary attachments authorize active members against the chat registry, without a pairing. */
|
|
15
|
+
readonly allowUnpairedMember?: boolean;
|
|
16
|
+
}): Effect.Effect<{
|
|
17
|
+
readonly ok: false;
|
|
18
|
+
readonly response: import("effect/unstable/http/HttpServerResponse").HttpServerResponse;
|
|
19
|
+
} | {
|
|
20
|
+
readonly ok: true;
|
|
21
|
+
readonly caller: AttachmentCaller;
|
|
22
|
+
}, never, RequestId | HttpServerRequest.ParsedSearchParams>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Effect, Redacted } from "effect";
|
|
2
|
+
import { HttpServerRequest } from "effect/unstable/http";
|
|
3
|
+
import { HttpApiBuilder, HttpApiSecurity } from "effect/unstable/httpapi";
|
|
4
|
+
import { RequestId, forbidden, notFound, toServerResponse, unauthorized, unavailable, } from "../errors.js";
|
|
5
|
+
import { ACT_AS_HEADER, AGENT_TASK_HEADER, agentTaskSecret, logRuntimeRejection, } from "../runtime-identity.js";
|
|
6
|
+
export const CONVERSATION_HEADER = "x-segmentstream-agent-conversation";
|
|
7
|
+
export const SESSION_HEADER = "x-segmentstream-agent-session";
|
|
8
|
+
const CONVERSATION = /^[a-z][a-z0-9_-]{0,31}:[A-Za-z0-9:_-]{1,200}$/;
|
|
9
|
+
const SESSION = /^[A-Za-z0-9:_.-]{1,200}$/;
|
|
10
|
+
/** Authenticate the runtime and resolve its member; attachment storage also checks chat access. */
|
|
11
|
+
export function authenticateAgentCaller(input) {
|
|
12
|
+
return Effect.gen(function* () {
|
|
13
|
+
const { request, agents, verify } = input;
|
|
14
|
+
const requestId = yield* RequestId;
|
|
15
|
+
const credential = HttpApiBuilder.securityDecode(HttpApiSecurity.bearer);
|
|
16
|
+
const bearer = yield* Effect.provideService(credential, HttpServerRequest.HttpServerRequest, request);
|
|
17
|
+
const token = Redacted.value(bearer);
|
|
18
|
+
const verified = token === "" ? undefined : yield* Effect.promise(() => verify(token));
|
|
19
|
+
const denied = (response) => ({ ok: false, response: toServerResponse(response) });
|
|
20
|
+
switch (verified?.status) {
|
|
21
|
+
case "valid":
|
|
22
|
+
break;
|
|
23
|
+
case "invalid":
|
|
24
|
+
yield* logRuntimeRejection(verified.reason);
|
|
25
|
+
return denied(unauthorized(requestId, "The bearer token is invalid, expired or revoked."));
|
|
26
|
+
case "unavailable":
|
|
27
|
+
return denied(unavailable(requestId));
|
|
28
|
+
default:
|
|
29
|
+
return denied(forbidden(requestId, "Only the app's agent calls this route."));
|
|
30
|
+
}
|
|
31
|
+
// Attachments and member files are a member's; a task, acting as a workflow's user, has none.
|
|
32
|
+
if (agentTaskSecret(request) !== undefined) {
|
|
33
|
+
return denied(forbidden(requestId, `This route does not accept ${AGENT_TASK_HEADER}.`));
|
|
34
|
+
}
|
|
35
|
+
const actAs = request.headers[ACT_AS_HEADER]?.trim() ?? "";
|
|
36
|
+
const conversation = request.headers[CONVERSATION_HEADER]?.trim() ?? "";
|
|
37
|
+
const session = request.headers[SESSION_HEADER]?.trim() ?? "";
|
|
38
|
+
const member = actAs === ""
|
|
39
|
+
? undefined
|
|
40
|
+
: input.allowUnpairedMember
|
|
41
|
+
? (yield* agents.member(actAs))?.principal
|
|
42
|
+
: yield* agents.actingMember(actAs);
|
|
43
|
+
if (member === undefined) {
|
|
44
|
+
return denied(input.allowUnpairedMember
|
|
45
|
+
? notFound(requestId, "Attachment not found.")
|
|
46
|
+
: forbidden(requestId, "The member is inactive or has not paired with the agent."));
|
|
47
|
+
}
|
|
48
|
+
if (!CONVERSATION.test(conversation) || (session !== "" && !SESSION.test(session))) {
|
|
49
|
+
return denied(forbidden(requestId, "The agent names the chat and session of every request."));
|
|
50
|
+
}
|
|
51
|
+
const caller = {
|
|
52
|
+
principal: member,
|
|
53
|
+
conversation,
|
|
54
|
+
...(session === "" ? {} : { sessionId: session }),
|
|
55
|
+
};
|
|
56
|
+
return { ok: true, caller };
|
|
57
|
+
});
|
|
58
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { HttpServerRequest, HttpServerResponse } from "effect/unstable/http";
|
|
3
|
+
import type { ConfirmationStore } from "../../runtime/confirmations.js";
|
|
4
|
+
/** Mounted only behind the existing deployment-runtime verifier. No member/model endpoint. */
|
|
5
|
+
export declare function confirmationCommand(store: ConfirmationStore): (request: HttpServerRequest.HttpServerRequest) => Effect.Effect<HttpServerResponse.HttpServerResponse, never, never>;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Effect, Schema } from "effect";
|
|
2
|
+
import { HttpServerResponse } from "effect/unstable/http";
|
|
3
|
+
const Key = Schema.String.check(Schema.isPattern(/^[0-9a-f]{20}$/));
|
|
4
|
+
const Hash = Schema.String.check(Schema.isPattern(/^[0-9a-f]{64}$/));
|
|
5
|
+
const Member = Schema.String.check(Schema.isUUID());
|
|
6
|
+
const Record = Schema.Struct({
|
|
7
|
+
id: Schema.String.check(Schema.isPattern(/^hq:[0-9a-f]{64}$/)),
|
|
8
|
+
key: Key,
|
|
9
|
+
memberId: Member,
|
|
10
|
+
inputHash: Hash,
|
|
11
|
+
expiresAt: Schema.Number,
|
|
12
|
+
status: Schema.Literal("pending"),
|
|
13
|
+
data: Schema.Record(Schema.String, Schema.Unknown),
|
|
14
|
+
});
|
|
15
|
+
const Command = Schema.Union([
|
|
16
|
+
Schema.Struct({ operation: Schema.Literal("create"), record: Record }),
|
|
17
|
+
Schema.Struct({
|
|
18
|
+
operation: Schema.Literal("attach"),
|
|
19
|
+
key: Key,
|
|
20
|
+
messageId: Schema.String,
|
|
21
|
+
address: Schema.String,
|
|
22
|
+
}),
|
|
23
|
+
Schema.Struct({ operation: Schema.Literal("read"), key: Key }),
|
|
24
|
+
Schema.Struct({
|
|
25
|
+
operation: Schema.Literal("decide"),
|
|
26
|
+
key: Key,
|
|
27
|
+
memberId: Member,
|
|
28
|
+
inputHash: Hash,
|
|
29
|
+
decision: Schema.Literals(["approve", "cancel", "expire"]),
|
|
30
|
+
}),
|
|
31
|
+
Schema.Struct({
|
|
32
|
+
operation: Schema.Literal("finish"),
|
|
33
|
+
key: Key,
|
|
34
|
+
status: Schema.Literals(["done", "failed"]),
|
|
35
|
+
}),
|
|
36
|
+
Schema.Struct({
|
|
37
|
+
operation: Schema.Literal("expired"),
|
|
38
|
+
chatId: Schema.optionalKey(Schema.String),
|
|
39
|
+
}),
|
|
40
|
+
]);
|
|
41
|
+
/** Mounted only behind the existing deployment-runtime verifier. No member/model endpoint. */
|
|
42
|
+
export function confirmationCommand(store) {
|
|
43
|
+
return (request) => Effect.gen(function* () {
|
|
44
|
+
const text = yield* request.text;
|
|
45
|
+
if (text.length > 100_000) {
|
|
46
|
+
return HttpServerResponse.empty({ status: 413 });
|
|
47
|
+
}
|
|
48
|
+
const value = yield* Effect.try(() => JSON.parse(text));
|
|
49
|
+
const command = yield* Schema.decodeUnknownEffect(Command)(value);
|
|
50
|
+
let result;
|
|
51
|
+
switch (command.operation) {
|
|
52
|
+
case "create":
|
|
53
|
+
result = yield* store.create(command.record);
|
|
54
|
+
break;
|
|
55
|
+
case "attach":
|
|
56
|
+
yield* store.attach(command.key, command.messageId, command.address);
|
|
57
|
+
break;
|
|
58
|
+
case "read":
|
|
59
|
+
result = yield* store.read(command.key);
|
|
60
|
+
break;
|
|
61
|
+
case "decide":
|
|
62
|
+
result = yield* store.decide(command);
|
|
63
|
+
break;
|
|
64
|
+
case "finish":
|
|
65
|
+
yield* store.finish(command.key, command.status);
|
|
66
|
+
break;
|
|
67
|
+
case "expired":
|
|
68
|
+
result = yield* store.expired(command.chatId);
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
return HttpServerResponse.jsonUnsafe({ result: result ?? null }, { headers: { "cache-control": "no-store" } });
|
|
72
|
+
}).pipe(Effect.catch(() => Effect.succeed(HttpServerResponse.empty({ status: 400 }))));
|
|
73
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Layer } from "effect";
|
|
2
|
+
import { HttpRouter } from "effect/unstable/http";
|
|
3
|
+
import { type SessionExchange, type TokenVerifier } from "../authentication.js";
|
|
4
|
+
import { RequestId } from "../errors.js";
|
|
5
|
+
import { OntologyBackend } from "../runtime-contract.js";
|
|
6
|
+
import { type RuntimeTokenVerifier } from "../runtime-identity.js";
|
|
7
|
+
import { type ConversationTransport } from "./conversations.js";
|
|
8
|
+
/** Same member scope as MCP, accessible to app clients with their usual bearer/session. */
|
|
9
|
+
export declare function conversationRoutes(options: {
|
|
10
|
+
readonly transport: ConversationTransport;
|
|
11
|
+
readonly verifyToken: TokenVerifier;
|
|
12
|
+
readonly verifyRuntime?: RuntimeTokenVerifier | undefined;
|
|
13
|
+
readonly exchangeSession?: SessionExchange | undefined;
|
|
14
|
+
}): Layer.Layer<never, never, OntologyBackend | HttpRouter.HttpRouter | HttpRouter.Request<"Requires", RequestId>>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Effect, Layer, Schema } from "effect";
|
|
2
|
+
import { HttpRouter, HttpServerRequest, HttpServerResponse } from "effect/unstable/http";
|
|
3
|
+
import { HttpApiBuilder, HttpApiSecurity } from "effect/unstable/httpapi";
|
|
4
|
+
import { CurrentPrincipal, withPrincipal, } from "../authentication.js";
|
|
5
|
+
import { RequestId, expectedFailure, errorBodyForWire } from "../errors.js";
|
|
6
|
+
import { identityToken } from "../operations.js";
|
|
7
|
+
import { OntologyBackend } from "../runtime-contract.js";
|
|
8
|
+
import { runtimeCredential } from "../runtime-identity.js";
|
|
9
|
+
import { ConversationSearch } from "./conversations.js";
|
|
10
|
+
import { withChatMembership } from "../chat/resolve.js";
|
|
11
|
+
/** Same member scope as MCP, accessible to app clients with their usual bearer/session. */
|
|
12
|
+
export function conversationRoutes(options) {
|
|
13
|
+
return Layer.effectDiscard(Effect.gen(function* () {
|
|
14
|
+
const router = yield* HttpRouter.HttpRouter;
|
|
15
|
+
const backend = yield* OntologyBackend;
|
|
16
|
+
const transport = withChatMembership(options.transport, backend);
|
|
17
|
+
yield* router.add("POST", "/api/ontology/agent/conversations/search", (request) => Effect.gen(function* () {
|
|
18
|
+
const bearer = yield* HttpApiBuilder.securityDecode(HttpApiSecurity.bearer).pipe(Effect.provideService(HttpServerRequest.HttpServerRequest, request));
|
|
19
|
+
const operation = Effect.gen(function* () {
|
|
20
|
+
const search = yield* Schema.decodeUnknownEffect(ConversationSearch)(yield* request.json);
|
|
21
|
+
const principal = yield* CurrentPrincipal;
|
|
22
|
+
const page = yield* transport({
|
|
23
|
+
search,
|
|
24
|
+
principal,
|
|
25
|
+
identityToken: identityToken(request),
|
|
26
|
+
});
|
|
27
|
+
return HttpServerResponse.jsonUnsafe(page, {
|
|
28
|
+
headers: { "cache-control": "private, no-store" },
|
|
29
|
+
});
|
|
30
|
+
}).pipe(Effect.catch((error) => Effect.gen(function* () {
|
|
31
|
+
const requestId = yield* RequestId;
|
|
32
|
+
const failure = expectedFailure(error, requestId);
|
|
33
|
+
return HttpServerResponse.jsonUnsafe(errorBodyForWire(failure?.body ?? {
|
|
34
|
+
error: "invalid_request",
|
|
35
|
+
detail: "The conversation request is invalid.",
|
|
36
|
+
requestId,
|
|
37
|
+
}), { status: failure?.status ?? 400 });
|
|
38
|
+
})));
|
|
39
|
+
return yield* withPrincipal(bearer, options.verifyToken, backend, operation, {
|
|
40
|
+
runtime: runtimeCredential(options.verifyRuntime, request),
|
|
41
|
+
session: { request, exchange: options.exchangeSession },
|
|
42
|
+
});
|
|
43
|
+
}));
|
|
44
|
+
}));
|
|
45
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Effect, Schema } from "effect";
|
|
2
|
+
import type { Principal } from "../../runtime.js";
|
|
3
|
+
import { PermissionDenied } from "../../errors.js";
|
|
4
|
+
import type { OntologyEnvironment } from "../config.js";
|
|
5
|
+
export declare const ConversationSearch: Schema.Struct<{
|
|
6
|
+
readonly q: Schema.optionalKey<Schema.String>;
|
|
7
|
+
readonly provider: Schema.optionalKey<Schema.String>;
|
|
8
|
+
readonly chatId: Schema.optionalKey<Schema.String>;
|
|
9
|
+
readonly threadId: Schema.optionalKey<Schema.String>;
|
|
10
|
+
readonly senderId: Schema.optionalKey<Schema.String>;
|
|
11
|
+
readonly from: Schema.optionalKey<Schema.String>;
|
|
12
|
+
readonly to: Schema.optionalKey<Schema.String>;
|
|
13
|
+
readonly before: Schema.optionalKey<Schema.String>;
|
|
14
|
+
readonly limit: Schema.optionalKey<Schema.Int>;
|
|
15
|
+
}>;
|
|
16
|
+
export type ConversationSearch = typeof ConversationSearch.Type;
|
|
17
|
+
export declare const ConversationPage: Schema.Struct<{
|
|
18
|
+
readonly events: Schema.$Array<Schema.$Record<Schema.String, Schema.Unknown>>;
|
|
19
|
+
readonly nextCursor: Schema.NullOr<Schema.String>;
|
|
20
|
+
}>;
|
|
21
|
+
export type ConversationPage = typeof ConversationPage.Type;
|
|
22
|
+
declare const ConversationArchiveUnavailable_base: Schema.Class<ConversationArchiveUnavailable, Schema.TaggedStruct<"ConversationArchiveUnavailable", {
|
|
23
|
+
readonly diagnostic: Schema.String;
|
|
24
|
+
readonly cause: Schema.optionalKey<Schema.Unknown>;
|
|
25
|
+
}>, import("effect/Cause").YieldableError>;
|
|
26
|
+
export declare class ConversationArchiveUnavailable extends ConversationArchiveUnavailable_base {
|
|
27
|
+
}
|
|
28
|
+
export type ConversationTransport = (input: {
|
|
29
|
+
readonly search: ConversationSearch;
|
|
30
|
+
readonly principal: Principal;
|
|
31
|
+
readonly identityToken: string | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* Group conversations (`provider:chatId`) the member is in. Their history is readable without
|
|
34
|
+
* `agent_chat:read`, as their attachments are; see `withChatMembership`.
|
|
35
|
+
*/
|
|
36
|
+
readonly memberGroups?: ReadonlyArray<string>;
|
|
37
|
+
}) => Effect.Effect<ConversationPage, ConversationArchiveUnavailable | PermissionDenied>;
|
|
38
|
+
/** The authenticated ontology service forwards its resolved member, never a caller-supplied ID. */
|
|
39
|
+
export declare function platformConversations(environment: OntologyEnvironment, fetchImpl?: typeof fetch): ConversationTransport;
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { Effect, Schema } from "effect";
|
|
2
|
+
import { PermissionDenied } from "../../errors.js";
|
|
3
|
+
import { isAllowed } from "../../permissions.js";
|
|
4
|
+
import { describeError } from "../metric-query-platform.js";
|
|
5
|
+
const Filter = Schema.String.check(Schema.isMaxLength(1000));
|
|
6
|
+
export const ConversationSearch = Schema.Struct({
|
|
7
|
+
q: Schema.optionalKey(Filter),
|
|
8
|
+
provider: Schema.optionalKey(Filter),
|
|
9
|
+
chatId: Schema.optionalKey(Filter),
|
|
10
|
+
threadId: Schema.optionalKey(Filter),
|
|
11
|
+
senderId: Schema.optionalKey(Filter),
|
|
12
|
+
from: Schema.optionalKey(Filter),
|
|
13
|
+
to: Schema.optionalKey(Filter),
|
|
14
|
+
before: Schema.optionalKey(Filter),
|
|
15
|
+
limit: Schema.optionalKey(Schema.Int.check(Schema.isBetween({ minimum: 1, maximum: 200 }))),
|
|
16
|
+
});
|
|
17
|
+
export const ConversationPage = Schema.Struct({
|
|
18
|
+
events: Schema.Array(Schema.Record(Schema.String, Schema.Unknown)),
|
|
19
|
+
nextCursor: Schema.NullOr(Schema.String),
|
|
20
|
+
});
|
|
21
|
+
export class ConversationArchiveUnavailable extends Schema.TaggedError()("ConversationArchiveUnavailable", { diagnostic: Schema.String, cause: Schema.optionalKey(Schema.Unknown) }) {
|
|
22
|
+
}
|
|
23
|
+
/** The authenticated ontology service forwards its resolved member, never a caller-supplied ID. */
|
|
24
|
+
export function platformConversations(environment, fetchImpl = fetch) {
|
|
25
|
+
return ({ search, principal, identityToken, memberGroups }) => {
|
|
26
|
+
if (principal.kind !== "member") {
|
|
27
|
+
return Effect.fail(new PermissionDenied({
|
|
28
|
+
message: "Only members may read conversations.",
|
|
29
|
+
permission: "conversation:participant",
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
32
|
+
if (!identityToken) {
|
|
33
|
+
return Effect.fail(new ConversationArchiveUnavailable({ diagnostic: "runtime_identity_missing" }));
|
|
34
|
+
}
|
|
35
|
+
return Effect.tryPromise({
|
|
36
|
+
try: async (signal) => {
|
|
37
|
+
const base = `${environment.segmentstreamUrl}/api/internal/v1/workspaces/`;
|
|
38
|
+
const response = await fetchImpl(`${base}${encodeURIComponent(environment.workspaceId)}/agent/conversations/search`, {
|
|
39
|
+
method: "POST",
|
|
40
|
+
redirect: "error",
|
|
41
|
+
headers: {
|
|
42
|
+
"content-type": "application/json",
|
|
43
|
+
"x-segmentstream-organization-id": environment.organizationId,
|
|
44
|
+
"x-segmentstream-runtime-identity": identityToken,
|
|
45
|
+
},
|
|
46
|
+
body: JSON.stringify({
|
|
47
|
+
search,
|
|
48
|
+
reader: {
|
|
49
|
+
participantId: principal.id,
|
|
50
|
+
groups: isAllowed("agent_chat:read", principal),
|
|
51
|
+
groupChats: memberGroups ?? [],
|
|
52
|
+
admin: false,
|
|
53
|
+
},
|
|
54
|
+
}),
|
|
55
|
+
signal: AbortSignal.any([signal, AbortSignal.timeout(15_000)]),
|
|
56
|
+
});
|
|
57
|
+
if (!response.ok) {
|
|
58
|
+
throw new Error(`Conversation archive returned HTTP ${response.status}; ` +
|
|
59
|
+
`request ${response.headers.get("x-request-id") ?? "unknown"}.`);
|
|
60
|
+
}
|
|
61
|
+
return Schema.decodeUnknownSync(ConversationPage)(await response.json());
|
|
62
|
+
},
|
|
63
|
+
catch: (cause) => new ConversationArchiveUnavailable({ diagnostic: "archive_request_failed", cause }),
|
|
64
|
+
}).pipe(Effect.tapError((error) => Effect.logWarning("ontology.conversations.read_failed").pipe(Effect.annotateLogs({
|
|
65
|
+
diagnostic: error.diagnostic,
|
|
66
|
+
error: describeError(error.cause, (text) => text.split(identityToken).join("[redacted]")),
|
|
67
|
+
}))));
|
|
68
|
+
};
|
|
69
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Layer } from "effect";
|
|
2
|
+
import { HttpRouter } from "effect/unstable/http";
|
|
3
|
+
import { RequestId } from "../errors.js";
|
|
4
|
+
import type { ApiPlan } from "../plan.js";
|
|
5
|
+
import { OntologyBackend } from "../runtime-contract.js";
|
|
6
|
+
import type { RuntimeTokenVerifier } from "../runtime-identity.js";
|
|
7
|
+
export declare const FILES_PATH = "/api/ontology/agent/files";
|
|
8
|
+
/** A short-lived download grant, issued only after the runtime's member may read the file. */
|
|
9
|
+
export declare function filesLayer(options: {
|
|
10
|
+
readonly plan: ApiPlan;
|
|
11
|
+
readonly verifyRuntime: RuntimeTokenVerifier | undefined;
|
|
12
|
+
}): Layer.Layer<never, never, OntologyBackend | HttpRouter.HttpRouter | HttpRouter.Request<"Requires", RequestId>>;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { Cause, Effect, Layer } from "effect";
|
|
2
|
+
import { HttpRouter, HttpServerResponse } from "effect/unstable/http";
|
|
3
|
+
import { resolveFileRecord } from "../../runtime/files.js";
|
|
4
|
+
import { isUuid } from "../../query.js";
|
|
5
|
+
import { RequestId, failureResponse, notFound, toServerResponse } from "../errors.js";
|
|
6
|
+
import { OntologyBackend } from "../runtime-contract.js";
|
|
7
|
+
import { authenticateAgentCaller } from "./authentication.js";
|
|
8
|
+
import { AGENT_PATH } from "./server.js";
|
|
9
|
+
export const FILES_PATH = `${AGENT_PATH}/files`;
|
|
10
|
+
/** A short-lived download grant, issued only after the runtime's member may read the file. */
|
|
11
|
+
export function filesLayer(options) {
|
|
12
|
+
return Layer.effectDiscard(Effect.gen(function* () {
|
|
13
|
+
const router = yield* HttpRouter.HttpRouter;
|
|
14
|
+
const backend = yield* OntologyBackend;
|
|
15
|
+
const { blobs, agents } = backend;
|
|
16
|
+
const verify = options.verifyRuntime;
|
|
17
|
+
if (blobs === undefined || agents === undefined || verify === undefined) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const read = (request) => Effect.gen(function* () {
|
|
21
|
+
const requestId = yield* RequestId;
|
|
22
|
+
const authenticated = yield* authenticateAgentCaller({ request, agents, verify });
|
|
23
|
+
if (!authenticated.ok) {
|
|
24
|
+
return authenticated.response;
|
|
25
|
+
}
|
|
26
|
+
const params = yield* HttpRouter.params;
|
|
27
|
+
const id = params.id ?? "";
|
|
28
|
+
if (!isUuid(id)) {
|
|
29
|
+
return toServerResponse(notFound(requestId, "File record not found."));
|
|
30
|
+
}
|
|
31
|
+
const resolved = yield* resolveFileRecord({
|
|
32
|
+
manifest: options.plan.ontology.manifest,
|
|
33
|
+
reads: backend,
|
|
34
|
+
principal: authenticated.caller.principal,
|
|
35
|
+
reference: {
|
|
36
|
+
entity: params.entity ?? "",
|
|
37
|
+
id,
|
|
38
|
+
...(params.property === undefined ? {} : { property: params.property }),
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
// Pin the revision read above. download rechecks live permissions in its transaction.
|
|
42
|
+
const download = yield* blobs.download(resolved.entity, resolved.id, resolved.property, { revisionId: resolved.file.id }, authenticated.caller.principal);
|
|
43
|
+
return HttpServerResponse.jsonUnsafe({
|
|
44
|
+
file: {
|
|
45
|
+
id,
|
|
46
|
+
entity: resolved.entity,
|
|
47
|
+
property: resolved.property,
|
|
48
|
+
filename: resolved.file.filename,
|
|
49
|
+
content_type: resolved.file.contentType,
|
|
50
|
+
size: resolved.file.size,
|
|
51
|
+
},
|
|
52
|
+
download: {
|
|
53
|
+
url: download.url,
|
|
54
|
+
method: download.method,
|
|
55
|
+
headers: download.headers,
|
|
56
|
+
expires_at: download.expiresAt,
|
|
57
|
+
},
|
|
58
|
+
}, { headers: { "cache-control": "no-store" } });
|
|
59
|
+
}).pipe(Effect.catchTag("UnsupportedFile", (error) => Effect.map(RequestId, (requestId) => HttpServerResponse.jsonUnsafe({
|
|
60
|
+
error: "unsupported",
|
|
61
|
+
detail: error.message,
|
|
62
|
+
request_id: requestId,
|
|
63
|
+
}, { status: 422 }))), Effect.catchCause((cause) => Cause.hasInterruptsOnly(cause)
|
|
64
|
+
? Effect.failCause(cause)
|
|
65
|
+
: Effect.flatMap(RequestId, (requestId) => failureResponse(cause, requestId))));
|
|
66
|
+
yield* router.add("GET", `${FILES_PATH}/:entity/:id`, read);
|
|
67
|
+
yield* router.add("GET", `${FILES_PATH}/:entity/:id/:property`, read);
|
|
68
|
+
}));
|
|
69
|
+
}
|