create-windy 0.9.1 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +1691 -1151
- package/package.json +2 -2
- package/template/.agents/skills/windy-business-module/SKILL.md +33 -1
- package/template/.windy-template.json +6 -2
- package/template/AGENTS.md +4 -0
- package/template/README.md +2 -0
- package/template/apps/agent-server/Dockerfile +1 -1
- package/template/apps/agent-server/README.md +1 -1
- package/template/apps/agent-server/native/EXTENSIONS.md +2 -2
- package/template/apps/agent-server/native/parallel-harness.ts +2 -0
- package/template/apps/agent-server/native/storage-lifecycle.test.ts +2 -1
- package/template/apps/agent-server/package.json +42 -41
- package/template/apps/agent-server/plugins/downloads/README.md +1 -1
- package/template/apps/agent-server/plugins/drop-overlay/README.md +1 -1
- package/template/apps/agent-server/plugins/settings/README.md +1 -1
- package/template/apps/agent-server/plugins/skill-library/client-chunks.test.ts +4 -1
- package/template/apps/agent-server/plugins/theme/README.md +5 -1
- package/template/apps/agent-server/plugins/theme/source-tokens.ts +0 -1
- package/template/apps/agent-server/plugins/theme/tokens.json +0 -4
- package/template/apps/agent-server/plugins/tool-catalog/README.md +6 -3
- package/template/apps/agent-server/plugins/tool-catalog/discovery.mjs +13 -10
- package/template/apps/agent-server/plugins/tool-catalog/discovery.test.ts +68 -6
- package/template/apps/agent-server/runtime/compatibility.ts +7 -1
- package/template/apps/agent-server/runtime/dsh-engine.ts +2 -0
- package/template/apps/agent-server/runtime/questions-workflow.nodecheck.ts +2 -0
- package/template/apps/server/Dockerfile +2 -1
- package/template/apps/server/package.json +11 -11
- package/template/apps/server/scripts/validate-module-composition-once.ts +2 -0
- package/template/apps/server/scripts/validate-module-composition.ts +8 -4
- package/template/apps/server/src/admin/routes.test.ts +29 -1
- package/template/apps/server/src/admin/routes.ts +20 -2
- package/template/apps/server/src/agent/client-session/completion.ts +1 -1
- package/template/apps/server/src/agent/client-session/manifest-admission.ts +1 -1
- package/template/apps/server/src/agent/client-session/request.ts +1 -1
- package/template/apps/server/src/agent/context-version-routes.ts +37 -13
- package/template/apps/server/src/agent/run-facade.ts +1 -1
- package/template/apps/server/src/agent/run-input-verification.ts +1 -1
- package/template/apps/server/src/agent/run-routes.ts +1 -14
- package/template/apps/server/src/agent/run-start-preparation.ts +1 -1
- package/template/apps/server/src/agent/runtime-bootstrap-input.ts +2 -0
- package/template/apps/server/src/agent/runtime-bootstrap.ts +49 -157
- package/template/apps/server/src/agent/runtime-disabled-composition.ts +2 -1
- package/template/apps/server/src/agent/session-invalidation/authorization-revocation.ts +54 -0
- package/template/apps/server/src/agent/session-runtime-composition.ts +1 -51
- package/template/apps/server/src/agent/unavailable-routes.ts +13 -2
- package/template/apps/server/src/agent-workflow/runtime-composition.ts +3 -0
- package/template/apps/server/src/agent-workflow/service.ts +17 -1
- package/template/apps/server/src/ai-artifact/media-resource-route.test.ts +134 -0
- package/template/apps/server/src/ai-artifact/routes.ts +1 -1
- package/template/apps/server/src/ai-artifact/runtime.ts +12 -0
- package/template/apps/server/src/ai-runtime-readiness/operation-port.test-support.ts +1 -1
- package/template/apps/server/src/ai-runtime-readiness/operation-port.ts +8 -0
- package/template/apps/server/src/ai-runtime-security/internal-token.ts +14 -0
- package/template/apps/server/src/app/antivirus-composition.test.ts +63 -0
- package/template/apps/server/src/app/antivirus-composition.ts +29 -0
- package/template/apps/server/src/app/dsh-workbench-socket-audit.test.ts +2 -1
- package/template/apps/server/src/configuration/definition.ts +15 -11
- package/template/apps/server/src/document/facade-support.ts +2 -2
- package/template/apps/server/src/document/facade.ts +2 -2
- package/template/apps/server/src/document/output-artifact-composition.ts +9 -5
- package/template/apps/server/src/document/output-artifact.test-support.ts +1 -1
- package/template/apps/server/src/embedding/facade.ts +1 -1
- package/template/apps/server/src/embedding/input.ts +1 -1
- package/template/apps/server/src/embedding/routes.ts +1 -1
- package/template/apps/server/src/index.ts +60 -60
- package/template/apps/server/src/license/routes.ts +4 -1
- package/template/apps/server/src/license/runtime-business-access.test.ts +261 -0
- package/template/apps/server/src/media-runtime/composition.ts +157 -0
- package/template/apps/server/src/media-runtime/media-only-composition.ts +44 -0
- package/template/apps/server/src/media-runtime/module-ai-port-factory.test.ts +69 -0
- package/template/apps/server/src/media-runtime/module-ai-port-factory.ts +72 -0
- package/template/apps/server/src/{agent → media-runtime}/runtime-readiness-sources.ts +14 -6
- package/template/apps/server/src/media-runtime/shared-composition.ts +104 -0
- package/template/apps/server/src/module-composition.test.ts +22 -0
- package/template/apps/server/src/module-composition.ts +48 -0
- package/template/apps/server/src/module-host/ai-operation-port.ts +97 -30
- package/template/apps/server/src/module-host/ai-operation-speech-normalize.test.ts +1 -1
- package/template/apps/server/src/module-host/http-runtime.ts +9 -3
- package/template/apps/server/src/module-host/static-route-authorization.test.ts +6 -3
- package/template/apps/server/src/module-host/storage-authorization-binding.test.ts +4 -0
- package/template/apps/server/src/module-runtime-validation.ts +2 -0
- package/template/apps/server/src/observability/diagnostic-index.ts +26 -1
- package/template/apps/server/src/observability/diagnostic-repository.ts +40 -11
- package/template/apps/server/src/platform-http-runtime.ts +1 -1
- package/template/apps/server/src/runtime-feature.ts +5 -1
- package/template/apps/server/src/runtime.ts +3 -0
- package/template/apps/server/src/settings/drizzle-watermark-repository.ts +35 -4
- package/template/apps/server/src/settings/watermark-repository.ts +14 -0
- package/template/apps/server/src/settings/watermark-routes.test.ts +84 -2
- package/template/apps/server/src/settings/watermark-routes.ts +109 -0
- package/template/apps/server/src/settings/watermark-transfer.ts +79 -0
- package/template/apps/server/src/speech/facade-validation.ts +1 -1
- package/template/apps/server/src/speech/facade.ts +2 -2
- package/template/apps/server/src/startup-composition-validation.test.ts +32 -0
- package/template/apps/server/src/startup-finalization.ts +2 -0
- package/template/apps/server/src/startup-runtime.ts +77 -0
- package/template/apps/server/src/system/ai-runtime-build.ts +3 -0
- package/template/apps/server/src/system/ai-runtime-configuration.test.ts +36 -0
- package/template/apps/server/src/system/ai-runtime-configuration.ts +58 -0
- package/template/apps/server/src/system/diagnostic-routes.test.ts +45 -0
- package/template/apps/server/src/system/diagnostic-routes.ts +35 -0
- package/template/apps/server/src/system/environment-policy-reader.test.ts +74 -0
- package/template/apps/server/src/system/environment-policy-reader.ts +62 -0
- package/template/apps/server/src/system/feature-environment-assessment.test.ts +148 -0
- package/template/apps/server/src/system/feature-environment-assessment.ts +179 -0
- package/template/apps/server/src/system/host-diagnostics.test.ts +155 -0
- package/template/apps/server/src/system/host-diagnostics.ts +225 -0
- package/template/apps/server/src/system/menu-registry.test.ts +26 -0
- package/template/apps/server/src/system/menu-registry.ts +9 -7
- package/template/apps/server/src/system/operations.test.ts +5 -0
- package/template/apps/server/src/system/operations.ts +36 -12
- package/template/apps/server/src/system/role-authorization-postgres.integration.test.ts +181 -0
- package/template/apps/web/Dockerfile +7 -3
- package/template/apps/web/dev/dev-port.test.ts +6 -6
- package/template/apps/web/dev/dev-port.ts +1 -1
- package/template/apps/web/dev/start.ts +6 -1
- package/template/apps/web/index.html +1 -0
- package/template/apps/web/package.json +16 -16
- package/template/apps/web/runtime-server.test.ts +22 -1
- package/template/apps/web/runtime-server.ts +6 -0
- package/template/apps/web/src/App.vue +6 -3
- package/template/apps/web/src/assets/windy.svg +4 -0
- package/template/apps/web/src/components/auth/LoginForm.vue +2 -2
- package/template/apps/web/src/components/auth/PasswordChangeForm.vue +14 -3
- package/template/apps/web/src/components/common/FormDialog.vue +1 -1
- package/template/apps/web/src/components/license/LicenseFlow.webtest.ts +3 -0
- package/template/apps/web/src/components/license/LicenseMachineCodeQr.vue +99 -0
- package/template/apps/web/src/components/license/LicenseMachineCodeQr.webtest.ts +83 -0
- package/template/apps/web/src/components/license/LicensePairingCard.vue +1 -1
- package/template/apps/web/src/components/license/LicenseStatusCard.vue +14 -2
- package/template/apps/web/src/composables/useLoginFlow.ts +2 -2
- package/template/apps/web/src/composables/usePlatformSettings.ts +1 -1
- package/template/apps/web/src/composables/useWatermarkSettings.ts +1 -0
- package/template/apps/web/src/layout/AppSidebar.vue +5 -9
- package/template/apps/web/src/layout/AppSidebar.webtest.ts +4 -1
- package/template/apps/web/src/pages/auth/ChangePasswordPage.vue +67 -6
- package/template/apps/web/src/pages/auth/LoginPage.vue +3 -12
- package/template/apps/web/src/pages/configuration/components/ModuleConfigurationEditor.vue +30 -0
- package/template/apps/web/src/pages/configuration/components/ModuleConfigurationWorkbench.vue +25 -14
- package/template/apps/web/src/pages/configuration/components/TimeZoneSelect.vue +55 -0
- package/template/apps/web/src/pages/profile/PersonalSettingsPage.vue +64 -11
- package/template/apps/web/src/pages/profile/PersonalSettingsPage.webtest.ts +21 -1
- package/template/apps/web/src/pages/settings/BrandingSettingsSection.vue +7 -18
- package/template/apps/web/src/pages/settings/BrandingSettingsSection.webtest.ts +9 -4
- package/template/apps/web/src/pages/settings/GlobalSettingsPage.vue +51 -6
- package/template/apps/web/src/pages/settings/GlobalSettingsPage.webtest.ts +19 -3
- package/template/apps/web/src/pages/settings/WatermarkSettingsSection.vue +1 -0
- package/template/apps/web/src/pages/settings/WatermarkYamlTransfer.vue +211 -0
- package/template/apps/web/src/pages/system/DiagnosticLookupPage.vue +18 -3
- package/template/apps/web/src/pages/system/DiagnosticLookupPage.webtest.ts +4 -1
- package/template/apps/web/src/pages/system/SystemOperationsPage.vue +23 -0
- package/template/apps/web/src/pages/system/components/DiagnosticLogList.vue +120 -0
- package/template/apps/web/src/pages/system/components/OperationEnvironmentPanel.vue +237 -0
- package/template/apps/web/src/pages/system/components/OperationFeatureAssessmentPanel.vue +131 -0
- package/template/apps/web/src/pages/system/components/PagedSelectionList.vue +31 -24
- package/template/apps/web/src/pages/system/components/SystemResourceActions.vue +2 -1
- package/template/apps/web/src/pages/system/components/SystemResourceEditor.vue +11 -2
- package/template/apps/web/src/pages/system/components/SystemResourcePage.vue +1 -0
- package/template/apps/web/src/pages/system/components/SystemResourcePage.webtest.ts +6 -2
- package/template/apps/web/src/pages/system/components/agent-skills/AgentSkillImportDialog.vue +18 -9
- package/template/apps/web/src/pages/system/components/agent-workbench/SessionReplayTimeline.vue +18 -9
- package/template/apps/web/src/pages/system/components/agent-workbench/TestRunComposer.vue +66 -34
- package/template/apps/web/src/pages/system/components/agent-workbench/ToolCatalogPanel.vue +48 -33
- package/template/apps/web/src/pages/system/components/agent-workbench/ToolCatalogPanel.webtest.ts +9 -2
- package/template/apps/web/src/pages/system/components/agent-workbench/ToolRuleDetail.vue +23 -16
- package/template/apps/web/src/pages/system/components/dictionary-bulk/DictionaryBulkJobDetail.vue +10 -7
- package/template/apps/web/src/pages/system/components/user-account/RolePermissionSummary.vue +81 -57
- package/template/apps/web/src/pages/system/components/user-account/UserRoleSelector.vue +6 -4
- package/template/apps/web/src/pages/system/components/user-account/UserRoleSelector.webtest.ts +20 -4
- package/template/apps/web/src/pages/system/resource-config.ts +9 -0
- package/template/apps/web/src/pages/work-orders/WorkOrderListPage.vue +1 -1
- package/template/apps/web/src/router/disabled-feature-loading.webtest.ts +78 -0
- package/template/apps/web/src/router/index.ts +3 -6
- package/template/apps/web/src/router/manifest-routes.ts +2 -3
- package/template/apps/web/src/router/platform-admin-pages.ts +21 -62
- package/template/apps/web/src/router/platform-admin-route-bindings.ts +4 -4
- package/template/apps/web/src/services/diagnostics-api.ts +13 -1
- package/template/apps/web/src/services/operations-api.ts +4 -0
- package/template/apps/web/src/services/platform-settings-api.ts +35 -1
- package/template/apps/web/vite.config.ts +9 -3
- package/template/deploy/environment/windy.environment.example.yaml +53 -0
- package/template/docker-compose.yml +4 -2
- package/template/docs/architecture/agent-admin-workbench-implementation.md +1 -1
- package/template/docs/architecture/agent-admin-workbench-plan.md +1 -1
- package/template/docs/architecture/agent-workflow.md +8 -0
- package/template/docs/architecture/durable-jobs.md +17 -0
- package/template/docs/architecture/embedded-dsh-integration.md +1 -1
- package/template/docs/development/dsh-plugins.md +1 -1
- package/template/docs/development/performance-engineering.md +24 -0
- package/template/docs/operations/admin-settings-yaml.md +29 -0
- package/template/docs/operations/dsh-agent-migration.md +2 -2
- package/template/docs/operations/environment-capabilities.md +185 -0
- package/template/docs/platform/module-configuration.md +18 -3
- package/template/docs/platform/platform-authentication.md +1 -1
- package/template/package.json +10 -8
- package/template/packages/config/package.json +2 -2
- package/template/packages/config/src/definition.ts +14 -4
- package/template/packages/config/src/environment-loader.ts +27 -3
- package/template/packages/config/src/platform-ai-runtime.test.ts +94 -0
- package/template/packages/config/src/platform.ts +5 -2
- package/template/packages/database/drizzle/0065_durable_job_lease_snapshot_lookup.sql +1 -0
- package/template/packages/database/drizzle/0066_agent_source_sequence_bigint.sql +3 -0
- package/template/packages/database/drizzle/0067_media_runtime_access.sql +46 -0
- package/template/packages/database/drizzle/meta/0065_snapshot.json +15370 -0
- package/template/packages/database/drizzle/meta/0066_snapshot.json +15370 -0
- package/template/packages/database/drizzle/meta/0067_snapshot.json +15370 -0
- package/template/packages/database/drizzle/meta/_journal.json +21 -0
- package/template/packages/database/package.json +3 -3
- package/template/packages/database/src/schema/agent-session.ts +4 -3
- package/template/packages/database/src/schema/durable-jobs.ts +4 -0
- package/template/packages/database/src/schema/index.ts +3 -1
- package/template/packages/database/src/schema-durable-recovery.test.ts +21 -1
- package/template/packages/database/src/schema-source-sequence.test.ts +24 -0
- package/template/packages/example-work-order/package.json +2 -2
- package/template/packages/modules/package.json +1 -1
- package/template/packages/modules/src/admin-ui-boundary.test.ts +33 -0
- package/template/packages/modules/src/composition.ts +11 -28
- package/template/packages/modules/src/manifest.ts +2 -0
- package/template/packages/modules/src/menu-composition.ts +24 -0
- package/template/packages/modules/src/system-admin-routes.ts +2 -2
- package/template/packages/modules/src/system-admin-ui-catalog.ts +6 -1
- package/template/packages/modules/src/system-ai-api-bindings.ts +0 -16
- package/template/packages/modules/src/system-api-control-plane.ts +9 -1
- package/template/packages/modules/src/system-api-permissions.ts +7 -0
- package/template/packages/modules/src/system-api-watermark.ts +21 -0
- package/template/packages/modules/src/system-audit-actions.ts +3 -1
- package/template/packages/modules/src/system-features.ts +21 -3
- package/template/packages/modules/src/system-media-api-bindings.ts +97 -0
- package/template/packages/modules/src/system-module-audit-selection.ts +2 -0
- package/template/packages/modules/src/system-module-catalog.test.ts +13 -6
- package/template/packages/modules/src/system-module-catalog.ts +6 -241
- package/template/packages/modules/src/system-module-definitions.ts +260 -0
- package/template/packages/modules/src/system-modules-access.test.ts +2 -0
- package/template/packages/modules/src/system-modules.test.ts +7 -1
- package/template/packages/modules/src/system-modules.ts +25 -13
- package/template/packages/modules/src/system-permissions.ts +12 -0
- package/template/packages/server-sdk/package.json +1 -1
- package/template/packages/shared/index.ts +3 -0
- package/template/packages/shared/package.json +1 -1
- package/template/packages/shared/src/environment-assessment.ts +68 -0
- package/template/packages/shared/src/environment-policy.ts +205 -0
- package/template/packages/shared/src/license-console-capabilities.ts +7 -0
- package/template/packages/shared/src/license.ts +1 -0
- package/template/packages/shared/src/module-configuration.ts +2 -1
- package/template/scripts/operations/collect-device-info.py +230 -0
- package/template/apps/server/src/agent/module-ai-port-factory.ts +0 -41
- /package/template/apps/server/src/{agent → ai-runtime-security}/execution-grants.ts +0 -0
- /package/template/apps/server/src/{agent → ai-runtime-security}/idempotency-key.test.ts +0 -0
- /package/template/apps/server/src/{agent → ai-runtime-security}/idempotency-key.ts +0 -0
- /package/template/apps/server/src/{agent → ai-runtime-security}/provider-input-governance.test.ts +0 -0
- /package/template/apps/server/src/{agent → ai-runtime-security}/provider-input-governance.ts +0 -0
- /package/template/apps/server/src/{agent → media-runtime}/required-environment.ts +0 -0
- /package/template/apps/server/src/{agent → media-runtime}/runtime-readiness-sources.test.ts +0 -0
|
@@ -9,25 +9,22 @@ import { registerBulkDataRoutes } from "./bulk-data/routes.js";
|
|
|
9
9
|
// @windy-module system.data-governance begin
|
|
10
10
|
import { registerGovernedUserExportRoutes } from "./data-governance/export/routes.js";
|
|
11
11
|
// @windy-module system.data-governance end
|
|
12
|
-
import { createServerRuntime } from "./runtime.js";
|
|
13
12
|
// @windy-module system.scheduler begin
|
|
14
13
|
import { readPositiveInt } from "./runtime-config.js";
|
|
15
14
|
// @windy-module system.scheduler end
|
|
15
|
+
// @windy-module system.media-runtime begin
|
|
16
|
+
import { composeMediaOnlyRuntime } from "./media-runtime/media-only-composition.js";
|
|
17
|
+
// @windy-module system.media-runtime end
|
|
16
18
|
// @windy-module system.agent begin
|
|
17
19
|
import { DeferredAgentBackgroundOperationPortFactory } from "./agent/background-operation-port.js";
|
|
18
20
|
import { composeApplicationAgentRuntime } from "./app/agent-runtime-composition.js";
|
|
19
21
|
import { workflowDurableInput } from "./agent/workflow-durable-runtime-input.js";
|
|
20
22
|
// @windy-module system.agent end
|
|
21
|
-
import { createComposedAuthRuntime } from "./auth/composition.js";
|
|
22
|
-
// @windy-module system.license begin
|
|
23
|
-
import { createLicenseRuntimeActivation } from "./license/activation.js";
|
|
24
|
-
// @windy-module system.license end
|
|
25
23
|
// @windy-module system.operations begin
|
|
26
24
|
import { registerSystemOperationRoutes } from "./system/operations.js";
|
|
27
25
|
import { createPostgresMonitorProbe } from "./system/postgres-monitoring.js";
|
|
28
26
|
// @windy-module system.operations end
|
|
29
27
|
import { registerSystemRoutes } from "./system/routes.js";
|
|
30
|
-
import { createAuthorizationInvalidationComposition } from "./system/authorization-invalidation-composition.js";
|
|
31
28
|
// @windy-module system.scheduler begin
|
|
32
29
|
import { registerSchedulerRoutes } from "./scheduler/routes.js";
|
|
33
30
|
import { SchedulerWorker } from "./scheduler/worker.js";
|
|
@@ -56,9 +53,9 @@ import { createSearchHost } from "./search/host.js";
|
|
|
56
53
|
import { registerWorkflowRoutes } from "./workflow/routes.js";
|
|
57
54
|
// @windy-module system.workflow end
|
|
58
55
|
import { bootstrapServerModules } from "./module-bootstrap.js";
|
|
59
|
-
import { createHttpObservability } from "./platform-http-runtime.js";
|
|
60
56
|
import { bootstrapPlatformApp } from "./platform-app-bootstrap.js";
|
|
61
57
|
import { createPreparedPlatformBootstrap } from "./startup-preflight.js";
|
|
58
|
+
import { createStartupRuntime } from "./startup-runtime.js";
|
|
62
59
|
import { finalizePlatformStartup } from "./startup-finalization.js";
|
|
63
60
|
const { logger, persistence, platformConfig, preparedModules } =
|
|
64
61
|
await createPreparedPlatformBootstrap();
|
|
@@ -73,36 +70,6 @@ const {
|
|
|
73
70
|
systemRepositories,
|
|
74
71
|
} = await bootstrapServerModules(platformConfig, persistence, preparedModules);
|
|
75
72
|
const features = foundationSnapshot.features;
|
|
76
|
-
// @windy-module system.license begin
|
|
77
|
-
const licenseActivation = createLicenseRuntimeActivation(
|
|
78
|
-
process.env,
|
|
79
|
-
foundationSnapshot.platform.licenseEnabled,
|
|
80
|
-
persistence?.licenseResolver,
|
|
81
|
-
);
|
|
82
|
-
// @windy-module system.license end
|
|
83
|
-
const runtime = createServerRuntime(process.env, {
|
|
84
|
-
actorResolver: persistence?.actorResolver,
|
|
85
|
-
// @windy-module system.license begin
|
|
86
|
-
licenseResolver: licenseActivation.resolver,
|
|
87
|
-
licenseEnforced: licenseActivation.enforced,
|
|
88
|
-
// @windy-module system.license end
|
|
89
|
-
featureResolver: persistence ? systemRepositories.features : undefined,
|
|
90
|
-
featureCatalog: features,
|
|
91
|
-
disabledModuleNames: new Set(foundationSnapshot.disabledModuleNames),
|
|
92
|
-
// @windy-module system.audit begin
|
|
93
|
-
auditReader: persistence?.auditReader,
|
|
94
|
-
auditWriter: persistence?.auditWriter,
|
|
95
|
-
// @windy-module system.audit end
|
|
96
|
-
});
|
|
97
|
-
const observability = createHttpObservability(runtime, persistence, logger);
|
|
98
|
-
const authorizationInvalidation = createAuthorizationInvalidationComposition({
|
|
99
|
-
platformConfig,
|
|
100
|
-
persistence,
|
|
101
|
-
repositories: systemRepositories,
|
|
102
|
-
});
|
|
103
|
-
// @windy-module system.license begin
|
|
104
|
-
licenseActivation.runtime.setAuditSink(runtime.auditSink);
|
|
105
|
-
// @windy-module system.license end
|
|
106
73
|
const {
|
|
107
74
|
authRepository,
|
|
108
75
|
authService,
|
|
@@ -112,12 +79,18 @@ const {
|
|
|
112
79
|
// @windy-module system.data-governance begin
|
|
113
80
|
reauthentication,
|
|
114
81
|
// @windy-module system.data-governance end
|
|
115
|
-
} = createComposedAuthRuntime({
|
|
116
|
-
repositories: systemRepositories,
|
|
117
|
-
platformConfig,
|
|
118
|
-
persistence,
|
|
119
82
|
runtime,
|
|
120
|
-
|
|
83
|
+
observability,
|
|
84
|
+
authorizationInvalidation,
|
|
85
|
+
aiRuntimeSwitches,
|
|
86
|
+
disabledAiFeatures,
|
|
87
|
+
// @windy-module system.license begin
|
|
88
|
+
licenseActivation,
|
|
89
|
+
// @windy-module system.license end
|
|
90
|
+
} = await createStartupRuntime(
|
|
91
|
+
{ logger, persistence, platformConfig },
|
|
92
|
+
{ foundationSnapshot, systemRepositories },
|
|
93
|
+
);
|
|
121
94
|
// @windy-module system.storage begin
|
|
122
95
|
const { storageRuntime, reportStagingRuntime } = createStorageHostRuntime(
|
|
123
96
|
process.env,
|
|
@@ -276,23 +249,47 @@ registerSystemOperationRoutes(app, runtime, features, {
|
|
|
276
249
|
databaseMonitorProbe: createPostgresMonitorProbe(persistence?.pool),
|
|
277
250
|
});
|
|
278
251
|
// @windy-module system.operations end
|
|
279
|
-
// @windy-module system.
|
|
280
|
-
const
|
|
252
|
+
// @windy-module system.media-runtime begin
|
|
253
|
+
const aiRuntimeInput = {
|
|
281
254
|
app,
|
|
282
|
-
platformConfig,
|
|
283
255
|
modules: foundationModules,
|
|
284
256
|
hosts: moduleHosts,
|
|
285
257
|
runtime,
|
|
286
258
|
systemRepositories,
|
|
287
259
|
storage: storageRuntime,
|
|
288
|
-
workflow: workflowService,
|
|
289
|
-
...workflowDurableInput([durableJobRuntime, storageRuntime, logger]),
|
|
290
260
|
db: persistence?.db,
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
261
|
+
};
|
|
262
|
+
let sharedAiPorts:
|
|
263
|
+
| Pick<
|
|
264
|
+
Parameters<typeof installModuleHttpRuntime>[2],
|
|
265
|
+
"aiArtifacts" | "aiOperations" | "aiReadiness"
|
|
266
|
+
>
|
|
267
|
+
| undefined;
|
|
268
|
+
if (aiRuntimeSwitches.agent === false) {
|
|
269
|
+
sharedAiPorts = composeMediaOnlyRuntime({
|
|
270
|
+
...aiRuntimeInput,
|
|
271
|
+
enableAI: platformConfig.enableAI,
|
|
272
|
+
switches: aiRuntimeSwitches,
|
|
273
|
+
features,
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
// @windy-module system.media-runtime end
|
|
277
|
+
// @windy-module system.agent begin
|
|
278
|
+
const agentRuntime =
|
|
279
|
+
aiRuntimeSwitches.agent !== false
|
|
280
|
+
? composeApplicationAgentRuntime({
|
|
281
|
+
...aiRuntimeInput,
|
|
282
|
+
aiRuntimeSwitches,
|
|
283
|
+
platformConfig,
|
|
284
|
+
workflow: workflowService,
|
|
285
|
+
...workflowDurableInput([durableJobRuntime, storageRuntime, logger]),
|
|
286
|
+
backgroundAi: moduleBackgroundAi,
|
|
287
|
+
bindAuthorizationInvalidation: (target) =>
|
|
288
|
+
authorizationInvalidation.bind(target),
|
|
289
|
+
bindClientAgentSessions,
|
|
290
|
+
})
|
|
291
|
+
: undefined;
|
|
292
|
+
if (agentRuntime) sharedAiPorts = agentRuntime;
|
|
296
293
|
// @windy-module system.agent end
|
|
297
294
|
// @windy-module system.scheduler begin
|
|
298
295
|
registerSchedulerRoutes(app, scheduler, runtime, features);
|
|
@@ -312,13 +309,15 @@ installModuleHttpRuntime(moduleHosts, app, {
|
|
|
312
309
|
reportStaging: reportStagingRuntime,
|
|
313
310
|
// @windy-module system.storage end
|
|
314
311
|
systemRepositories,
|
|
312
|
+
// @windy-module system.media-runtime begin
|
|
313
|
+
aiArtifacts: sharedAiPorts?.aiArtifacts,
|
|
314
|
+
aiOperations: sharedAiPorts?.aiOperations,
|
|
315
|
+
aiReadiness: sharedAiPorts?.aiReadiness,
|
|
316
|
+
// @windy-module system.media-runtime end
|
|
315
317
|
// @windy-module system.agent begin
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
sessionMemory: agentRuntime.sessionMemory,
|
|
320
|
-
sourceInvalidation: agentRuntime.sourceInvalidation,
|
|
321
|
-
screenshots: agentRuntime.screenshots,
|
|
318
|
+
sessionMemory: agentRuntime?.sessionMemory,
|
|
319
|
+
sourceInvalidation: agentRuntime?.sourceInvalidation,
|
|
320
|
+
screenshots: agentRuntime?.screenshots,
|
|
322
321
|
// @windy-module system.agent end
|
|
323
322
|
// @windy-module system.data-governance begin
|
|
324
323
|
reauthenticate: (actorId, password) =>
|
|
@@ -328,13 +327,14 @@ installModuleHttpRuntime(moduleHosts, app, {
|
|
|
328
327
|
});
|
|
329
328
|
finalizePlatformStartup({
|
|
330
329
|
app,
|
|
330
|
+
disabledFeatureKeys: disabledAiFeatures,
|
|
331
331
|
modules: foundationModules,
|
|
332
332
|
// @windy-module system.scheduler begin
|
|
333
333
|
tasks: scheduledTaskDefinitions,
|
|
334
334
|
// @windy-module system.scheduler end
|
|
335
335
|
// @windy-module system.agent begin
|
|
336
|
-
tools: agentRuntime
|
|
337
|
-
disposeAgentRuntime: agentRuntime
|
|
336
|
+
tools: agentRuntime?.toolHandlers,
|
|
337
|
+
disposeAgentRuntime: agentRuntime?.disposeAgentRuntime,
|
|
338
338
|
// @windy-module system.agent end
|
|
339
339
|
// @windy-module system.search begin
|
|
340
340
|
providers: searchHost.providerKeys,
|
|
@@ -35,7 +35,10 @@ export function registerPlatformLicenseRoutes(
|
|
|
35
35
|
{ restrictedModeAccess: "admin-admission" },
|
|
36
36
|
);
|
|
37
37
|
if (denied) return denied;
|
|
38
|
-
return
|
|
38
|
+
return Response.json(
|
|
39
|
+
await licenseRuntime.snapshotForActor(context.guardContext.actor),
|
|
40
|
+
{ headers: { "cache-control": "no-store" } },
|
|
41
|
+
);
|
|
39
42
|
});
|
|
40
43
|
|
|
41
44
|
app.post(
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { generateKeyPairSync, sign } from "node:crypto";
|
|
3
|
+
import { Elysia } from "elysia";
|
|
4
|
+
import {
|
|
5
|
+
createLicenseSigningPayload,
|
|
6
|
+
MemoryAtomicLicenseStore,
|
|
7
|
+
} from "@southwind-ai/license";
|
|
8
|
+
import { licenseVersionKey, type SignedLicenseV1 } from "@southwind-ai/shared";
|
|
9
|
+
import { createFoundationSnapshot, loadSystemModules } from "../foundation.js";
|
|
10
|
+
import { createServerRuntime } from "../runtime.js";
|
|
11
|
+
import { createStaticRouteAuthorizer } from "../module-host/static-route-authorization.js";
|
|
12
|
+
import { evaluateAdminAccess } from "../admin/routes.js";
|
|
13
|
+
import { evaluateRouteGuards } from "../route-guards.js";
|
|
14
|
+
import { PlatformLicenseRuntime } from "./runtime-service.js";
|
|
15
|
+
import { registerPlatformLicenseRoutes } from "./routes.js";
|
|
16
|
+
import {
|
|
17
|
+
evaluateRestrictedHttpRequest,
|
|
18
|
+
licenseRestrictedResponse,
|
|
19
|
+
} from "./restriction.js";
|
|
20
|
+
|
|
21
|
+
const businessPermissions = ["home.read", "case.read"];
|
|
22
|
+
|
|
23
|
+
describe("普通业务账号的 License 运行状态契约", () => {
|
|
24
|
+
test("仅业务权限可读取最小投影并通过业务 Guard,未授权页面和后台仍拒绝", async () => {
|
|
25
|
+
const fixture = createFixture();
|
|
26
|
+
const response = await fixture.request("/license/runtime");
|
|
27
|
+
expect(response.status).toBe(200);
|
|
28
|
+
expect(response.headers.get("cache-control")).toBe("no-store");
|
|
29
|
+
expect(await response.json()).toEqual({
|
|
30
|
+
status: "valid",
|
|
31
|
+
restricted: false,
|
|
32
|
+
expiresAt: "2030-08-01T00:00:00.000Z",
|
|
33
|
+
reminder: { level: "none", daysRemaining: 1461 },
|
|
34
|
+
canViewDetails: false,
|
|
35
|
+
});
|
|
36
|
+
const context = await fixture.runtime.createGuardContext(
|
|
37
|
+
new Request("http://localhost/"),
|
|
38
|
+
);
|
|
39
|
+
for (const permissionKey of businessPermissions) {
|
|
40
|
+
expect(
|
|
41
|
+
(
|
|
42
|
+
await evaluateRouteGuards(fixture.runtime, context, {
|
|
43
|
+
permission: { method: "GET", path: "/api/business", permissionKey },
|
|
44
|
+
})
|
|
45
|
+
).allowed,
|
|
46
|
+
).toBe(true);
|
|
47
|
+
}
|
|
48
|
+
expect(
|
|
49
|
+
(
|
|
50
|
+
await evaluateRouteGuards(fixture.runtime, context, {
|
|
51
|
+
permission: {
|
|
52
|
+
method: "POST",
|
|
53
|
+
path: "/api/cases",
|
|
54
|
+
permissionKey: "case.manage",
|
|
55
|
+
},
|
|
56
|
+
})
|
|
57
|
+
).reason,
|
|
58
|
+
).toBe("missing-permission");
|
|
59
|
+
expect(
|
|
60
|
+
(await evaluateAdminAccess(fixture.runtime, context, fixture.features))
|
|
61
|
+
.reason,
|
|
62
|
+
).toBe("missing-permission");
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test("匿名及服务 Actor 不取得运行状态", async () => {
|
|
66
|
+
for (const actorType of ["anonymous", "service"] as const) {
|
|
67
|
+
expect(
|
|
68
|
+
(await createFixture({ actorType }).request("/license/runtime")).status,
|
|
69
|
+
).toBe(401);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test("无任何权限也只获得基础投影,License 管理开关不影响基础读取", async () => {
|
|
74
|
+
const fixture = createFixture({
|
|
75
|
+
permissionKeys: [],
|
|
76
|
+
licenseFeatureEnabled: false,
|
|
77
|
+
});
|
|
78
|
+
const response = await fixture.request("/license/runtime");
|
|
79
|
+
expect(response.status).toBe(200);
|
|
80
|
+
expect(await response.json()).toMatchObject({
|
|
81
|
+
canViewDetails: false,
|
|
82
|
+
restricted: false,
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test("业务用户不可安装、配对、确认或读取管理记录", async () => {
|
|
87
|
+
const fixture = createFixture();
|
|
88
|
+
for (const [method, path] of [
|
|
89
|
+
["POST", "/license/runtime/install"],
|
|
90
|
+
["POST", "/license/runtime/pairing/sessions"],
|
|
91
|
+
["GET", "/license/runtime/pairing/sessions/session_1"],
|
|
92
|
+
["POST", "/license/runtime/pairing/sessions/session_1/confirm"],
|
|
93
|
+
]) {
|
|
94
|
+
const response = await fixture.request(path!, method!);
|
|
95
|
+
expect(response.status).toBe(403);
|
|
96
|
+
expect(await response.json()).toMatchObject({
|
|
97
|
+
reason: "missing-permission",
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
const context = await fixture.runtime.createGuardContext(
|
|
101
|
+
new Request("http://localhost/"),
|
|
102
|
+
);
|
|
103
|
+
expect(
|
|
104
|
+
(
|
|
105
|
+
await fixture.authorizer.authorize(
|
|
106
|
+
context,
|
|
107
|
+
"GET",
|
|
108
|
+
"/api/system/licenses",
|
|
109
|
+
)
|
|
110
|
+
)?.status,
|
|
111
|
+
).toBe(403);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test("维护人员保留详情,read 权限不升级为详情权限", async () => {
|
|
115
|
+
const readOnly = await createFixture({
|
|
116
|
+
permissionKeys: ["system.license.read"],
|
|
117
|
+
}).request("/license/runtime");
|
|
118
|
+
expect(await readOnly.json()).toMatchObject({ canViewDetails: false });
|
|
119
|
+
const manager = await createFixture({
|
|
120
|
+
permissionKeys: ["system.license.manage"],
|
|
121
|
+
}).request("/license/runtime");
|
|
122
|
+
expect(await manager.json()).toMatchObject({
|
|
123
|
+
canViewDetails: true,
|
|
124
|
+
machineCode: "test-machine",
|
|
125
|
+
license: { claims: { customer: { name: "测试客户" } } },
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
test.each(["expired", "missing", "invalid"] as const)(
|
|
130
|
+
"%s 状态仍可读取,业务访问保持受限",
|
|
131
|
+
async (status) => {
|
|
132
|
+
const fixture = createFixture({ status });
|
|
133
|
+
const response = await fixture.request("/license/runtime");
|
|
134
|
+
expect(response.status).toBe(200);
|
|
135
|
+
expect(await response.json()).toMatchObject({
|
|
136
|
+
status,
|
|
137
|
+
restricted: true,
|
|
138
|
+
canViewDetails: false,
|
|
139
|
+
});
|
|
140
|
+
const context = await fixture.runtime.createGuardContext(
|
|
141
|
+
new Request("http://localhost/"),
|
|
142
|
+
);
|
|
143
|
+
expect(
|
|
144
|
+
(
|
|
145
|
+
await evaluateRouteGuards(fixture.runtime, context, {
|
|
146
|
+
permission: {
|
|
147
|
+
method: "GET",
|
|
148
|
+
path: "/api/cases",
|
|
149
|
+
permissionKey: "case.read",
|
|
150
|
+
},
|
|
151
|
+
})
|
|
152
|
+
).reason,
|
|
153
|
+
).toBe("license-restricted");
|
|
154
|
+
expect(
|
|
155
|
+
evaluateRestrictedHttpRequest(
|
|
156
|
+
context,
|
|
157
|
+
new Request("http://localhost/api/cases"),
|
|
158
|
+
).allowed,
|
|
159
|
+
).toBe(false);
|
|
160
|
+
expect(
|
|
161
|
+
(await fixture.request("/license/runtime/install", "POST")).status,
|
|
162
|
+
).toBe(403);
|
|
163
|
+
},
|
|
164
|
+
);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
function createFixture(
|
|
168
|
+
options: {
|
|
169
|
+
actorType?: "user" | "anonymous" | "service";
|
|
170
|
+
permissionKeys?: string[];
|
|
171
|
+
licenseFeatureEnabled?: boolean;
|
|
172
|
+
status?: "expired" | "missing" | "invalid";
|
|
173
|
+
} = {},
|
|
174
|
+
) {
|
|
175
|
+
const { privateKey, publicKey } = generateKeyPairSync("ed25519");
|
|
176
|
+
const unsigned = {
|
|
177
|
+
formatVersion: 1,
|
|
178
|
+
algorithm: "ED25519",
|
|
179
|
+
publicKeyId: "test-key",
|
|
180
|
+
claims: {
|
|
181
|
+
licenseId: "test-license",
|
|
182
|
+
productCode: "windy-platform",
|
|
183
|
+
machineCode: "test-machine",
|
|
184
|
+
customer: { id: "customer", code: "C", name: "测试客户" },
|
|
185
|
+
project: { id: "project", code: "P", name: "测试项目" },
|
|
186
|
+
contract: { id: "contract", contractNumber: "TEST", version: "1" },
|
|
187
|
+
issuedAt: "2026-07-01T00:00:00.000Z",
|
|
188
|
+
expiresAt:
|
|
189
|
+
options.status === "expired"
|
|
190
|
+
? "2026-07-31T00:00:00.000Z"
|
|
191
|
+
: "2030-08-01T00:00:00.000Z",
|
|
192
|
+
licenseVersion: { key: licenseVersionKey("advanced"), name: "高级版" },
|
|
193
|
+
},
|
|
194
|
+
} as const;
|
|
195
|
+
const license: SignedLicenseV1 = {
|
|
196
|
+
...unsigned,
|
|
197
|
+
signature: sign(
|
|
198
|
+
null,
|
|
199
|
+
Buffer.from(createLicenseSigningPayload(unsigned)),
|
|
200
|
+
privateKey,
|
|
201
|
+
).toString("base64"),
|
|
202
|
+
};
|
|
203
|
+
const licenseRuntime = new PlatformLicenseRuntime({
|
|
204
|
+
productCode: "windy-platform",
|
|
205
|
+
machineCode: "test-machine",
|
|
206
|
+
publicKeys: {
|
|
207
|
+
"test-key": publicKey.export({ type: "spki", format: "pem" }).toString(),
|
|
208
|
+
},
|
|
209
|
+
store: new MemoryAtomicLicenseStore(
|
|
210
|
+
options.status === "missing"
|
|
211
|
+
? undefined
|
|
212
|
+
: options.status === "invalid"
|
|
213
|
+
? "{broken"
|
|
214
|
+
: JSON.stringify(license),
|
|
215
|
+
),
|
|
216
|
+
enforceRestrictions: true,
|
|
217
|
+
now: () => new Date("2026-08-01T00:00:00.000Z"),
|
|
218
|
+
});
|
|
219
|
+
const { features } = createFoundationSnapshot();
|
|
220
|
+
const runtime = createServerRuntime(
|
|
221
|
+
{},
|
|
222
|
+
{
|
|
223
|
+
actorResolver: {
|
|
224
|
+
resolve: () => ({
|
|
225
|
+
id: "business-user",
|
|
226
|
+
type: options.actorType ?? "user",
|
|
227
|
+
name: "业务用户",
|
|
228
|
+
roleCodes: ["officer"],
|
|
229
|
+
permissionKeys: options.permissionKeys ?? businessPermissions,
|
|
230
|
+
}),
|
|
231
|
+
},
|
|
232
|
+
licenseResolver: licenseRuntime,
|
|
233
|
+
featureCatalog: features,
|
|
234
|
+
featureResolver: {
|
|
235
|
+
resolve: (key) => ({
|
|
236
|
+
key,
|
|
237
|
+
enabled:
|
|
238
|
+
key !== "system.license" || options.licenseFeatureEnabled !== false,
|
|
239
|
+
visible: "visible",
|
|
240
|
+
}),
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
);
|
|
244
|
+
const authorizer = createStaticRouteAuthorizer(runtime, loadSystemModules());
|
|
245
|
+
const app = new Elysia({ prefix: "/api" })
|
|
246
|
+
.derive(async ({ request }) => ({
|
|
247
|
+
guardContext: await runtime.createGuardContext(request),
|
|
248
|
+
}))
|
|
249
|
+
.onBeforeHandle(({ request, guardContext }) => {
|
|
250
|
+
if (!evaluateRestrictedHttpRequest(guardContext, request).allowed)
|
|
251
|
+
return licenseRestrictedResponse(guardContext);
|
|
252
|
+
});
|
|
253
|
+
registerPlatformLicenseRoutes(app, licenseRuntime, authorizer);
|
|
254
|
+
return {
|
|
255
|
+
runtime,
|
|
256
|
+
authorizer,
|
|
257
|
+
features,
|
|
258
|
+
request: (path: string, method = "GET") =>
|
|
259
|
+
app.handle(new Request(`http://localhost/api${path}`, { method })),
|
|
260
|
+
};
|
|
261
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import type { AiRuntimeSwitches } from "@southwind-ai/shared";
|
|
2
|
+
import { DocumentRunFacade } from "../document/facade.js";
|
|
3
|
+
import {
|
|
4
|
+
RemoteDocumentRuntime,
|
|
5
|
+
unavailableDocumentRuntime,
|
|
6
|
+
} from "../document/remote-runtime.js";
|
|
7
|
+
import { registerDocumentRunRoutes } from "../document/routes.js";
|
|
8
|
+
import { createDocumentOutputRuntime } from "../document/output-artifact-composition.js";
|
|
9
|
+
import { installDocumentOutputRuntimeRoutes } from "../document/output-artifact-route-composition.js";
|
|
10
|
+
import { EmbeddingFacade } from "../embedding/facade.js";
|
|
11
|
+
import { EmbeddingRunAuthorizations } from "../embedding/run-authorization.js";
|
|
12
|
+
import { InMemoryEmbeddingRunBindingRepository } from "../embedding/run-binding-repository.js";
|
|
13
|
+
import { DrizzleEmbeddingRunBindingRepository } from "../embedding/drizzle-run-binding-repository.js";
|
|
14
|
+
import {
|
|
15
|
+
RemoteEmbeddingRuntime,
|
|
16
|
+
unavailableEmbeddingRuntime,
|
|
17
|
+
} from "../embedding/remote-runtime.js";
|
|
18
|
+
import {
|
|
19
|
+
registerEmbeddingRoutes,
|
|
20
|
+
registerEmbeddingRunArtifactRoutes,
|
|
21
|
+
} from "../embedding/routes.js";
|
|
22
|
+
import { SpeechRunFacade } from "../speech/facade.js";
|
|
23
|
+
import {
|
|
24
|
+
RemoteSpeechRuntime,
|
|
25
|
+
unavailableSpeechRuntime,
|
|
26
|
+
} from "../speech/remote-runtime.js";
|
|
27
|
+
import { registerSpeechRunRoutes } from "../speech/routes.js";
|
|
28
|
+
|
|
29
|
+
export function connectMediaRuntimes(
|
|
30
|
+
internalToken: string,
|
|
31
|
+
switches?: AiRuntimeSwitches,
|
|
32
|
+
) {
|
|
33
|
+
const documentRemote =
|
|
34
|
+
switches?.document !== false && process.env.DOCUMENT_SERVER_URL?.trim()
|
|
35
|
+
? new RemoteDocumentRuntime({
|
|
36
|
+
baseUrl: process.env.DOCUMENT_SERVER_URL,
|
|
37
|
+
internalToken,
|
|
38
|
+
})
|
|
39
|
+
: unavailableDocumentRuntime;
|
|
40
|
+
const speechRemote =
|
|
41
|
+
switches?.speech !== false && process.env.SPEECH_SERVER_URL?.trim()
|
|
42
|
+
? new RemoteSpeechRuntime({
|
|
43
|
+
baseUrl: process.env.SPEECH_SERVER_URL,
|
|
44
|
+
internalToken,
|
|
45
|
+
})
|
|
46
|
+
: unavailableSpeechRuntime;
|
|
47
|
+
const embeddingRemote =
|
|
48
|
+
switches?.embedding !== false && process.env.EMBEDDING_SERVER_URL?.trim()
|
|
49
|
+
? new RemoteEmbeddingRuntime({
|
|
50
|
+
baseUrl: process.env.EMBEDDING_SERVER_URL,
|
|
51
|
+
internalToken,
|
|
52
|
+
})
|
|
53
|
+
: unavailableEmbeddingRuntime;
|
|
54
|
+
return { documentRemote, speechRemote, embeddingRemote };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function registerMediaRuntimes(
|
|
58
|
+
input: ReturnType<typeof connectMediaRuntimes> & {
|
|
59
|
+
switches?: AiRuntimeSwitches;
|
|
60
|
+
modules: ConstructorParameters<typeof DocumentRunFacade>[0];
|
|
61
|
+
hosts: ConstructorParameters<typeof DocumentRunFacade>[1];
|
|
62
|
+
runtime: ConstructorParameters<typeof DocumentRunFacade>[2];
|
|
63
|
+
storage: Parameters<typeof createDocumentOutputRuntime>[0]["storage"];
|
|
64
|
+
db: Parameters<typeof createDocumentOutputRuntime>[0]["db"];
|
|
65
|
+
aiReadiness: Parameters<typeof createDocumentOutputRuntime>[0]["readiness"];
|
|
66
|
+
resolveActor: Parameters<
|
|
67
|
+
typeof createDocumentOutputRuntime
|
|
68
|
+
>[0]["resolveActor"];
|
|
69
|
+
aiArtifacts: ConstructorParameters<typeof DocumentRunFacade>[4];
|
|
70
|
+
grants: ConstructorParameters<typeof DocumentRunFacade>[5];
|
|
71
|
+
aiRouteApp: Parameters<typeof registerDocumentRunRoutes>[0];
|
|
72
|
+
internalToken: string;
|
|
73
|
+
},
|
|
74
|
+
) {
|
|
75
|
+
const {
|
|
76
|
+
documentRemote,
|
|
77
|
+
speechRemote,
|
|
78
|
+
embeddingRemote,
|
|
79
|
+
aiReadiness,
|
|
80
|
+
resolveActor,
|
|
81
|
+
aiArtifacts,
|
|
82
|
+
grants,
|
|
83
|
+
aiRouteApp,
|
|
84
|
+
internalToken,
|
|
85
|
+
} = input;
|
|
86
|
+
const outputRuntime = createDocumentOutputRuntime({
|
|
87
|
+
modules: input.modules,
|
|
88
|
+
readiness: aiReadiness,
|
|
89
|
+
runtime: input.runtime,
|
|
90
|
+
storage: input.storage,
|
|
91
|
+
resolveActor,
|
|
92
|
+
db: input.db,
|
|
93
|
+
documentEnabled: input.switches?.document,
|
|
94
|
+
speechEnabled: input.switches?.speech,
|
|
95
|
+
});
|
|
96
|
+
const documentFacadeWithOutput =
|
|
97
|
+
input.switches?.document === false
|
|
98
|
+
? undefined
|
|
99
|
+
: new DocumentRunFacade(
|
|
100
|
+
input.modules,
|
|
101
|
+
input.hosts,
|
|
102
|
+
input.runtime,
|
|
103
|
+
documentRemote,
|
|
104
|
+
aiArtifacts,
|
|
105
|
+
grants,
|
|
106
|
+
outputRuntime?.host,
|
|
107
|
+
aiReadiness,
|
|
108
|
+
);
|
|
109
|
+
installDocumentOutputRuntimeRoutes(outputRuntime, aiRouteApp, internalToken);
|
|
110
|
+
if (documentFacadeWithOutput)
|
|
111
|
+
registerDocumentRunRoutes(
|
|
112
|
+
aiRouteApp,
|
|
113
|
+
documentFacadeWithOutput,
|
|
114
|
+
documentRemote,
|
|
115
|
+
);
|
|
116
|
+
const speechFacade =
|
|
117
|
+
input.switches?.speech === false
|
|
118
|
+
? undefined
|
|
119
|
+
: new SpeechRunFacade(
|
|
120
|
+
input.modules,
|
|
121
|
+
input.hosts,
|
|
122
|
+
input.runtime,
|
|
123
|
+
speechRemote,
|
|
124
|
+
aiArtifacts,
|
|
125
|
+
grants,
|
|
126
|
+
aiReadiness,
|
|
127
|
+
outputRuntime?.speechHost,
|
|
128
|
+
);
|
|
129
|
+
if (speechFacade)
|
|
130
|
+
registerSpeechRunRoutes(aiRouteApp, speechFacade, speechRemote);
|
|
131
|
+
const embeddingFacade =
|
|
132
|
+
input.switches?.embedding === false
|
|
133
|
+
? undefined
|
|
134
|
+
: new EmbeddingFacade(
|
|
135
|
+
input.modules,
|
|
136
|
+
input.hosts,
|
|
137
|
+
input.runtime,
|
|
138
|
+
embeddingRemote,
|
|
139
|
+
aiArtifacts,
|
|
140
|
+
new EmbeddingRunAuthorizations(
|
|
141
|
+
input.db
|
|
142
|
+
? new DrizzleEmbeddingRunBindingRepository(input.db)
|
|
143
|
+
: new InMemoryEmbeddingRunBindingRepository(),
|
|
144
|
+
internalToken,
|
|
145
|
+
),
|
|
146
|
+
aiReadiness,
|
|
147
|
+
);
|
|
148
|
+
if (embeddingFacade) {
|
|
149
|
+
registerEmbeddingRoutes(aiRouteApp, embeddingFacade);
|
|
150
|
+
registerEmbeddingRunArtifactRoutes(
|
|
151
|
+
aiRouteApp,
|
|
152
|
+
embeddingFacade,
|
|
153
|
+
internalToken,
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
return { documentFacadeWithOutput, speechFacade, embeddingFacade };
|
|
157
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { SystemRepositories } from "../system/seed.js";
|
|
2
|
+
import { resolveCurrentSystemActor } from "../system/actor.js";
|
|
3
|
+
import {
|
|
4
|
+
createManifestAuthorizedRouteApp,
|
|
5
|
+
createStaticRouteAuthorizer,
|
|
6
|
+
} from "../module-host/static-route-authorization.js";
|
|
7
|
+
import { requiredEnvironment } from "./required-environment.js";
|
|
8
|
+
import { composeSharedAiRuntime } from "./shared-composition.js";
|
|
9
|
+
|
|
10
|
+
type SharedInput = Parameters<typeof composeSharedAiRuntime>[0];
|
|
11
|
+
|
|
12
|
+
export function composeMediaOnlyRuntime(
|
|
13
|
+
input: Omit<
|
|
14
|
+
SharedInput,
|
|
15
|
+
"internalToken" | "secret" | "resolveActor" | "agent"
|
|
16
|
+
> & {
|
|
17
|
+
enableAI: boolean;
|
|
18
|
+
systemRepositories: SystemRepositories;
|
|
19
|
+
},
|
|
20
|
+
) {
|
|
21
|
+
if (
|
|
22
|
+
!input.enableAI ||
|
|
23
|
+
(input.switches?.document === false &&
|
|
24
|
+
input.switches.speech === false &&
|
|
25
|
+
input.switches.embedding === false)
|
|
26
|
+
)
|
|
27
|
+
return undefined;
|
|
28
|
+
|
|
29
|
+
const authorizer = createStaticRouteAuthorizer(input.runtime, input.modules);
|
|
30
|
+
const shared = composeSharedAiRuntime({
|
|
31
|
+
...input,
|
|
32
|
+
app: createManifestAuthorizedRouteApp(input.app, authorizer),
|
|
33
|
+
internalToken: requiredEnvironment("AGENT_SERVER_INTERNAL_TOKEN"),
|
|
34
|
+
secret: requiredEnvironment("AI_ARTIFACT_ENCRYPTION_SECRET"),
|
|
35
|
+
resolveActor: (actorId) =>
|
|
36
|
+
resolveCurrentSystemActor(input.systemRepositories, actorId),
|
|
37
|
+
});
|
|
38
|
+
const ports = shared.modulePorts();
|
|
39
|
+
return {
|
|
40
|
+
aiArtifacts: shared.aiArtifacts,
|
|
41
|
+
aiOperations: ports.operations,
|
|
42
|
+
aiReadiness: ports.readiness,
|
|
43
|
+
};
|
|
44
|
+
}
|