create-windy 0.5.1 → 0.6.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/dist/cli.js +486 -156
- package/package.json +2 -1
- package/template/.windy-template.json +2 -2
- package/template/apps/agent-server/README.md +25 -6
- package/template/apps/agent-server/src/southwind_agent_server/adk_adapter.py +15 -2
- package/template/apps/agent-server/src/southwind_agent_server/app.py +13 -34
- package/template/apps/agent-server/src/southwind_agent_server/config.py +49 -0
- package/template/apps/agent-server/src/southwind_agent_server/contracts.py +13 -0
- package/template/apps/agent-server/src/southwind_agent_server/engine_capacity.py +31 -0
- package/template/apps/agent-server/src/southwind_agent_server/fingerprint.py +5 -0
- package/template/apps/agent-server/src/southwind_agent_server/health_routes.py +50 -0
- package/template/apps/agent-server/src/southwind_agent_server/openai_engine.py +11 -2
- package/template/apps/agent-server/src/southwind_agent_server/openai_provider.py +3 -9
- package/template/apps/agent-server/src/southwind_agent_server/postgres_store.py +5 -0
- package/template/apps/agent-server/src/southwind_agent_server/readiness_pin.py +37 -0
- package/template/apps/agent-server/src/southwind_agent_server/run_admission.py +64 -0
- package/template/apps/agent-server/src/southwind_agent_server/run_capacity.py +59 -0
- package/template/apps/agent-server/src/southwind_agent_server/service.py +42 -43
- package/template/apps/agent-server/src/southwind_agent_server/service_errors.py +4 -0
- package/template/apps/agent-server/src/southwind_agent_server/service_execution.py +31 -0
- package/template/apps/agent-server/src/southwind_agent_server/service_tasks.py +34 -0
- package/template/apps/agent-server/src/southwind_agent_server/sqlite_catalog.py +11 -0
- package/template/apps/agent-server/src/southwind_agent_server/store.py +6 -0
- package/template/apps/agent-server/src/southwind_agent_server/vision_probe.py +87 -0
- package/template/apps/agent-server/src/southwind_agent_server/vision_requirement.py +28 -0
- package/template/apps/agent-server/src/southwind_agent_server/vlm_readiness.py +247 -0
- package/template/apps/agent-server/tests/test_api.py +16 -3
- package/template/apps/agent-server/tests/test_openai_provider.py +21 -4
- package/template/apps/agent-server/tests/test_postgres_store.py +3 -0
- package/template/apps/agent-server/tests/test_run_capacity.py +110 -0
- package/template/apps/agent-server/tests/test_runtime_factory_readiness.py +37 -0
- package/template/apps/agent-server/tests/test_sqlite_store.py +3 -0
- package/template/apps/agent-server/tests/test_vision_readiness_enforcement.py +72 -0
- package/template/apps/agent-server/tests/test_vlm_readiness.py +106 -0
- package/template/apps/document-server/src/southwind_document_server/adapter.py +117 -205
- package/template/apps/document-server/src/southwind_document_server/adapter_errors.py +13 -0
- package/template/apps/document-server/src/southwind_document_server/app.py +62 -14
- package/template/apps/document-server/src/southwind_document_server/artifacts.py +27 -0
- package/template/apps/document-server/src/southwind_document_server/config.py +96 -2
- package/template/apps/document-server/src/southwind_document_server/contracts.py +168 -13
- package/template/apps/document-server/src/southwind_document_server/fingerprint.py +128 -0
- package/template/apps/document-server/src/southwind_document_server/grants.py +81 -0
- package/template/apps/document-server/src/southwind_document_server/multipart_output.py +265 -0
- package/template/apps/document-server/src/southwind_document_server/output_validation.py +202 -0
- package/template/apps/document-server/src/southwind_document_server/progress.py +27 -0
- package/template/apps/document-server/src/southwind_document_server/readiness.py +280 -0
- package/template/apps/document-server/src/southwind_document_server/readiness_contracts.py +280 -0
- package/template/apps/document-server/src/southwind_document_server/readiness_http.py +87 -0
- package/template/apps/document-server/src/southwind_document_server/readiness_support.py +120 -0
- package/template/apps/document-server/src/southwind_document_server/request_validation.py +48 -0
- package/template/apps/document-server/src/southwind_document_server/service.py +297 -96
- package/template/apps/document-server/src/southwind_document_server/service_recovery.py +183 -0
- package/template/apps/document-server/src/southwind_document_server/sink.py +316 -0
- package/template/apps/document-server/src/southwind_document_server/store.py +301 -141
- package/template/apps/document-server/src/southwind_document_server/store_events.py +40 -0
- package/template/apps/document-server/src/southwind_document_server/store_models.py +62 -0
- package/template/apps/document-server/src/southwind_document_server/store_recovery.py +247 -0
- package/template/apps/document-server/src/southwind_document_server/store_schema.py +50 -0
- package/template/apps/document-server/tests/recovery_support.py +230 -0
- package/template/apps/document-server/tests/support.py +210 -0
- package/template/apps/document-server/tests/test_adapter.py +251 -0
- package/template/apps/document-server/tests/test_config.py +43 -0
- package/template/apps/document-server/tests/test_contracts.py +80 -0
- package/template/apps/document-server/tests/test_fingerprint.py +125 -0
- package/template/apps/document-server/tests/test_grants.py +46 -0
- package/template/apps/document-server/tests/test_handshake.py +154 -0
- package/template/apps/document-server/tests/test_integration.py +192 -0
- package/template/apps/document-server/tests/test_multipart_security.py +259 -0
- package/template/apps/document-server/tests/test_readiness.py +311 -0
- package/template/apps/document-server/tests/test_readiness_contracts.py +131 -0
- package/template/apps/document-server/tests/test_recovery.py +222 -0
- package/template/apps/document-server/tests/test_recovery_faults.py +101 -0
- package/template/apps/document-server/tests/test_recovery_races.py +283 -0
- package/template/apps/document-server/tests/test_service.py +16 -13
- package/template/apps/document-server/tests/test_service_artifacts.py +296 -0
- package/template/apps/document-server/tests/test_sink.py +253 -0
- package/template/apps/document-server/tests/test_store.py +199 -0
- package/template/apps/embedding-server/pyproject.toml +5 -0
- package/template/apps/embedding-server/src/southwind_embedding_server/adapter.py +38 -2
- package/template/apps/embedding-server/src/southwind_embedding_server/app.py +111 -3
- package/template/apps/embedding-server/src/southwind_embedding_server/config.py +27 -0
- package/template/apps/embedding-server/src/southwind_embedding_server/image_input.py +16 -5
- package/template/apps/embedding-server/src/southwind_embedding_server/run_cipher.py +31 -0
- package/template/apps/embedding-server/src/southwind_embedding_server/run_service.py +130 -0
- package/template/apps/embedding-server/src/southwind_embedding_server/run_store.py +250 -0
- package/template/apps/embedding-server/tests/test_adapter.py +25 -0
- package/template/apps/embedding-server/tests/test_run_http.py +185 -0
- package/template/apps/embedding-server/tests/test_run_service.py +200 -0
- package/template/apps/embedding-server/uv.lock +71 -0
- package/template/apps/server/Dockerfile +13 -0
- package/template/apps/server/package.json +1 -0
- package/template/apps/server/src/agent/drizzle-screenshot-intake-repository.integration.test.ts +283 -0
- package/template/apps/server/src/agent/drizzle-screenshot-intake-repository.ts +175 -0
- package/template/apps/server/src/agent/persistent-screenshot-intake-producer.ts +320 -0
- package/template/apps/server/src/agent/remote-runtime.ts +8 -1
- package/template/apps/server/src/agent/required-environment.ts +5 -0
- package/template/apps/server/src/agent/run-attach.ts +41 -0
- package/template/apps/server/src/agent/run-audit.ts +49 -0
- package/template/apps/server/src/agent/run-contracts.ts +6 -1
- package/template/apps/server/src/agent/run-facade.ts +66 -68
- package/template/apps/server/src/agent/run-route-input.ts +26 -1
- package/template/apps/server/src/agent/run-routes.ts +1 -0
- package/template/apps/server/src/agent/runtime-bootstrap-report.test.ts +1 -1
- package/template/apps/server/src/agent/runtime-bootstrap.ts +110 -60
- package/template/apps/server/src/agent/runtime-readiness-sources.test.ts +27 -0
- package/template/apps/server/src/agent/runtime-readiness-sources.ts +31 -0
- package/template/apps/server/src/agent/runtime-reporting-bootstrap.ts +40 -0
- package/template/apps/server/src/agent/screenshot-intake-authorization.ts +29 -0
- package/template/apps/server/src/agent/screenshot-intake-bootstrap.ts +61 -0
- package/template/apps/server/src/agent/screenshot-intake-durable.ts +53 -0
- package/template/apps/server/src/agent/screenshot-intake-errors.ts +9 -0
- package/template/apps/server/src/agent/screenshot-intake-producer.ts +41 -0
- package/template/apps/server/src/agent/screenshot-intake-record.ts +44 -0
- package/template/apps/server/src/agent/screenshot-intake-recovery.ts +106 -0
- package/template/apps/server/src/agent/screenshot-intake-repository.ts +64 -0
- package/template/apps/server/src/agent/screenshot-intake-reservation.ts +24 -0
- package/template/apps/server/src/agent/screenshot-intake-routes.ts +171 -0
- package/template/apps/server/src/agent/screenshot-intake-runtime-types.ts +6 -0
- package/template/apps/server/src/agent/screenshot-intake-sweep.ts +26 -0
- package/template/apps/server/src/agent/screenshot-intake-test-support.ts +87 -0
- package/template/apps/server/src/agent/screenshot-intake-v2-validation.ts +152 -0
- package/template/apps/server/src/agent/screenshot-intake-v2.test.ts +338 -0
- package/template/apps/server/src/agent/screenshot-intake-v2.ts +350 -0
- package/template/apps/server/src/agent/screenshot-png.ts +15 -0
- package/template/apps/server/src/agent/screenshot-run-binding.ts +34 -0
- package/template/apps/server/src/agent/unavailable-routes.ts +9 -0
- package/template/apps/server/src/agent/vision-facade.test.ts +98 -8
- package/template/apps/server/src/agent/vision-input.ts +5 -2
- package/template/apps/server/src/agent/vision-readiness-pin.ts +74 -0
- package/template/apps/server/src/agent/vision-readiness.ts +58 -0
- package/template/apps/server/src/ai-artifact/runtime-reference.test.ts +135 -0
- package/template/apps/server/src/ai-artifact/runtime.ts +134 -5
- package/template/apps/server/src/ai-output-artifact/cleanup.ts +214 -0
- package/template/apps/server/src/ai-output-artifact/contracts.ts +152 -0
- package/template/apps/server/src/ai-output-artifact/drizzle-cleanup.ts +37 -0
- package/template/apps/server/src/ai-output-artifact/drizzle-complete.ts +71 -0
- package/template/apps/server/src/ai-output-artifact/drizzle-grant-cleanup.ts +45 -0
- package/template/apps/server/src/ai-output-artifact/drizzle-grants.ts +109 -0
- package/template/apps/server/src/ai-output-artifact/drizzle-mapping.ts +77 -0
- package/template/apps/server/src/ai-output-artifact/drizzle-readiness.ts +46 -0
- package/template/apps/server/src/ai-output-artifact/drizzle-repository.ts +350 -0
- package/template/apps/server/src/ai-output-artifact/drizzle-seal.ts +64 -0
- package/template/apps/server/src/ai-output-artifact/grant.ts +30 -0
- package/template/apps/server/src/ai-output-artifact/host-registry.ts +53 -0
- package/template/apps/server/src/ai-output-artifact/memory-cleanup.ts +47 -0
- package/template/apps/server/src/ai-output-artifact/memory-grants.ts +98 -0
- package/template/apps/server/src/ai-output-artifact/memory-readiness.ts +26 -0
- package/template/apps/server/src/ai-output-artifact/memory-repository.ts +348 -0
- package/template/apps/server/src/ai-output-artifact/policy.test.ts +67 -0
- package/template/apps/server/src/ai-output-artifact/policy.ts +125 -0
- package/template/apps/server/src/ai-output-artifact/postgres-test-support.ts +147 -0
- package/template/apps/server/src/ai-output-artifact/postgres.integration.test.ts +349 -0
- package/template/apps/server/src/ai-output-artifact/reference-codec.ts +128 -0
- package/template/apps/server/src/ai-output-artifact/repository-grant-invariants.test-support.ts +165 -0
- package/template/apps/server/src/ai-output-artifact/repository-invariants.test-support.ts +239 -0
- package/template/apps/server/src/ai-output-artifact/repository-invariants.test.ts +18 -0
- package/template/apps/server/src/ai-output-artifact/repository.ts +107 -0
- package/template/apps/server/src/ai-output-artifact/route-input.ts +173 -0
- package/template/apps/server/src/ai-output-artifact/routes-delete.test.ts +287 -0
- package/template/apps/server/src/ai-output-artifact/routes-grant.test.ts +116 -0
- package/template/apps/server/src/ai-output-artifact/routes-nonblocking-body.test.ts +136 -0
- package/template/apps/server/src/ai-output-artifact/routes-security.test.ts +176 -0
- package/template/apps/server/src/ai-output-artifact/routes-storage-error.test.ts +105 -0
- package/template/apps/server/src/ai-output-artifact/routes.test-support.ts +84 -0
- package/template/apps/server/src/ai-output-artifact/routes.test.ts +198 -0
- package/template/apps/server/src/ai-output-artifact/routes.ts +280 -0
- package/template/apps/server/src/ai-output-artifact/service-completion.ts +60 -0
- package/template/apps/server/src/ai-output-artifact/service-grants.test.ts +169 -0
- package/template/apps/server/src/ai-output-artifact/service-grants.ts +217 -0
- package/template/apps/server/src/ai-output-artifact/service-input.ts +175 -0
- package/template/apps/server/src/ai-output-artifact/service-read.ts +89 -0
- package/template/apps/server/src/ai-output-artifact/service-recovery.test.ts +238 -0
- package/template/apps/server/src/ai-output-artifact/service-support.ts +240 -0
- package/template/apps/server/src/ai-output-artifact/service.test.ts +283 -0
- package/template/apps/server/src/ai-output-artifact/service.ts +334 -0
- package/template/apps/server/src/ai-output-artifact/storage-recovery.ts +33 -0
- package/template/apps/server/src/ai-output-artifact/storage-writer.ts +103 -0
- package/template/apps/server/src/ai-output-artifact/test-support.ts +161 -0
- package/template/apps/server/src/ai-runtime-readiness/health-response.ts +92 -0
- package/template/apps/server/src/ai-runtime-readiness/operation-port-trust.test.ts +66 -0
- package/template/apps/server/src/ai-runtime-readiness/operation-port.test-support.ts +143 -0
- package/template/apps/server/src/ai-runtime-readiness/operation-port.test.ts +193 -0
- package/template/apps/server/src/ai-runtime-readiness/operation-port.ts +172 -0
- package/template/apps/server/src/ai-runtime-readiness/trust-store.ts +61 -0
- package/template/apps/server/src/app/ai-screenshot-intake-binding.ts +22 -0
- package/template/apps/server/src/app/document-output-artifact-bindings.ts +5 -0
- package/template/apps/server/src/app/speech-output-artifact-bindings.ts +5 -0
- package/template/apps/server/src/application-services.ts +9 -3
- package/template/apps/server/src/audit/redaction.ts +1 -0
- package/template/apps/server/src/audit/reliable-writer.test.ts +8 -0
- package/template/apps/server/src/auth/password-change-license-restriction.test.ts +156 -0
- package/template/apps/server/src/document/cancel-response.ts +33 -0
- package/template/apps/server/src/document/contracts.ts +6 -0
- package/template/apps/server/src/document/errors.ts +11 -0
- package/template/apps/server/src/document/facade-cancel.test.ts +226 -0
- package/template/apps/server/src/document/facade-cancel.ts +110 -0
- package/template/apps/server/src/document/facade-grant-handoff.test.ts +113 -0
- package/template/apps/server/src/document/facade-idempotency.test.ts +195 -0
- package/template/apps/server/src/document/facade-invocation.ts +46 -0
- package/template/apps/server/src/document/facade-output-artifact.test.ts +310 -0
- package/template/apps/server/src/document/facade-read-response.ts +116 -0
- package/template/apps/server/src/document/facade-readiness.test.ts +95 -0
- package/template/apps/server/src/document/facade-support.ts +297 -0
- package/template/apps/server/src/document/facade.ts +164 -173
- package/template/apps/server/src/document/output-artifact-composition.test.ts +64 -0
- package/template/apps/server/src/document/output-artifact-composition.ts +78 -0
- package/template/apps/server/src/document/output-artifact-fingerprint.contract.test.ts +110 -0
- package/template/apps/server/src/document/output-artifact-fingerprint.ts +150 -0
- package/template/apps/server/src/document/output-artifact-host-registry.ts +44 -0
- package/template/apps/server/src/document/output-artifact-host.test.ts +332 -0
- package/template/apps/server/src/document/output-artifact-host.ts +331 -0
- package/template/apps/server/src/document/output-artifact-manifest.test-support.ts +71 -0
- package/template/apps/server/src/document/output-artifact-publish.test-support.ts +48 -0
- package/template/apps/server/src/document/output-artifact-readiness-probe.ts +347 -0
- package/template/apps/server/src/document/output-artifact-readiness-timeout.ts +30 -0
- package/template/apps/server/src/document/output-artifact-readiness.test.ts +264 -0
- package/template/apps/server/src/document/output-artifact-readiness.ts +87 -0
- package/template/apps/server/src/document/output-artifact-route-composition.test.ts +27 -0
- package/template/apps/server/src/document/output-artifact-route-composition.ts +14 -0
- package/template/apps/server/src/document/output-artifact-runtime.test-support.ts +8 -0
- package/template/apps/server/src/document/output-artifact-runtime.test.ts +124 -0
- package/template/apps/server/src/document/output-artifact-runtime.ts +275 -0
- package/template/apps/server/src/document/output-artifact.test-support.ts +350 -0
- package/template/apps/server/src/document/remote-response.ts +162 -0
- package/template/apps/server/src/document/remote-runtime.test.ts +100 -4
- package/template/apps/server/src/document/remote-runtime.ts +37 -85
- package/template/apps/server/src/document/routes-read-response.test.ts +267 -0
- package/template/apps/server/src/document/routes.test.ts +109 -0
- package/template/apps/server/src/document/routes.ts +23 -14
- package/template/apps/server/src/embedding/audit.ts +46 -0
- package/template/apps/server/src/embedding/contracts.ts +13 -0
- package/template/apps/server/src/embedding/drizzle-run-binding-repository.integration.test.ts +100 -0
- package/template/apps/server/src/embedding/drizzle-run-binding-repository.ts +102 -0
- package/template/apps/server/src/embedding/facade-types.ts +18 -0
- package/template/apps/server/src/embedding/facade.ts +242 -111
- package/template/apps/server/src/embedding/operation-authorization.ts +23 -0
- package/template/apps/server/src/embedding/remote-runtime.test.ts +18 -0
- package/template/apps/server/src/embedding/remote-runtime.ts +77 -0
- package/template/apps/server/src/embedding/routes.test.ts +118 -0
- package/template/apps/server/src/embedding/routes.ts +98 -0
- package/template/apps/server/src/embedding/run-artifact.ts +18 -0
- package/template/apps/server/src/embedding/run-authorization.test.ts +133 -0
- package/template/apps/server/src/embedding/run-authorization.ts +91 -0
- package/template/apps/server/src/embedding/run-binding-repository.ts +75 -0
- package/template/apps/server/src/embedding/run-fingerprint.test.ts +52 -0
- package/template/apps/server/src/embedding/run-fingerprint.ts +39 -0
- package/template/apps/server/src/embedding/terminal-observer.test.ts +26 -0
- package/template/apps/server/src/embedding/terminal-observer.ts +44 -0
- package/template/apps/server/src/index.ts +38 -31
- package/template/apps/server/src/module-host/ai-operation-port.ts +3 -3
- package/template/apps/server/src/module-host/durable-context.ts +194 -16
- package/template/apps/server/src/module-host/durable-handler-registration.ts +1 -0
- package/template/apps/server/src/module-host/durable-storage-filesystem-restart.test.ts +265 -0
- package/template/apps/server/src/module-host/durable-storage-write.test.ts +345 -0
- package/template/apps/server/src/module-host/http-runtime.ts +25 -0
- package/template/apps/server/src/module-host/initialize-contracts.ts +18 -1
- package/template/apps/server/src/module-host/initialize.test.ts +18 -0
- package/template/apps/server/src/module-host/initialize.ts +42 -2
- package/template/apps/server/src/module-host/module-secret-audit-version.test.ts +73 -0
- package/template/apps/server/src/module-host/module-secret-binding-resolution.ts +60 -0
- package/template/apps/server/src/module-host/module-secret-durable.test.ts +206 -0
- package/template/apps/server/src/module-host/module-secret-port.test-support.ts +125 -0
- package/template/apps/server/src/module-host/module-secret-port.test.ts +161 -0
- package/template/apps/server/src/module-host/module-secret-port.ts +249 -0
- package/template/apps/server/src/module-host/module-secret-result.test.ts +324 -0
- package/template/apps/server/src/module-host/module-secret-result.ts +274 -0
- package/template/apps/server/src/module-host/module-secret-tool-boundary.test.ts +143 -0
- package/template/apps/server/src/module-host/project-composition.ts +1 -0
- package/template/apps/server/src/module-host/report-staging-port.ts +55 -0
- package/template/apps/server/src/module-host/report-staging-registration.test.ts +104 -0
- package/template/apps/server/src/module-host/request-context.ts +58 -1
- package/template/apps/server/src/module-host/route-declaration.ts +11 -4
- package/template/apps/server/src/module-host/route-installer.test-fixture.ts +246 -0
- package/template/apps/server/src/module-host/route-installer.test.ts +47 -211
- package/template/apps/server/src/module-host/route-installer.ts +192 -21
- package/template/apps/server/src/module-host/route-registration.test.ts +44 -4
- package/template/apps/server/src/module-host/runtime-composition.ts +2 -0
- package/template/apps/server/src/module-host/scoped-host.ts +84 -0
- package/template/apps/server/src/module-host/screenshot-artifact-ref.ts +91 -0
- package/template/apps/server/src/module-host/screenshot-intake-composition.test.ts +292 -0
- package/template/apps/server/src/module-host/screenshot-intake-deadline.ts +38 -0
- package/template/apps/server/src/module-host/screenshot-intake-plan.ts +75 -0
- package/template/apps/server/src/module-host/screenshot-intake-port.ts +297 -0
- package/template/apps/server/src/module-host/screenshot-intake-security.test.ts +311 -0
- package/template/apps/server/src/module-host/screenshot-intake-store.ts +76 -0
- package/template/apps/server/src/module-host/screenshot-intake-test-support.ts +68 -0
- package/template/apps/server/src/module-host/secret-bindings.test.ts +167 -0
- package/template/apps/server/src/module-host/secret-bindings.ts +184 -0
- package/template/apps/server/src/module-host/storage-authorization-binding.test.ts +242 -0
- package/template/apps/server/src/module-host/storage-port.test.ts +8 -1
- package/template/apps/server/src/module-host/storage-port.ts +84 -8
- package/template/apps/server/src/module-host/storage-restart-fixture.test-support.ts +242 -0
- package/template/apps/server/src/module-host/storage-restart-postgres.integration.test.ts +280 -0
- package/template/apps/server/src/module-host/storage-scope-drift-http.test.ts +68 -0
- package/template/apps/server/src/module-host/storage-scope.ts +52 -1
- package/template/apps/server/src/module-host/storage-stream-route.test.ts +282 -0
- package/template/apps/server/src/module-host/storage-write-error.test.ts +174 -0
- package/template/apps/server/src/module-host/storage-write-error.ts +62 -0
- package/template/apps/server/src/module-host/storage-write-port.test.ts +323 -0
- package/template/apps/server/src/module-host/storage-write-port.ts +320 -0
- package/template/apps/server/src/module-host/storage-write-unavailable.ts +21 -0
- package/template/apps/server/src/module-host/storage-writer-retention.test.ts +109 -0
- package/template/apps/server/src/module-host/user-directory-composition.test.ts +1 -0
- package/template/apps/server/src/module-preflight-secret.test.ts +79 -0
- package/template/apps/server/src/module-preflight.ts +5 -0
- package/template/apps/server/src/platform-http-runtime.ts +16 -4
- package/template/apps/server/src/report-staging/archive-frame-stream.test.ts +209 -0
- package/template/apps/server/src/report-staging/archive-frame-stream.ts +341 -0
- package/template/apps/server/src/report-staging/archive-process.test.ts +302 -0
- package/template/apps/server/src/report-staging/archive-process.ts +257 -0
- package/template/apps/server/src/report-staging/archive-volumes.ts +30 -0
- package/template/apps/server/src/report-staging/cancellation.ts +13 -0
- package/template/apps/server/src/report-staging/contracts.ts +94 -0
- package/template/apps/server/src/report-staging/drizzle-lifecycle.ts +278 -0
- package/template/apps/server/src/report-staging/drizzle-mapping.ts +140 -0
- package/template/apps/server/src/report-staging/drizzle-repository.integration.test.ts +346 -0
- package/template/apps/server/src/report-staging/drizzle-repository.ts +255 -0
- package/template/apps/server/src/report-staging/drizzle-seal.integration.test.ts +267 -0
- package/template/apps/server/src/report-staging/drizzle-seal.ts +177 -0
- package/template/apps/server/src/report-staging/filesystem-cleanup.test.ts +68 -0
- package/template/apps/server/src/report-staging/filesystem-cleanup.ts +102 -0
- package/template/apps/server/src/report-staging/filesystem-errors.ts +15 -0
- package/template/apps/server/src/report-staging/filesystem-identifiers.ts +19 -0
- package/template/apps/server/src/report-staging/filesystem-io.test.ts +85 -0
- package/template/apps/server/src/report-staging/filesystem-io.ts +206 -0
- package/template/apps/server/src/report-staging/filesystem-scan.ts +85 -0
- package/template/apps/server/src/report-staging/filesystem-store.ts +346 -0
- package/template/apps/server/src/report-staging/heartbeat.test.ts +47 -0
- package/template/apps/server/src/report-staging/heartbeat.ts +53 -0
- package/template/apps/server/src/report-staging/manifest-stream.ts +46 -0
- package/template/apps/server/src/report-staging/memory-repository.ts +256 -0
- package/template/apps/server/src/report-staging/metadata-catalog.ts +89 -0
- package/template/apps/server/src/report-staging/metadata-spool-paths.ts +195 -0
- package/template/apps/server/src/report-staging/metadata-spool-schema.ts +54 -0
- package/template/apps/server/src/report-staging/metadata-spool.test.ts +214 -0
- package/template/apps/server/src/report-staging/metadata-spool.ts +305 -0
- package/template/apps/server/src/report-staging/native/archive-frame-helper.c +309 -0
- package/template/apps/server/src/report-staging/path-policy.test.ts +127 -0
- package/template/apps/server/src/report-staging/path-policy.ts +263 -0
- package/template/apps/server/src/report-staging/repository-fence.test.ts +114 -0
- package/template/apps/server/src/report-staging/repository.ts +75 -0
- package/template/apps/server/src/report-staging/runtime.ts +31 -0
- package/template/apps/server/src/report-staging/sealed-file.test.ts +34 -0
- package/template/apps/server/src/report-staging/sealed-file.ts +137 -0
- package/template/apps/server/src/report-staging/service-input-limits.test.ts +62 -0
- package/template/apps/server/src/report-staging/service-input.ts +204 -0
- package/template/apps/server/src/report-staging/service-lifecycle.test.ts +132 -0
- package/template/apps/server/src/report-staging/service-read-fence.test.ts +37 -0
- package/template/apps/server/src/report-staging/service-read.ts +172 -0
- package/template/apps/server/src/report-staging/service-support.ts +149 -0
- package/template/apps/server/src/report-staging/service.test-fixture.ts +226 -0
- package/template/apps/server/src/report-staging/service.test.ts +314 -0
- package/template/apps/server/src/report-staging/service.ts +255 -0
- package/template/apps/server/src/report-staging/supervised-process.ts +194 -0
- package/template/apps/server/src/speech/contracts.ts +8 -0
- package/template/apps/server/src/speech/errors.ts +10 -0
- package/template/apps/server/src/speech/facade-contract.ts +49 -0
- package/template/apps/server/src/speech/facade-output.test.ts +299 -0
- package/template/apps/server/src/speech/facade-output.ts +298 -0
- package/template/apps/server/src/speech/facade-validation.ts +127 -0
- package/template/apps/server/src/speech/facade.ts +185 -151
- package/template/apps/server/src/speech/fingerprint.test.ts +42 -0
- package/template/apps/server/src/speech/fingerprint.ts +28 -0
- package/template/apps/server/src/speech/output-artifact-binding.test.ts +11 -0
- package/template/apps/server/src/speech/output-artifact-binding.ts +30 -0
- package/template/apps/server/src/speech/output-artifact-error.ts +9 -0
- package/template/apps/server/src/speech/output-artifact-host.test-support.ts +73 -0
- package/template/apps/server/src/speech/output-artifact-host.test.ts +302 -0
- package/template/apps/server/src/speech/output-artifact-host.ts +279 -0
- package/template/apps/server/src/speech/output-artifact-policy.ts +114 -0
- package/template/apps/server/src/speech/output-artifact-replay.ts +91 -0
- package/template/apps/server/src/speech/remote-response.ts +158 -0
- package/template/apps/server/src/speech/remote-runtime.test.ts +90 -0
- package/template/apps/server/src/speech/remote-runtime.ts +36 -78
- package/template/apps/server/src/speech/routes.ts +60 -16
- package/template/apps/server/src/startup-finalization.ts +52 -0
- package/template/apps/server/src/startup-preflight.ts +2 -0
- package/template/apps/server/src/startup-shutdown.test.ts +69 -0
- package/template/apps/server/src/startup-shutdown.ts +61 -0
- package/template/apps/server/src/storage/drizzle-upload-purge.ts +61 -0
- package/template/apps/server/src/storage/drizzle-upload-references.ts +23 -0
- package/template/apps/server/src/storage/drizzle-upload-repository.integration.test.ts +103 -0
- package/template/apps/server/src/storage/drizzle-upload-repository.ts +109 -14
- package/template/apps/server/src/storage/host-runtime.ts +15 -0
- package/template/apps/server/src/storage/routes-stream-cancellation.test.ts +154 -0
- package/template/apps/server/src/storage/routes.test.ts +13 -2
- package/template/apps/server/src/storage/routes.ts +57 -18
- package/template/apps/server/src/storage/runtime.ts +17 -4
- package/template/apps/server/src/system/route-types.ts +5 -1
- package/template/apps/server/src/system/system-resource-monitoring.test.ts +47 -0
- package/template/apps/server/src/system/system-resource-monitoring.ts +60 -10
- package/template/apps/server/src/work-order/routes.test.ts +1 -0
- package/template/apps/speech-server/src/southwind_speech_server/adapter.py +58 -17
- package/template/apps/speech-server/src/southwind_speech_server/app.py +24 -17
- package/template/apps/speech-server/src/southwind_speech_server/bounded_json.py +60 -0
- package/template/apps/speech-server/src/southwind_speech_server/config.py +122 -2
- package/template/apps/speech-server/src/southwind_speech_server/contracts.py +58 -0
- package/template/apps/speech-server/src/southwind_speech_server/errors.py +8 -0
- package/template/apps/speech-server/src/southwind_speech_server/normalizer.py +14 -0
- package/template/apps/speech-server/src/southwind_speech_server/output_artifact.py +190 -0
- package/template/apps/speech-server/src/southwind_speech_server/output_validation.py +54 -0
- package/template/apps/speech-server/src/southwind_speech_server/pin_cli.py +83 -0
- package/template/apps/speech-server/src/southwind_speech_server/readiness.py +266 -0
- package/template/apps/speech-server/src/southwind_speech_server/readiness_contracts.py +268 -0
- package/template/apps/speech-server/src/southwind_speech_server/readiness_http.py +91 -0
- package/template/apps/speech-server/src/southwind_speech_server/readiness_local.py +161 -0
- package/template/apps/speech-server/src/southwind_speech_server/readiness_support.py +106 -0
- package/template/apps/speech-server/src/southwind_speech_server/service.py +118 -13
- package/template/apps/speech-server/src/southwind_speech_server/store.py +7 -0
- package/template/apps/speech-server/tests/test_bounded_json.py +55 -0
- package/template/apps/speech-server/tests/test_config.py +22 -0
- package/template/apps/speech-server/tests/test_output_artifact.py +60 -0
- package/template/apps/speech-server/tests/test_output_validation.py +44 -0
- package/template/apps/speech-server/tests/test_readiness.py +315 -0
- package/template/apps/speech-server/tests/test_readiness_http.py +48 -0
- package/template/apps/speech-server/tests/test_readiness_local.py +43 -0
- package/template/apps/speech-server/tests/test_service.py +211 -36
- package/template/apps/web/src/pages/system/components/OperationGpuMonitor.vue +23 -3
- package/template/apps/web/src/pages/system/components/OperationGpuMonitor.webtest.ts +29 -0
- package/template/apps/web/src/pages/system/components/OperationServiceMonitor.vue +2 -1
- package/template/apps/web/src/pages/system/components/OperationServiceMonitor.webtest.ts +4 -1
- package/template/docker-compose.yml +38 -1
- package/template/docs/architecture/ai-runtime-readiness.md +498 -0
- package/template/docs/architecture/ai-runtime.md +20 -4
- package/template/docs/architecture/durable-jobs.md +54 -5
- package/template/docs/architecture/module-host.md +72 -9
- package/template/docs/architecture/module-manifest-composition.md +5 -2
- package/template/docs/architecture/module-secret-resolution.md +250 -0
- package/template/docs/architecture/object-storage.md +144 -3
- package/template/docs/architecture/report-staging.md +158 -0
- package/template/docs/architecture/server-module-interface.md +29 -0
- package/template/docs/architecture/speech-variants.md +45 -0
- package/template/docs/platform/agent-tools.md +16 -0
- package/template/docs/platform/document-ai-runtime.md +199 -17
- package/template/docs/platform/module-configuration.md +5 -0
- package/template/docs/platform/speech-ai-runtime.md +34 -5
- package/template/docs/platform/vision-ai-runtime.md +24 -0
- package/template/package.json +4 -1
- package/template/packages/ai-client/package.json +1 -1
- package/template/packages/ai-client/src/agent/client/client.ts +3 -0
- package/template/packages/ai-client/src/agent/client/index.ts +1 -0
- package/template/packages/ai-client/src/agent/client/screenshot.test.ts +40 -0
- package/template/packages/ai-client/src/agent/client/screenshot.ts +146 -0
- package/template/packages/ai-client/src/agent/client/types.ts +2 -0
- package/template/packages/ai-client/src/agent/contracts/runs.ts +1 -0
- package/template/packages/ai-client/src/embedding/client.test.ts +52 -0
- package/template/packages/ai-client/src/embedding/client.ts +69 -0
- package/template/packages/ai-client/src/embedding/contracts.ts +47 -0
- package/template/packages/ai-client/src/embedding/index.ts +1 -0
- package/template/packages/ai-client/src/embedding/run.ts +130 -0
- package/template/packages/ai-client/src/speech/client.test.ts +26 -0
- package/template/packages/ai-client/src/speech/client.ts +25 -1
- package/template/packages/ai-client/src/speech/contracts.ts +19 -0
- package/template/packages/config/package.json +1 -1
- package/template/packages/database/drizzle/0048_illegal_magneto.sql +11 -0
- package/template/packages/database/drizzle/0049_right_lenny_balinger.sql +79 -0
- package/template/packages/database/drizzle/0050_greedy_sister_grimm.sql +92 -0
- package/template/packages/database/drizzle/0051_lame_shockwave.sql +19 -0
- package/template/packages/database/drizzle/0052_tiresome_komodo.sql +1 -0
- package/template/packages/database/drizzle/0053_calm_victor_mancha.sql +1 -0
- package/template/packages/database/drizzle/0054_tough_thanos.sql +29 -0
- package/template/packages/database/drizzle/meta/0048_snapshot.json +8852 -0
- package/template/packages/database/drizzle/meta/0049_snapshot.json +9410 -0
- package/template/packages/database/drizzle/meta/0050_snapshot.json +10115 -0
- package/template/packages/database/drizzle/meta/0051_snapshot.json +10257 -0
- package/template/packages/database/drizzle/meta/0052_snapshot.json +10263 -0
- package/template/packages/database/drizzle/meta/0053_snapshot.json +10270 -0
- package/template/packages/database/drizzle/meta/0054_snapshot.json +10468 -0
- package/template/packages/database/drizzle/meta/_journal.json +49 -0
- package/template/packages/database/package.json +1 -1
- package/template/packages/database/src/agent-runtime-schema.test.ts +15 -0
- package/template/packages/database/src/ai-output-artifacts.test.ts +57 -0
- package/template/packages/database/src/schema/agent-runtime.ts +43 -0
- package/template/packages/database/src/schema/ai-output-artifacts.ts +182 -0
- package/template/packages/database/src/schema/embedding-runtime.ts +62 -0
- package/template/packages/database/src/schema/file-storage.ts +18 -0
- package/template/packages/database/src/schema/index.ts +3 -0
- package/template/packages/database/src/schema/report-staging.ts +212 -0
- package/template/packages/database/src/schema.test.ts +19 -0
- package/template/packages/jobs/package.json +1 -1
- package/template/packages/modules/index.ts +1 -0
- package/template/packages/modules/package.json +1 -1
- package/template/packages/modules/src/ai-operation-composition.test.ts +37 -0
- package/template/packages/modules/src/ai-operation-composition.ts +2 -0
- package/template/packages/modules/src/ai-operation-readiness-contract.test.ts +38 -0
- package/template/packages/modules/src/ai-operation-readiness-contract.ts +34 -0
- package/template/packages/modules/src/capability-audit-validation.ts +20 -0
- package/template/packages/modules/src/capability-guard-validation.ts +41 -0
- package/template/packages/modules/src/composition.ts +11 -0
- package/template/packages/modules/src/manifest.ts +40 -0
- package/template/packages/modules/src/secret-composition.test.ts +308 -0
- package/template/packages/modules/src/secret-composition.ts +176 -0
- package/template/packages/modules/src/system-api-control-plane.ts +17 -1
- package/template/packages/modules/src/system-module-catalog.test.ts +52 -0
- package/template/packages/modules/src/system-module-catalog.ts +1 -1
- package/template/packages/server-sdk/contracts/ai-runtime-readiness/v1/document-python-parity.json +12 -0
- package/template/packages/server-sdk/contracts/ai-runtime-readiness/v1/document.json +70 -0
- package/template/packages/server-sdk/contracts/ai-runtime-readiness/v1/embedding.json +68 -0
- package/template/packages/server-sdk/contracts/ai-runtime-readiness/v1/speech.json +80 -0
- package/template/packages/server-sdk/contracts/ai-runtime-readiness/v1/vlm.json +70 -0
- package/template/packages/server-sdk/contracts/document-runtime/v1/fingerprint-fixture.json +101 -0
- package/template/packages/server-sdk/index.ts +109 -0
- package/template/packages/server-sdk/package.json +22 -3
- package/template/packages/server-sdk/src/ai-runtime-readiness-capture.ts +168 -0
- package/template/packages/server-sdk/src/ai-runtime-readiness-digest.ts +49 -0
- package/template/packages/server-sdk/src/ai-runtime-readiness-identity.ts +16 -0
- package/template/packages/server-sdk/src/ai-runtime-readiness-keys.ts +23 -0
- package/template/packages/server-sdk/src/ai-runtime-readiness-limits.ts +141 -0
- package/template/packages/server-sdk/src/ai-runtime-readiness-projection.ts +326 -0
- package/template/packages/server-sdk/src/ai-runtime-readiness-requirement.ts +31 -0
- package/template/packages/server-sdk/src/ai-runtime-readiness-time.ts +16 -0
- package/template/packages/server-sdk/src/ai-runtime-readiness-trust.ts +84 -0
- package/template/packages/server-sdk/src/ai-runtime-readiness-validation-values.ts +147 -0
- package/template/packages/server-sdk/src/ai-runtime-readiness-validation.ts +299 -0
- package/template/packages/server-sdk/src/ai-runtime-readiness-values.ts +42 -0
- package/template/packages/server-sdk/src/ai-runtime-readiness.adversarial-input.contract.test.ts +146 -0
- package/template/packages/server-sdk/src/ai-runtime-readiness.contract-support.ts +139 -0
- package/template/packages/server-sdk/src/ai-runtime-readiness.contract.test.ts +314 -0
- package/template/packages/server-sdk/src/ai-runtime-readiness.digest-safety.contract.test.ts +131 -0
- package/template/packages/server-sdk/src/ai-runtime-readiness.fail-closed.contract.test.ts +215 -0
- package/template/packages/server-sdk/src/ai-runtime-readiness.identity.contract.test.ts +138 -0
- package/template/packages/server-sdk/src/ai-runtime-readiness.input-safety.contract.test.ts +314 -0
- package/template/packages/server-sdk/src/ai-runtime-readiness.public-api.test.ts +18 -0
- package/template/packages/server-sdk/src/ai-runtime-readiness.python-parity.contract.test.ts +160 -0
- package/template/packages/server-sdk/src/ai-runtime-readiness.trust.contract.test.ts +135 -0
- package/template/packages/server-sdk/src/ai-runtime-readiness.ts +198 -0
- package/template/packages/server-sdk/src/ai-screenshot-intake-port.ts +58 -0
- package/template/packages/server-sdk/src/data-governance-registration.ts +1 -3
- package/template/packages/server-sdk/src/durable-handler.ts +12 -0
- package/template/packages/server-sdk/src/module-adapter.test.ts +10 -0
- package/template/packages/server-sdk/src/module-adapter.ts +3 -0
- package/template/packages/server-sdk/src/module-host.ts +8 -0
- package/template/packages/server-sdk/src/report-staging-context-compatibility.test.ts +25 -0
- package/template/packages/server-sdk/src/report-staging-port.ts +190 -0
- package/template/packages/server-sdk/src/request-context.ts +27 -1
- package/template/packages/server-sdk/src/route-definition.ts +6 -0
- package/template/packages/server-sdk/src/secret-binding.test.ts +66 -0
- package/template/packages/server-sdk/src/secret-binding.ts +54 -0
- package/template/packages/server-sdk/src/secret-context-compatibility.test.ts +77 -0
- package/template/packages/server-sdk/src/secret-port.ts +80 -0
- package/template/packages/server-sdk/src/storage-port.ts +129 -9
- package/template/packages/server-sdk/src/storage-v052-source-compatibility.test.ts +61 -0
- package/template/packages/shared/index.ts +2 -0
- package/template/packages/shared/package.json +4 -1
- package/template/packages/shared/src/ai-operation-readiness.test.ts +75 -0
- package/template/packages/shared/src/ai-operation-readiness.ts +170 -0
- package/template/packages/shared/src/license-catalog.ts +14 -9
- package/template/packages/shared/src/stable-key.ts +26 -0
- package/template/packages/shared/tsconfig.json +16 -0
- package/template/packages/storage/index.ts +2 -0
- package/template/packages/storage/package.json +1 -1
- package/template/packages/storage/src/in-memory-upload-repository.ts +105 -2
- package/template/packages/storage/src/local-file-blob-store.test.ts +58 -0
- package/template/packages/storage/src/local-file-blob-store.ts +5 -71
- package/template/packages/storage/src/local-file-blob-writer.ts +96 -0
- package/template/packages/storage/src/upload-abort-recovery.test.ts +234 -0
- package/template/packages/storage/src/upload-abort.ts +130 -0
- package/template/packages/storage/src/upload-cleanup-race.test.ts +207 -0
- package/template/packages/storage/src/upload-cleanup.ts +85 -0
- package/template/packages/storage/src/upload-completion.ts +52 -0
- package/template/packages/storage/src/upload-purge.test.ts +163 -0
- package/template/packages/storage/src/upload-purge.ts +261 -0
- package/template/packages/storage/src/upload-repository-v052-compatibility.test.ts +31 -0
- package/template/packages/storage/src/upload-repository.ts +61 -0
- package/template/packages/storage/src/upload-service-recovery.test.ts +296 -0
- package/template/packages/storage/src/upload-service.ts +138 -150
- package/template/packages/storage/src/upload-streams.ts +126 -30
- package/template/packages/storage/src/upload-types.ts +13 -0
- package/template/packages/storage/src/upload-validation.ts +127 -0
- package/template/scripts/provision-speech-readiness.ts +147 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { describe, expect, test } from "bun:test";
|
|
3
|
+
import {
|
|
4
|
+
AI_RUNTIME_MAX_CAPABILITIES_PER_OFFER_V1,
|
|
5
|
+
AI_RUNTIME_MAX_OFFERS_V1,
|
|
6
|
+
AI_RUNTIME_MODALITIES_V1,
|
|
7
|
+
} from "./ai-runtime-readiness.js";
|
|
8
|
+
import {
|
|
9
|
+
cloneRecord,
|
|
10
|
+
firstOffer,
|
|
11
|
+
readinessContractFixtures,
|
|
12
|
+
type ReadinessContractFixture,
|
|
13
|
+
} from "./ai-runtime-readiness.contract-support.js";
|
|
14
|
+
import { parseAiRuntimeReadinessV1 } from "./ai-runtime-readiness-validation.js";
|
|
15
|
+
|
|
16
|
+
interface PythonParityFixture {
|
|
17
|
+
readonly maxOffers: number;
|
|
18
|
+
readonly maxCapabilitiesPerOffer: number;
|
|
19
|
+
readonly maxModalities: number;
|
|
20
|
+
readonly maxSafeInteger: number;
|
|
21
|
+
readonly firstUnsafeInteger: number;
|
|
22
|
+
readonly integerNumbers: {
|
|
23
|
+
readonly acceptedJson: readonly number[];
|
|
24
|
+
readonly rejectedJson: readonly (number | boolean)[];
|
|
25
|
+
readonly rejectedNonFinite: readonly string[];
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const boundary = await loadBoundary();
|
|
30
|
+
const documentFixture = requiredDocumentFixture();
|
|
31
|
+
|
|
32
|
+
describe("Document Python 与公共 readiness V1 边界", () => {
|
|
33
|
+
test("同一 fixture 固定 cardinality 与 safe integer", () => {
|
|
34
|
+
expect(boundary).toEqual({
|
|
35
|
+
maxOffers: AI_RUNTIME_MAX_OFFERS_V1,
|
|
36
|
+
maxCapabilitiesPerOffer: AI_RUNTIME_MAX_CAPABILITIES_PER_OFFER_V1,
|
|
37
|
+
maxModalities: AI_RUNTIME_MODALITIES_V1.length,
|
|
38
|
+
maxSafeInteger: Number.MAX_SAFE_INTEGER,
|
|
39
|
+
firstUnsafeInteger: Number.MAX_SAFE_INTEGER + 1,
|
|
40
|
+
integerNumbers: {
|
|
41
|
+
acceptedJson: [1, 1, Number.MAX_SAFE_INTEGER],
|
|
42
|
+
rejectedJson: [true, false, 1.5],
|
|
43
|
+
rejectedNonFinite: ["NaN", "Infinity", "-Infinity"],
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test("公共 parser 统一接受整数数值并拒绝 bool、非整数和非有限数", () => {
|
|
49
|
+
for (const value of boundary.integerNumbers.acceptedJson) {
|
|
50
|
+
expect(
|
|
51
|
+
parseAiRuntimeReadinessV1(
|
|
52
|
+
snapshotWithLimits(value),
|
|
53
|
+
documentFixture.now,
|
|
54
|
+
).ok,
|
|
55
|
+
).toBe(true);
|
|
56
|
+
}
|
|
57
|
+
for (const value of boundary.integerNumbers.rejectedJson) {
|
|
58
|
+
expect(
|
|
59
|
+
parseAiRuntimeReadinessV1(
|
|
60
|
+
snapshotWithLimits(value),
|
|
61
|
+
documentFixture.now,
|
|
62
|
+
).ok,
|
|
63
|
+
).toBe(false);
|
|
64
|
+
}
|
|
65
|
+
for (const token of boundary.integerNumbers.rejectedNonFinite) {
|
|
66
|
+
expect(
|
|
67
|
+
parseAiRuntimeReadinessV1(
|
|
68
|
+
snapshotWithLimits(Number(token)),
|
|
69
|
+
documentFixture.now,
|
|
70
|
+
).ok,
|
|
71
|
+
).toBe(false);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test("公共 parser 接受边界值并拒绝第一个不安全整数", () => {
|
|
76
|
+
const safe = snapshotWithLimits(boundary.maxSafeInteger);
|
|
77
|
+
expect(parseAiRuntimeReadinessV1(safe, documentFixture.now).ok).toBe(true);
|
|
78
|
+
|
|
79
|
+
const unsafe = snapshotWithLimits(boundary.firstUnsafeInteger);
|
|
80
|
+
expect(parseAiRuntimeReadinessV1(unsafe, documentFixture.now).ok).toBe(
|
|
81
|
+
false,
|
|
82
|
+
);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
test("公共 parser 在 fixture MAX 接受并在 MAX+1 失败关闭", () => {
|
|
86
|
+
const atLimit = snapshotAtCardinalityLimit();
|
|
87
|
+
expect(parseAiRuntimeReadinessV1(atLimit, documentFixture.now).ok).toBe(
|
|
88
|
+
true,
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
const offersOverflow = cloneRecord(atLimit);
|
|
92
|
+
offersOverflow.offers = Array.from(
|
|
93
|
+
{ length: boundary.maxOffers + 1 },
|
|
94
|
+
(_, index) => ({
|
|
95
|
+
...firstOffer(documentFixture),
|
|
96
|
+
variant: `document.overflow-${index}`,
|
|
97
|
+
}),
|
|
98
|
+
);
|
|
99
|
+
expect(
|
|
100
|
+
parseAiRuntimeReadinessV1(offersOverflow, documentFixture.now).ok,
|
|
101
|
+
).toBe(false);
|
|
102
|
+
|
|
103
|
+
const capabilitiesOverflow = cloneRecord(atLimit);
|
|
104
|
+
const offer = firstOffer(capabilitiesOverflow);
|
|
105
|
+
offer.capabilities = Array.from(
|
|
106
|
+
{ length: boundary.maxCapabilitiesPerOffer + 1 },
|
|
107
|
+
(_, index) => `document.capability-${index}`,
|
|
108
|
+
);
|
|
109
|
+
capabilitiesOverflow.offers = [offer];
|
|
110
|
+
expect(
|
|
111
|
+
parseAiRuntimeReadinessV1(capabilitiesOverflow, documentFixture.now).ok,
|
|
112
|
+
).toBe(false);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
function snapshotAtCardinalityLimit() {
|
|
117
|
+
const snapshot = cloneRecord(documentFixture.snapshot);
|
|
118
|
+
const base = firstOffer(documentFixture);
|
|
119
|
+
base.capabilities = Array.from(
|
|
120
|
+
{ length: boundary.maxCapabilitiesPerOffer },
|
|
121
|
+
(_, index) => `document.capability-${index}`,
|
|
122
|
+
);
|
|
123
|
+
const modalities = AI_RUNTIME_MODALITIES_V1.slice(0, boundary.maxModalities);
|
|
124
|
+
base.inputModalities = modalities;
|
|
125
|
+
base.outputModalities = [...modalities];
|
|
126
|
+
snapshot.offers = Array.from({ length: boundary.maxOffers }, (_, index) => ({
|
|
127
|
+
...structuredClone(base),
|
|
128
|
+
variant: `document.variant-${index}`,
|
|
129
|
+
}));
|
|
130
|
+
return snapshot;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function snapshotWithLimits(maxInputBytes: unknown) {
|
|
134
|
+
const snapshot = cloneRecord(documentFixture.snapshot);
|
|
135
|
+
const offer = firstOffer(documentFixture);
|
|
136
|
+
const limits = cloneRecord(offer.limits);
|
|
137
|
+
limits.maxInputBytes = maxInputBytes;
|
|
138
|
+
offer.limits = limits;
|
|
139
|
+
snapshot.offers = [offer];
|
|
140
|
+
return snapshot;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
async function loadBoundary(): Promise<PythonParityFixture> {
|
|
144
|
+
const body = await readFile(
|
|
145
|
+
new URL(
|
|
146
|
+
"../contracts/ai-runtime-readiness/v1/document-python-parity.json",
|
|
147
|
+
import.meta.url,
|
|
148
|
+
),
|
|
149
|
+
"utf8",
|
|
150
|
+
);
|
|
151
|
+
return JSON.parse(body) as PythonParityFixture;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function requiredDocumentFixture(): ReadinessContractFixture {
|
|
155
|
+
const fixture = readinessContractFixtures.find(
|
|
156
|
+
({ operation }) => operation.runtimeKind === "document",
|
|
157
|
+
);
|
|
158
|
+
if (!fixture) throw new Error("document readiness fixture 缺失");
|
|
159
|
+
return fixture;
|
|
160
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import type { AiRuntimeOfferV1 } from "./ai-runtime-readiness.js";
|
|
3
|
+
import {
|
|
4
|
+
cloneRecord,
|
|
5
|
+
firstOffer,
|
|
6
|
+
firstProbe,
|
|
7
|
+
readinessContractFixtures as fixtures,
|
|
8
|
+
type ReadinessContractFixture,
|
|
9
|
+
} from "./ai-runtime-readiness.contract-support.js";
|
|
10
|
+
import { computeAiRuntimeOffersDigestV1 } from "./ai-runtime-readiness-digest.js";
|
|
11
|
+
import { projectAiOperationReadinessV1 } from "./ai-runtime-readiness-projection.js";
|
|
12
|
+
import { parseAiRuntimeReadinessV1 } from "./ai-runtime-readiness-validation.js";
|
|
13
|
+
|
|
14
|
+
for (const fixture of fixtures) {
|
|
15
|
+
describe(`${fixture.name} readiness Host trust`, () => {
|
|
16
|
+
test("Runtime payload 自报 pinned 字段不能证明 digest 漂移", () => {
|
|
17
|
+
const snapshot = changedSnapshot(fixture, "runtime.degraded-safe");
|
|
18
|
+
const deployment = cloneRecord(snapshot.deployment);
|
|
19
|
+
const probe = cloneRecord(snapshot.downstreamProbe);
|
|
20
|
+
deployment.pinnedReleaseDigest =
|
|
21
|
+
fixture.operation.expectedDeployment.releaseDigest;
|
|
22
|
+
deployment.pinnedOffersDigest =
|
|
23
|
+
fixture.operation.expectedDeployment.offersDigest;
|
|
24
|
+
probe.pinnedReleaseDigest =
|
|
25
|
+
fixture.operation.expectedDeployment.releaseDigest;
|
|
26
|
+
probe.pinnedOffersDigest =
|
|
27
|
+
fixture.operation.expectedDeployment.offersDigest;
|
|
28
|
+
snapshot.deployment = deployment;
|
|
29
|
+
snapshot.downstreamProbe = probe;
|
|
30
|
+
|
|
31
|
+
const result = projectAiOperationReadinessV1(
|
|
32
|
+
fixture.operation,
|
|
33
|
+
snapshot,
|
|
34
|
+
{ now: fixture.now },
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
expect(result.status).toBe("unavailable");
|
|
38
|
+
expect(
|
|
39
|
+
result.unavailableReasons.some(({ code }) =>
|
|
40
|
+
["RELEASE_DIGEST_MISMATCH", "OFFERS_DIGEST_MISMATCH"].includes(code),
|
|
41
|
+
),
|
|
42
|
+
).toBe(true);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test("Host 独立保存的完整 offers 只允许当前事实降级", () => {
|
|
46
|
+
const currentOffer = firstOffer(fixture);
|
|
47
|
+
const fullOffer: AiRuntimeOfferV1 = {
|
|
48
|
+
...(currentOffer as unknown as AiRuntimeOfferV1),
|
|
49
|
+
capabilities: [
|
|
50
|
+
...(currentOffer.capabilities as string[]),
|
|
51
|
+
"runtime.optional-full-capability",
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
const fullOffers = [fullOffer] as const;
|
|
55
|
+
const expectedDeployment = {
|
|
56
|
+
...fixture.operation.expectedDeployment,
|
|
57
|
+
offersDigest: computeAiRuntimeOffersDigestV1(fullOffers),
|
|
58
|
+
};
|
|
59
|
+
const result = projectAiOperationReadinessV1(
|
|
60
|
+
{ ...fixture.operation, expectedDeployment },
|
|
61
|
+
fixture.snapshot,
|
|
62
|
+
{
|
|
63
|
+
now: fixture.now,
|
|
64
|
+
trustedFullAttestation: {
|
|
65
|
+
deployment: expectedDeployment,
|
|
66
|
+
offers: fullOffers,
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
expect(result.status).toBe("ready");
|
|
72
|
+
if (result.status === "ready") {
|
|
73
|
+
expect(result.deployment).toEqual(expectedDeployment);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test("Host 历史不能授权当前 offers 能力扩张", () => {
|
|
78
|
+
const snapshot = changedSnapshot(
|
|
79
|
+
fixture,
|
|
80
|
+
"runtime.untrusted-expansion",
|
|
81
|
+
false,
|
|
82
|
+
);
|
|
83
|
+
const result = projectAiOperationReadinessV1(
|
|
84
|
+
fixture.operation,
|
|
85
|
+
snapshot,
|
|
86
|
+
{
|
|
87
|
+
now: fixture.now,
|
|
88
|
+
trustedFullAttestation: parsedFullAttestation(fixture),
|
|
89
|
+
},
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
expect(result.status).toBe("unavailable");
|
|
93
|
+
expect(result.unavailableReasons.map(({ code }) => code)).toContain(
|
|
94
|
+
"OFFERS_DIGEST_MISMATCH",
|
|
95
|
+
);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function changedSnapshot(
|
|
101
|
+
fixture: ReadinessContractFixture,
|
|
102
|
+
capability: string,
|
|
103
|
+
changeRelease = true,
|
|
104
|
+
) {
|
|
105
|
+
const snapshot = cloneRecord(fixture.snapshot);
|
|
106
|
+
const offer = firstOffer(fixture);
|
|
107
|
+
offer.capabilities = [...(offer.capabilities as string[]), capability];
|
|
108
|
+
const currentDigest = computeAiRuntimeOffersDigestV1([
|
|
109
|
+
offer as unknown as AiRuntimeOfferV1,
|
|
110
|
+
]);
|
|
111
|
+
const deployment = cloneRecord(snapshot.deployment);
|
|
112
|
+
const probe = firstProbe(fixture);
|
|
113
|
+
deployment.offersDigest = currentDigest;
|
|
114
|
+
probe.offersDigest = currentDigest;
|
|
115
|
+
if (changeRelease) {
|
|
116
|
+
const currentRelease = `sha256:${"d".repeat(64)}`;
|
|
117
|
+
deployment.releaseDigest = currentRelease;
|
|
118
|
+
probe.releaseDigest = currentRelease;
|
|
119
|
+
}
|
|
120
|
+
snapshot.deployment = deployment;
|
|
121
|
+
snapshot.downstreamProbe = probe;
|
|
122
|
+
snapshot.offers = [offer];
|
|
123
|
+
return snapshot;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function parsedFullAttestation(fixture: ReadinessContractFixture) {
|
|
127
|
+
const parsed = parseAiRuntimeReadinessV1(fixture.snapshot, fixture.now);
|
|
128
|
+
if (!parsed.ok || parsed.value.status !== "ready") {
|
|
129
|
+
throw new Error("readiness fixture 不是 ready full attestation");
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
deployment: parsed.value.deployment,
|
|
133
|
+
offers: parsed.value.offers,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AI_RUNTIME_READINESS_SCHEMA_VERSION,
|
|
3
|
+
type AiOperationRequiredLimitsV1,
|
|
4
|
+
type AiRuntimeDeploymentV1,
|
|
5
|
+
type AiRuntimeKindV1,
|
|
6
|
+
type AiRuntimeModalityV1,
|
|
7
|
+
type AiRuntimeOffersDigestV1,
|
|
8
|
+
type AiRuntimeReleaseDigestV1,
|
|
9
|
+
} from "@southwind-ai/shared";
|
|
10
|
+
|
|
11
|
+
export {
|
|
12
|
+
AI_OPERATION_MAX_REQUIRED_CAPABILITIES_V1,
|
|
13
|
+
AI_RUNTIME_KINDS_V1,
|
|
14
|
+
AI_RUNTIME_MODALITIES_V1,
|
|
15
|
+
AI_RUNTIME_READINESS_SCHEMA_VERSION,
|
|
16
|
+
} from "@southwind-ai/shared";
|
|
17
|
+
export type {
|
|
18
|
+
AiOperationReadinessRequirementV1,
|
|
19
|
+
AiOperationRequiredLimitsV1,
|
|
20
|
+
AiOperationRequiredResourcesV1,
|
|
21
|
+
AiRuntimeDeploymentV1,
|
|
22
|
+
AiRuntimeKindV1,
|
|
23
|
+
AiRuntimeModalityV1,
|
|
24
|
+
AiRuntimeOffersDigestV1,
|
|
25
|
+
AiRuntimeReleaseDigestV1,
|
|
26
|
+
} from "@southwind-ai/shared";
|
|
27
|
+
|
|
28
|
+
export const AI_RUNTIME_MAX_PROBE_TTL_SECONDS = 300 as const;
|
|
29
|
+
export const AI_RUNTIME_MAX_UNAVAILABLE_REASONS_V1 = 16 as const;
|
|
30
|
+
export const AI_RUNTIME_MAX_OFFERS_V1 = 16 as const;
|
|
31
|
+
export const AI_RUNTIME_MAX_CAPABILITIES_PER_OFFER_V1 = 32 as const;
|
|
32
|
+
|
|
33
|
+
export const AI_RUNTIME_PROBE_FAILURE_CODES_V1 = [
|
|
34
|
+
"AUTHENTICATION_FAILED",
|
|
35
|
+
"CONNECTION_FAILED",
|
|
36
|
+
"INVALID_RESPONSE",
|
|
37
|
+
"LOCAL_DEPENDENCY_UNAVAILABLE",
|
|
38
|
+
"RESOURCE_UNAVAILABLE",
|
|
39
|
+
"TIMEOUT",
|
|
40
|
+
"UNHEALTHY",
|
|
41
|
+
] as const;
|
|
42
|
+
|
|
43
|
+
export type AiRuntimeProbeFailureCodeV1 =
|
|
44
|
+
(typeof AI_RUNTIME_PROBE_FAILURE_CODES_V1)[number];
|
|
45
|
+
|
|
46
|
+
export const AI_READINESS_REASON_CODES_V1 = [
|
|
47
|
+
"RUNTIME_NOT_CONFIGURED",
|
|
48
|
+
"DOWNSTREAM_NOT_PROBED",
|
|
49
|
+
"DOWNSTREAM_PROBE_FAILED",
|
|
50
|
+
"PROBE_STALE",
|
|
51
|
+
"PROBE_NOT_YET_VALID",
|
|
52
|
+
"PROBE_TTL_EXCEEDED",
|
|
53
|
+
"PROBE_ATTESTATION_MISMATCH",
|
|
54
|
+
"RESOURCE_UNAVAILABLE",
|
|
55
|
+
"CONTRACT_UNSUPPORTED",
|
|
56
|
+
"CONTRACT_INVALID",
|
|
57
|
+
"RUNTIME_KIND_MISMATCH",
|
|
58
|
+
"DEPLOYMENT_KEY_MISMATCH",
|
|
59
|
+
"DEPLOYMENT_IDENTITY_MISSING",
|
|
60
|
+
"DEPLOYMENT_IDENTITY_MISMATCH",
|
|
61
|
+
"RELEASE_DIGEST_MISSING",
|
|
62
|
+
"RELEASE_DIGEST_MISMATCH",
|
|
63
|
+
"OFFERS_DIGEST_MISSING",
|
|
64
|
+
"OFFERS_DIGEST_MISMATCH",
|
|
65
|
+
"CAPABILITY_MISSING",
|
|
66
|
+
"VARIANT_UNSUPPORTED",
|
|
67
|
+
"INPUT_MODALITY_UNSUPPORTED",
|
|
68
|
+
"OUTPUT_MODALITY_UNSUPPORTED",
|
|
69
|
+
"LIMIT_INSUFFICIENT",
|
|
70
|
+
"RESOURCE_LIMIT_INSUFFICIENT",
|
|
71
|
+
] as const;
|
|
72
|
+
|
|
73
|
+
export type AiReadinessReasonCodeV1 =
|
|
74
|
+
(typeof AI_READINESS_REASON_CODES_V1)[number];
|
|
75
|
+
|
|
76
|
+
export interface AiReadinessReasonV1 {
|
|
77
|
+
readonly code: AiReadinessReasonCodeV1;
|
|
78
|
+
readonly retryable: boolean;
|
|
79
|
+
/** Host 定义的 bounded safe token;不承载 Runtime 原始消息。 */
|
|
80
|
+
readonly subject?: string;
|
|
81
|
+
/** 仅供 Host 生成的安全比较值;不透传 Runtime detail。 */
|
|
82
|
+
readonly expected?: string | number;
|
|
83
|
+
/** 仅供 Host 生成的安全比较值;不透传 Runtime detail。 */
|
|
84
|
+
readonly actual?: string | number;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export type AiRuntimeDownstreamProbeV1 =
|
|
88
|
+
| {
|
|
89
|
+
readonly status: "not-run";
|
|
90
|
+
readonly reason: "NOT_CONFIGURED" | "NOT_PROBED";
|
|
91
|
+
}
|
|
92
|
+
| {
|
|
93
|
+
readonly status: "failed";
|
|
94
|
+
readonly checkedAt: string;
|
|
95
|
+
readonly latencyMs: number;
|
|
96
|
+
readonly failureCode: AiRuntimeProbeFailureCodeV1;
|
|
97
|
+
readonly retryable: boolean;
|
|
98
|
+
}
|
|
99
|
+
| {
|
|
100
|
+
readonly status: "passed";
|
|
101
|
+
readonly checkedAt: string;
|
|
102
|
+
readonly validUntil: string;
|
|
103
|
+
readonly latencyMs: number;
|
|
104
|
+
/** 通过公共 V1 identity parser 的持久化 opaque token。 */
|
|
105
|
+
readonly deploymentIdentity: string;
|
|
106
|
+
readonly releaseDigest: AiRuntimeReleaseDigestV1;
|
|
107
|
+
readonly offersDigest: AiRuntimeOffersDigestV1;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
export interface AiRuntimeOfferLimitsV1 extends AiOperationRequiredLimitsV1 {
|
|
111
|
+
/** 同一 deployment 可同时执行的最大 Run 数,不表示已经预留资源。 */
|
|
112
|
+
readonly maxConcurrentRuns: number;
|
|
113
|
+
/** Runtime 可接受的排队 Run 数;0 表示不提供排队。 */
|
|
114
|
+
readonly maxQueueDepth: number;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export interface AiRuntimeOfferV1 {
|
|
118
|
+
/** 同一 deployment 内唯一的稳定变体 Key。 */
|
|
119
|
+
readonly variant: string;
|
|
120
|
+
/** 最多 AI_RUNTIME_MAX_CAPABILITIES_PER_OFFER_V1 个不同的稳定能力 Key。 */
|
|
121
|
+
readonly capabilities: readonly string[];
|
|
122
|
+
readonly inputModalities: readonly AiRuntimeModalityV1[];
|
|
123
|
+
readonly outputModalities: readonly AiRuntimeModalityV1[];
|
|
124
|
+
readonly limits: AiRuntimeOfferLimitsV1;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
interface AiRuntimeReadinessBaseV1 {
|
|
128
|
+
readonly schemaVersion: typeof AI_RUNTIME_READINESS_SCHEMA_VERSION;
|
|
129
|
+
readonly runtimeKind: AiRuntimeKindV1;
|
|
130
|
+
readonly observedAt: string;
|
|
131
|
+
readonly configured: boolean;
|
|
132
|
+
readonly downstreamProbe: AiRuntimeDownstreamProbeV1;
|
|
133
|
+
readonly deployment: AiRuntimeDeploymentV1 | null;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export interface AiRuntimeReadyV1 extends AiRuntimeReadinessBaseV1 {
|
|
137
|
+
readonly status: "ready";
|
|
138
|
+
readonly configured: true;
|
|
139
|
+
readonly downstreamProbe: Extract<
|
|
140
|
+
AiRuntimeDownstreamProbeV1,
|
|
141
|
+
{ readonly status: "passed" }
|
|
142
|
+
>;
|
|
143
|
+
readonly deployment: AiRuntimeDeploymentV1;
|
|
144
|
+
/** 最多 AI_RUNTIME_MAX_OFFERS_V1 个不同 variant。 */
|
|
145
|
+
readonly offers: readonly [AiRuntimeOfferV1, ...AiRuntimeOfferV1[]];
|
|
146
|
+
readonly unavailableReasons: readonly [];
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export interface AiRuntimeUnavailableV1 extends AiRuntimeReadinessBaseV1 {
|
|
150
|
+
readonly status: "unavailable";
|
|
151
|
+
readonly offers: readonly [];
|
|
152
|
+
/** 最多 AI_RUNTIME_MAX_UNAVAILABLE_REASONS_V1 个不同的稳定原因 identity。 */
|
|
153
|
+
readonly unavailableReasons: readonly [
|
|
154
|
+
AiReadinessReasonV1,
|
|
155
|
+
...AiReadinessReasonV1[],
|
|
156
|
+
];
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export type AiRuntimeReadinessV1 = AiRuntimeReadyV1 | AiRuntimeUnavailableV1;
|
|
160
|
+
|
|
161
|
+
interface ModuleAiOperationReadinessBaseV1 {
|
|
162
|
+
readonly schemaVersion: typeof AI_RUNTIME_READINESS_SCHEMA_VERSION;
|
|
163
|
+
readonly operationKey: string;
|
|
164
|
+
readonly runtimeKind: AiRuntimeKindV1;
|
|
165
|
+
readonly observedAt: string;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export interface ModuleAiOperationReadyV1 extends ModuleAiOperationReadinessBaseV1 {
|
|
169
|
+
readonly status: "ready";
|
|
170
|
+
readonly validUntil: string;
|
|
171
|
+
readonly deployment: AiRuntimeDeploymentV1;
|
|
172
|
+
readonly offers: readonly [AiRuntimeOfferV1, ...AiRuntimeOfferV1[]];
|
|
173
|
+
readonly unavailableReasons: readonly [];
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export interface ModuleAiOperationUnavailableV1 extends ModuleAiOperationReadinessBaseV1 {
|
|
177
|
+
readonly status: "unavailable";
|
|
178
|
+
readonly deployment: null;
|
|
179
|
+
readonly offers: readonly [];
|
|
180
|
+
readonly unavailableReasons: readonly [
|
|
181
|
+
AiReadinessReasonV1,
|
|
182
|
+
...AiReadinessReasonV1[],
|
|
183
|
+
];
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export type ModuleAiOperationReadinessV1 =
|
|
187
|
+
| ModuleAiOperationReadyV1
|
|
188
|
+
| ModuleAiOperationUnavailableV1;
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Integration 任务由 Host 实现本 Port;当前独立 Interface 不改变既有
|
|
192
|
+
* ModuleAiOperationPort implementer 的必填表面。
|
|
193
|
+
*/
|
|
194
|
+
export interface ModuleAiOperationReadinessPortV1 {
|
|
195
|
+
inspect(input: {
|
|
196
|
+
readonly operationKey: string;
|
|
197
|
+
}): Promise<ModuleAiOperationReadinessV1>;
|
|
198
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { ModuleAiArtifactRef } from "./ai-artifact-port.js";
|
|
2
|
+
|
|
3
|
+
/** Host-issued plan. Module never supplies a Run ID, ArtifactRef or provider URL. */
|
|
4
|
+
export interface ModuleAiScreenshotPlanV1 {
|
|
5
|
+
readonly contractVersion: 1;
|
|
6
|
+
readonly intakeToken: string;
|
|
7
|
+
readonly expiresAt: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface ModuleAiScreenshotIntakePortV1 {
|
|
11
|
+
create(input: {
|
|
12
|
+
readonly operationKey: string;
|
|
13
|
+
readonly pageId: string;
|
|
14
|
+
}): Promise<ModuleAiScreenshotPlanV1>;
|
|
15
|
+
/** Canonical Run is host-owned; this consumes the plan exactly once. */
|
|
16
|
+
bind(input: { readonly intakeToken: string }): Promise<ModuleAiArtifactRef>;
|
|
17
|
+
discard(input: { readonly intakeToken: string }): Promise<void>;
|
|
18
|
+
/** cancel 与 discard 等价:终止尚未 bind 的计划,不接受业务 Run ID。 */
|
|
19
|
+
cancel(input: { readonly intakeToken: string }): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* V2 是浏览器上传的 Host 控制面,不进入 Module RequestContext。
|
|
24
|
+
* 调用者只能声明页面及像素元数据;Actor、scope、Operation、Run 和物理
|
|
25
|
+
* Artifact locator 全由 Host 重建或签发。
|
|
26
|
+
*/
|
|
27
|
+
export interface ModuleAiScreenshotIntakeCreateV2 {
|
|
28
|
+
readonly pageId: string;
|
|
29
|
+
readonly contextDigest: string;
|
|
30
|
+
readonly mediaType: "image/png";
|
|
31
|
+
readonly byteSize: number;
|
|
32
|
+
readonly pixels: number;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface ModuleAiScreenshotPlanV2 {
|
|
36
|
+
readonly contractVersion: 2;
|
|
37
|
+
readonly intakeToken: string;
|
|
38
|
+
readonly expiresAt: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Project-owned producer seam. It is never exposed to a business Module. */
|
|
42
|
+
export interface ModuleAiScreenshotIntakeProducerV2 {
|
|
43
|
+
create(input: ModuleAiScreenshotIntakeCreateV2): Promise<
|
|
44
|
+
ModuleAiScreenshotPlanV2 & {
|
|
45
|
+
readonly operationKey: string;
|
|
46
|
+
}
|
|
47
|
+
>;
|
|
48
|
+
upload(input: {
|
|
49
|
+
readonly intakeToken: string;
|
|
50
|
+
readonly bytes: Uint8Array;
|
|
51
|
+
readonly mediaType: string;
|
|
52
|
+
}): Promise<ModuleAiArtifactRef>;
|
|
53
|
+
bind(input: {
|
|
54
|
+
readonly intakeToken: string;
|
|
55
|
+
readonly runId: string;
|
|
56
|
+
}): Promise<void>;
|
|
57
|
+
cancel(input: { readonly intakeToken: string }): Promise<void>;
|
|
58
|
+
}
|
|
@@ -66,9 +66,7 @@ export interface ModuleGovernedExportRendererRegistration {
|
|
|
66
66
|
readonly signal: AbortSignal;
|
|
67
67
|
readonly heartbeat: () => Promise<void>;
|
|
68
68
|
},
|
|
69
|
-
):
|
|
70
|
-
| Promise<GovernedExportRenderedArtifact>
|
|
71
|
-
| GovernedExportRenderedArtifact;
|
|
69
|
+
): Promise<GovernedExportRenderedArtifact> | GovernedExportRenderedArtifact;
|
|
72
70
|
}
|
|
73
71
|
|
|
74
72
|
export interface ModuleGovernedExportRegistration {
|
|
@@ -2,9 +2,12 @@ import type { DurableHandlerContext, PayloadParser } from "@southwind-ai/jobs";
|
|
|
2
2
|
import type { AuditActionType } from "@southwind-ai/shared";
|
|
3
3
|
import type { ModuleActor } from "./actor.js";
|
|
4
4
|
import type { ModuleBackgroundAiPort } from "./background-ai-port.js";
|
|
5
|
+
import type { ModuleSecretPort } from "./secret-port.js";
|
|
6
|
+
import type { ModuleReportStagingPortV1 } from "./report-staging-port.js";
|
|
5
7
|
import type {
|
|
6
8
|
ModuleOpenedResourceFile,
|
|
7
9
|
ModuleResourceFileRequest,
|
|
10
|
+
ModuleStorageWritePortV1,
|
|
8
11
|
} from "./storage-port.js";
|
|
9
12
|
|
|
10
13
|
export interface ModuleDurableStoragePort {
|
|
@@ -16,7 +19,16 @@ export interface ModuleDurableStoragePort {
|
|
|
16
19
|
export interface ModuleDurableHandlerContext extends DurableHandlerContext {
|
|
17
20
|
readonly actor: ModuleActor;
|
|
18
21
|
readonly requestId: string;
|
|
22
|
+
/**
|
|
23
|
+
* 兼容旧 Durable Context 测试桩而保持 optional;Windy Host 每 attempt 注入。
|
|
24
|
+
* 显式依赖 Secret 的 Handler 使用 requireModuleSecretPort() fail closed。
|
|
25
|
+
*/
|
|
26
|
+
readonly secrets?: ModuleSecretPort;
|
|
19
27
|
readonly storage: ModuleDurableStoragePort;
|
|
28
|
+
/** 受治理写入是版本化、可选的 additive seam。 */
|
|
29
|
+
readonly storageWriter?: ModuleStorageWritePortV1;
|
|
30
|
+
/** 每个 attempt 重新绑定 Actor、Scope 与当前授权。 */
|
|
31
|
+
readonly reportStaging?: ModuleReportStagingPortV1;
|
|
20
32
|
readonly ai: ModuleBackgroundAiPort;
|
|
21
33
|
}
|
|
22
34
|
|
|
@@ -36,9 +36,19 @@ test("defineWindyServerComposition 保留项目装配与显式运行时挂载",
|
|
|
36
36
|
assembly: { schemaVersion: 1 as const, modules: [] },
|
|
37
37
|
adapters: [],
|
|
38
38
|
attachments: [attachment],
|
|
39
|
+
secretBindings: [
|
|
40
|
+
{
|
|
41
|
+
moduleName: "case",
|
|
42
|
+
handle: "case.sftp.password",
|
|
43
|
+
connection: "case.sftp.primary",
|
|
44
|
+
purpose: "case.sftp.read",
|
|
45
|
+
resolve: () => ({ status: "disabled" }),
|
|
46
|
+
},
|
|
47
|
+
],
|
|
39
48
|
});
|
|
40
49
|
|
|
41
50
|
expect(declaration.assembly.schemaVersion).toBe(1);
|
|
42
51
|
expect(declaration.attachments).toEqual([attachment]);
|
|
52
|
+
expect(declaration.secretBindings?.[0]?.handle).toBe("case.sftp.password");
|
|
43
53
|
declaration.attachments?.[0]?.attach({ database: "customer" });
|
|
44
54
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { InstallableServerModule } from "./module-host.js";
|
|
2
|
+
import type { ModuleSecretBinding } from "./secret-port.js";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* 模块 package 提供给 Windy Server Host 的标准入口。
|
|
@@ -40,6 +41,8 @@ export interface WindyServerCompositionDeclaration<
|
|
|
40
41
|
readonly assembly: TAssembly;
|
|
41
42
|
readonly adapters: readonly WindyServerModuleAdapter<TManifest>[];
|
|
42
43
|
readonly attachments?: readonly WindyServerModuleAttachment<TRuntime>[];
|
|
44
|
+
/** 只允许 project-owned Composition 提供的模块 Secret 物理绑定。 */
|
|
45
|
+
readonly secretBindings?: readonly ModuleSecretBinding[];
|
|
43
46
|
}
|
|
44
47
|
|
|
45
48
|
export function defineWindyServerModule<TManifest>(
|
|
@@ -7,6 +7,7 @@ import type { ModuleRouteDefinition } from "./route-definition.js";
|
|
|
7
7
|
import type { ModuleSearchProvider } from "./search-provider-port.js";
|
|
8
8
|
import type { ModuleSandboxToolHost } from "./sandbox-tool.js";
|
|
9
9
|
import type { ModuleResourceFileAccessPolicy } from "./storage-port.js";
|
|
10
|
+
import type { ModuleReportStagingPolicyV1 } from "./report-staging-port.js";
|
|
10
11
|
import type { ModuleTaskHandlerRegistration } from "./task-registration.js";
|
|
11
12
|
import type { ModuleToolHandlerRegistration } from "./tool-registration.js";
|
|
12
13
|
|
|
@@ -15,6 +16,11 @@ export interface ModuleUploadPolicy {
|
|
|
15
16
|
maxByteSize: number;
|
|
16
17
|
maxPartByteSize: number;
|
|
17
18
|
sessionTtlMs: number;
|
|
19
|
+
/**
|
|
20
|
+
* Writer V1 发布文件的保留期。缺失时旧 create/read Port 仍可用,
|
|
21
|
+
* Writer V1 创建会话会 fail closed。
|
|
22
|
+
*/
|
|
23
|
+
fileRetentionMs?: number;
|
|
18
24
|
allowedTypes: Readonly<Record<string, readonly string[]>>;
|
|
19
25
|
signature?: "image" | "none";
|
|
20
26
|
}
|
|
@@ -29,6 +35,8 @@ export interface ModuleUploadPolicy {
|
|
|
29
35
|
export interface ModuleHost {
|
|
30
36
|
readonly moduleName: string;
|
|
31
37
|
registerUploadPolicy(policy: ModuleUploadPolicy): void;
|
|
38
|
+
/** 注册 Host 固定治理上限的大报告暂存用途。 */
|
|
39
|
+
registerReportStagingPolicy(policy: ModuleReportStagingPolicyV1): void;
|
|
32
40
|
/**
|
|
33
41
|
* 注册跨上传者资源文件读取策略;purpose 必须由本模块或 Manifest 显式依赖模块的
|
|
34
42
|
* Upload Policy 声明,Feature、Permission 与 Audit Action 必须来自当前 Manifest。
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import {
|
|
3
|
+
ModuleReportStagingError,
|
|
4
|
+
type ModuleReportStagingPortV1,
|
|
5
|
+
requireModuleReportStagingPortV1,
|
|
6
|
+
} from "./report-staging-port.js";
|
|
7
|
+
|
|
8
|
+
describe("Module Report Staging Context 兼容 seam", () => {
|
|
9
|
+
test("缺少 V1 Port 时 helper 以稳定 unavailable fail closed", () => {
|
|
10
|
+
expect(() => requireModuleReportStagingPortV1({})).toThrow(
|
|
11
|
+
new ModuleReportStagingError(
|
|
12
|
+
"REPORT_STAGING_UNAVAILABLE",
|
|
13
|
+
"模块 Report Staging V1 未挂载",
|
|
14
|
+
true,
|
|
15
|
+
),
|
|
16
|
+
);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test("Host 注入的版本化 Port 原样返回", () => {
|
|
20
|
+
const port = {} as ModuleReportStagingPortV1;
|
|
21
|
+
expect(requireModuleReportStagingPortV1({ reportStaging: port })).toBe(
|
|
22
|
+
port,
|
|
23
|
+
);
|
|
24
|
+
});
|
|
25
|
+
});
|