create-windy 0.9.1 → 0.10.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 +1769 -1277
- 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
|
@@ -1,6 +1,5 @@
|
|
|
1
|
+
import { invalidateActorAuthorization } from "./session-invalidation/authorization-revocation.js";
|
|
1
2
|
import type { ModuleManifest } from "@southwind-ai/modules";
|
|
2
|
-
import { agentSourceInvalidations } from "@southwind-ai/database";
|
|
3
|
-
import { and, desc, eq } from "drizzle-orm";
|
|
4
3
|
import type { NodePgDatabase } from "drizzle-orm/node-postgres";
|
|
5
4
|
import type { RequestActor } from "../guards.js";
|
|
6
5
|
import type { createServerRuntime } from "../runtime.js";
|
|
@@ -30,7 +29,6 @@ import type { AgentRunAuthorizationStore } from "./run-authorization.js";
|
|
|
30
29
|
import { AgentRunSessionBindingAuthorizer } from "./run-session-authorization.js";
|
|
31
30
|
import { DrizzleSessionAuthoritativeSourceAccess } from "./session-context-source.js";
|
|
32
31
|
import {
|
|
33
|
-
authorizationCoordinateForActor,
|
|
34
32
|
ResolvingCurrentSourceAuthorizationPort,
|
|
35
33
|
SessionProjectionSourceAuthorizer,
|
|
36
34
|
} from "./session-projection-access.js";
|
|
@@ -215,51 +213,3 @@ export function composeAgentLongSessionRuntime(input: {
|
|
|
215
213
|
},
|
|
216
214
|
};
|
|
217
215
|
}
|
|
218
|
-
|
|
219
|
-
async function invalidateActorAuthorization(
|
|
220
|
-
input: AgentAuthorizationInvalidationInput,
|
|
221
|
-
sources: ModuleAuthoritativeSourceAccessRegistry,
|
|
222
|
-
outbox: DrizzleSessionInvalidationOutbox,
|
|
223
|
-
) {
|
|
224
|
-
const authorization = authorizationCoordinateForActor(input.previousActor);
|
|
225
|
-
const sourceKind = "authorization-scope";
|
|
226
|
-
const [latest] = await input.database
|
|
227
|
-
.select({ sequence: agentSourceInvalidations.sequence })
|
|
228
|
-
.from(agentSourceInvalidations)
|
|
229
|
-
.where(
|
|
230
|
-
and(
|
|
231
|
-
eq(agentSourceInvalidations.sourceModuleKey, "system.agent"),
|
|
232
|
-
eq(agentSourceInvalidations.sourceKind, sourceKind),
|
|
233
|
-
eq(agentSourceInvalidations.sourceId, authorization.actorId),
|
|
234
|
-
),
|
|
235
|
-
)
|
|
236
|
-
.orderBy(desc(agentSourceInvalidations.sequence))
|
|
237
|
-
.limit(1);
|
|
238
|
-
const occurredAt = Date.parse(input.occurredAt);
|
|
239
|
-
if (!Number.isSafeInteger(occurredAt) || occurredAt < 1) {
|
|
240
|
-
throw new Error("Agent 授权失效时间坐标无效");
|
|
241
|
-
}
|
|
242
|
-
const sequence = Math.max(occurredAt, (latest?.sequence ?? 0) + 1);
|
|
243
|
-
const producer = sources.bindInvalidationProducer({
|
|
244
|
-
moduleKey: "system.agent",
|
|
245
|
-
authorization,
|
|
246
|
-
append: {
|
|
247
|
-
append: (envelope) =>
|
|
248
|
-
outbox.appendInTransaction(input.database, envelope),
|
|
249
|
-
},
|
|
250
|
-
});
|
|
251
|
-
const result = await producer.authorizationRevoked({
|
|
252
|
-
source: {
|
|
253
|
-
sourceKind,
|
|
254
|
-
sourceId: authorization.actorId,
|
|
255
|
-
version: authorization.scopeDigest,
|
|
256
|
-
sequence,
|
|
257
|
-
},
|
|
258
|
-
event: {
|
|
259
|
-
eventId: input.eventId,
|
|
260
|
-
eventSequence: sequence,
|
|
261
|
-
occurredAt: input.occurredAt,
|
|
262
|
-
},
|
|
263
|
-
});
|
|
264
|
-
if (result === "stale") throw new Error("Agent 授权失效序列未收敛");
|
|
265
|
-
}
|
|
@@ -63,8 +63,19 @@ const unavailableRoutes = [
|
|
|
63
63
|
["GET", "/system/ai-runtime/actors"],
|
|
64
64
|
] as const;
|
|
65
65
|
|
|
66
|
-
export function registerUnavailableAiRoutes(
|
|
67
|
-
|
|
66
|
+
export function registerUnavailableAiRoutes(
|
|
67
|
+
app: RouteApp,
|
|
68
|
+
options?: { mediaAvailable: boolean },
|
|
69
|
+
): void {
|
|
70
|
+
const routes = options?.mediaAvailable
|
|
71
|
+
? unavailableRoutes.filter(
|
|
72
|
+
([, path]) =>
|
|
73
|
+
path.startsWith("/agent/") ||
|
|
74
|
+
path.startsWith("/internal/agent/") ||
|
|
75
|
+
path.startsWith("/system/ai-runtime/"),
|
|
76
|
+
)
|
|
77
|
+
: unavailableRoutes;
|
|
78
|
+
registerUnavailableRoutes(app, routes, "AI Runtime 未启用");
|
|
68
79
|
registerUnavailableRoutes(
|
|
69
80
|
app,
|
|
70
81
|
longSessionUnavailableRoutes,
|
|
@@ -98,6 +98,7 @@ export function composeProductionAgentWorkflowRuntime(input: {
|
|
|
98
98
|
)
|
|
99
99
|
return undefined;
|
|
100
100
|
const resolveActor = input.resolveActor;
|
|
101
|
+
const agentFacade = input.agentFacade;
|
|
101
102
|
const repository = new DrizzleAgentWorkflowRepository(input.db);
|
|
102
103
|
const effectFence = new DrizzleWorkflowEffectCommandFence(input.db);
|
|
103
104
|
const budgetLedger = new DrizzleWorkflowBudgetLedger(input.db);
|
|
@@ -105,6 +106,8 @@ export function composeProductionAgentWorkflowRuntime(input: {
|
|
|
105
106
|
repository,
|
|
106
107
|
effectFence,
|
|
107
108
|
budgetLedger,
|
|
109
|
+
(operationKey) =>
|
|
110
|
+
agentFacade.operationPolicy(operationKey)?.release?.promptVersion,
|
|
108
111
|
);
|
|
109
112
|
const query = new AgentWorkflowQueryService(repository);
|
|
110
113
|
const waitSignals = new AgentWorkflowWaitSignalService(repository);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AgentWorkflowCommandError } from "./command-error.js";
|
|
1
2
|
import {
|
|
2
3
|
budgetFitsWithin,
|
|
3
4
|
type AgentWorkflowArtifactRef,
|
|
@@ -74,10 +75,25 @@ export class AgentWorkflowService {
|
|
|
74
75
|
private readonly repository: AgentWorkflowRepository,
|
|
75
76
|
private readonly effectFence: WorkflowEffectCommandFencePort,
|
|
76
77
|
private readonly budgetLedger: WorkflowBudgetLedgerPort,
|
|
78
|
+
private readonly resolvePromptVersion?: (
|
|
79
|
+
operationKey: string,
|
|
80
|
+
) => string | undefined,
|
|
77
81
|
) {}
|
|
78
82
|
|
|
79
83
|
publish(input: PublishAgentWorkflowReleaseInput) {
|
|
80
|
-
|
|
84
|
+
const release = buildAgentWorkflowRelease(input);
|
|
85
|
+
for (const node of release.definition.nodes) {
|
|
86
|
+
if (
|
|
87
|
+
node.type === "model" &&
|
|
88
|
+
this.resolvePromptVersion?.(node.operationKey) !== node.promptKey
|
|
89
|
+
) {
|
|
90
|
+
throw new AgentWorkflowCommandError(
|
|
91
|
+
"MODEL_PROMPT_RELEASE_MISMATCH",
|
|
92
|
+
400,
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return this.repository.publishRelease(release);
|
|
81
97
|
}
|
|
82
98
|
|
|
83
99
|
async createRun(input: CreateAgentWorkflowRunRequest) {
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { systemModuleManifest } from "@southwind-ai/modules";
|
|
3
|
+
import { expect, test } from "bun:test";
|
|
4
|
+
import { initializeModuleHosts } from "../module-host/initialize.js";
|
|
5
|
+
import {
|
|
6
|
+
restartActor,
|
|
7
|
+
restartModuleManifest,
|
|
8
|
+
restartUploadPolicy,
|
|
9
|
+
} from "../module-host/storage-restart-fixture.test-support.js";
|
|
10
|
+
import { createServerRuntime } from "../runtime.js";
|
|
11
|
+
import { createStorageRuntime } from "../storage/runtime.js";
|
|
12
|
+
import { createPlatformHttpApp } from "../http-app.js";
|
|
13
|
+
import {
|
|
14
|
+
createManifestAuthorizedRouteApp,
|
|
15
|
+
createStaticRouteAuthorizer,
|
|
16
|
+
} from "../module-host/static-route-authorization.js";
|
|
17
|
+
import { createPlatformObservability } from "../observability/bootstrap.js";
|
|
18
|
+
import { AiArtifactCodec } from "./codec.js";
|
|
19
|
+
import { registerAiArtifactRoutes } from "./routes.js";
|
|
20
|
+
import { AiArtifactRuntime } from "./runtime.js";
|
|
21
|
+
|
|
22
|
+
test("关闭 Agent 后媒体 Artifact 仍读取受授权的上传文件,并在撤权后拒绝", async () => {
|
|
23
|
+
const actor = restartActor();
|
|
24
|
+
const manifest = {
|
|
25
|
+
...restartModuleManifest,
|
|
26
|
+
apiPermissions: [],
|
|
27
|
+
tasks: [],
|
|
28
|
+
auditActions: [...restartModuleManifest.auditActions, "evidence.file.read"],
|
|
29
|
+
};
|
|
30
|
+
let active = true;
|
|
31
|
+
const hosts = await initializeModuleHosts({
|
|
32
|
+
modules: [manifest],
|
|
33
|
+
installations: [
|
|
34
|
+
{
|
|
35
|
+
manifest,
|
|
36
|
+
setup(host) {
|
|
37
|
+
host.registerUploadPolicy(restartUploadPolicy);
|
|
38
|
+
host.registerResourceFileAccessPolicies([
|
|
39
|
+
{
|
|
40
|
+
purpose: restartUploadPolicy.purpose,
|
|
41
|
+
resourceType: "evidence.document",
|
|
42
|
+
featureKey: "evidence.generate",
|
|
43
|
+
permissionKey: "evidence.generate.manage",
|
|
44
|
+
auditAction: "evidence.file.read",
|
|
45
|
+
authorize: () => active,
|
|
46
|
+
},
|
|
47
|
+
]);
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
});
|
|
52
|
+
const storage = createStorageRuntime({}, undefined, [restartUploadPolicy]);
|
|
53
|
+
const bytes = new TextEncoder().encode("synthetic OCR input");
|
|
54
|
+
const sha256 = createHash("sha256").update(bytes).digest("hex");
|
|
55
|
+
const session = await storage.uploads.create({
|
|
56
|
+
ownerId: actor.id,
|
|
57
|
+
purpose: restartUploadPolicy.purpose,
|
|
58
|
+
filename: "fixture.txt",
|
|
59
|
+
mimeType: "text/plain",
|
|
60
|
+
expectedByteSize: bytes.byteLength,
|
|
61
|
+
});
|
|
62
|
+
await storage.uploads.appendPart({
|
|
63
|
+
sessionId: session.id,
|
|
64
|
+
ownerId: actor.id,
|
|
65
|
+
partNumber: 0,
|
|
66
|
+
byteOffset: 0,
|
|
67
|
+
byteSize: bytes.byteLength,
|
|
68
|
+
sha256,
|
|
69
|
+
body: new Blob([bytes]).stream(),
|
|
70
|
+
});
|
|
71
|
+
const file = await storage.uploads.complete(session.id, actor.id);
|
|
72
|
+
const modules = [manifest, systemModuleManifest("system.media-runtime")];
|
|
73
|
+
const features = modules.flatMap((module) => module.features);
|
|
74
|
+
const runtime = createServerRuntime(
|
|
75
|
+
{ NODE_ENV: "test" },
|
|
76
|
+
{
|
|
77
|
+
featureCatalog: features,
|
|
78
|
+
disabledFeatureKeys: new Set(["system.agent"]),
|
|
79
|
+
licenseEnforced: false,
|
|
80
|
+
},
|
|
81
|
+
);
|
|
82
|
+
const request = new Request("http://localhost/api/evidence");
|
|
83
|
+
const context = await runtime.createGuardContextForActor(request, actor);
|
|
84
|
+
const artifacts = new AiArtifactRuntime(
|
|
85
|
+
new AiArtifactCodec("test-media-secret".repeat(3)),
|
|
86
|
+
hosts,
|
|
87
|
+
runtime,
|
|
88
|
+
features,
|
|
89
|
+
storage,
|
|
90
|
+
async () => actor,
|
|
91
|
+
);
|
|
92
|
+
const reference = await artifacts
|
|
93
|
+
.createModulePort(manifest.name, context, request.signal)
|
|
94
|
+
.issue({
|
|
95
|
+
fileId: file.id,
|
|
96
|
+
purpose: restartUploadPolicy.purpose,
|
|
97
|
+
resourceType: "evidence.document",
|
|
98
|
+
resourceId: "synthetic",
|
|
99
|
+
});
|
|
100
|
+
const app = createPlatformHttpApp(
|
|
101
|
+
runtime,
|
|
102
|
+
createPlatformObservability({
|
|
103
|
+
databaseRequired: false,
|
|
104
|
+
auditStatus: () => runtime.auditSink.status(),
|
|
105
|
+
logger: { info() {} },
|
|
106
|
+
}),
|
|
107
|
+
);
|
|
108
|
+
registerAiArtifactRoutes(
|
|
109
|
+
createManifestAuthorizedRouteApp(
|
|
110
|
+
app,
|
|
111
|
+
createStaticRouteAuthorizer(runtime, modules),
|
|
112
|
+
),
|
|
113
|
+
artifacts,
|
|
114
|
+
"internal-test-token",
|
|
115
|
+
);
|
|
116
|
+
const open = (token: string) =>
|
|
117
|
+
app.handle(
|
|
118
|
+
new Request("http://localhost/api/internal/ai/artifacts", {
|
|
119
|
+
headers: {
|
|
120
|
+
authorization: `Bearer ${token}`,
|
|
121
|
+
"x-ai-artifact-ref": reference.value,
|
|
122
|
+
},
|
|
123
|
+
}),
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
expect((await open("wrong-token")).status).toBe(403);
|
|
127
|
+
const opened = await open("internal-test-token");
|
|
128
|
+
expect(opened.status).toBe(200);
|
|
129
|
+
expect(opened.headers.get("x-content-sha256")).toBe(sha256);
|
|
130
|
+
expect(new Uint8Array(await opened.arrayBuffer())).toEqual(bytes);
|
|
131
|
+
|
|
132
|
+
active = false;
|
|
133
|
+
expect((await open("internal-test-token")).status).toBe(404);
|
|
134
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { RouteApp } from "../system/route-types.js";
|
|
2
|
-
import { validInternalToken } from "../
|
|
2
|
+
import { validInternalToken } from "../ai-runtime-security/internal-token.js";
|
|
3
3
|
import type { AiArtifactRuntime } from "./runtime.js";
|
|
4
4
|
|
|
5
5
|
interface RouteContext {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { evaluateFeatureGuard } from "../guards.js";
|
|
1
2
|
import {
|
|
2
3
|
ModuleAiArtifactError,
|
|
3
4
|
type ModuleAiArtifactPort,
|
|
@@ -251,6 +252,17 @@ export class AiArtifactRuntime {
|
|
|
251
252
|
request,
|
|
252
253
|
actor,
|
|
253
254
|
);
|
|
255
|
+
if (claims.source.resourceType === "agent-screenshot") {
|
|
256
|
+
const agent = this.features.find(({ key }) => key === "system.agent");
|
|
257
|
+
if (
|
|
258
|
+
!agent ||
|
|
259
|
+
!evaluateFeatureGuard(
|
|
260
|
+
guardContext,
|
|
261
|
+
await this.runtime.resolveFeature(guardContext, agent),
|
|
262
|
+
).allowed
|
|
263
|
+
)
|
|
264
|
+
throw forbidden();
|
|
265
|
+
}
|
|
254
266
|
const opened =
|
|
255
267
|
claims.source.resourceType === "agent-screenshot"
|
|
256
268
|
? await openedScreenshot(
|
|
@@ -66,7 +66,7 @@ export function degradedSnapshot(capabilities = ["document.ocr"]) {
|
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
function readinessManifest(): ModuleManifest {
|
|
69
|
+
export function readinessManifest(): ModuleManifest {
|
|
70
70
|
const manifest = documentManifest();
|
|
71
71
|
const operation = manifest.aiOperations?.[0];
|
|
72
72
|
if (!operation) throw new Error("测试 Manifest 缺少 Operation");
|
|
@@ -32,6 +32,7 @@ export function createModuleAiOperationReadinessPort(input: {
|
|
|
32
32
|
readonly now?: () => Date;
|
|
33
33
|
/** Tests may shorten the bound; production defaults to five seconds. */
|
|
34
34
|
readonly probeTimeoutMs?: number;
|
|
35
|
+
readonly runtimeAllowed?: (kind: AiRuntimeKindV1) => Promise<boolean>;
|
|
35
36
|
readonly trustStore?: AiRuntimeReadinessTrustStoreV1;
|
|
36
37
|
}): ModuleAiOperationReadinessPortV1 {
|
|
37
38
|
const operations = new Map(
|
|
@@ -92,6 +93,13 @@ export function createModuleAiOperationReadinessPort(input: {
|
|
|
92
93
|
"RUNTIME_NOT_CONFIGURED",
|
|
93
94
|
);
|
|
94
95
|
}
|
|
96
|
+
if (input.runtimeAllowed && !(await input.runtimeAllowed(operation.kind)))
|
|
97
|
+
return unavailable(
|
|
98
|
+
operationKey,
|
|
99
|
+
operation.kind,
|
|
100
|
+
now(),
|
|
101
|
+
"RUNTIME_NOT_CONFIGURED",
|
|
102
|
+
);
|
|
95
103
|
const deadlineController = new AbortController();
|
|
96
104
|
const deadline = setTimeout(
|
|
97
105
|
() => deadlineController.abort("ai-runtime-health-deadline"),
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { timingSafeEqual } from "node:crypto";
|
|
2
|
+
|
|
3
|
+
export function validInternalToken(
|
|
4
|
+
request: Request,
|
|
5
|
+
expected: string,
|
|
6
|
+
): boolean {
|
|
7
|
+
const provided = request.headers
|
|
8
|
+
.get("authorization")
|
|
9
|
+
?.replace(/^Bearer /, "");
|
|
10
|
+
if (!provided || !expected) return false;
|
|
11
|
+
const left = Buffer.from(provided);
|
|
12
|
+
const right = Buffer.from(expected);
|
|
13
|
+
return left.length === right.length && timingSafeEqual(left, right);
|
|
14
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { expect, test } from "bun:test";
|
|
2
|
+
import { parseEnvironmentPolicy } from "@southwind-ai/shared";
|
|
3
|
+
import { configureProjectAntivirus } from "./antivirus-composition.js";
|
|
4
|
+
|
|
5
|
+
test("病毒扫描必须已交付且实际就绪", async () => {
|
|
6
|
+
const base = { schemaVersion: 1, build: { modules: [] }, features: [] };
|
|
7
|
+
expect(() =>
|
|
8
|
+
parseEnvironmentPolicy({
|
|
9
|
+
...base,
|
|
10
|
+
antivirus: { packaged: false, enabled: true },
|
|
11
|
+
}),
|
|
12
|
+
).toThrow("病毒扫描未随项目交付");
|
|
13
|
+
const { antivirus } = parseEnvironmentPolicy({
|
|
14
|
+
...base,
|
|
15
|
+
antivirus: { packaged: true, enabled: true },
|
|
16
|
+
});
|
|
17
|
+
await expect(configureProjectAntivirus(antivirus)).rejects.toThrow(
|
|
18
|
+
"项目未装配扫描器",
|
|
19
|
+
);
|
|
20
|
+
await expect(
|
|
21
|
+
configureProjectAntivirus(antivirus, {
|
|
22
|
+
packaged: true,
|
|
23
|
+
configure: async () => "disabled",
|
|
24
|
+
}),
|
|
25
|
+
).rejects.toThrow("未达到环境预设要求");
|
|
26
|
+
await configureProjectAntivirus(antivirus, {
|
|
27
|
+
packaged: true,
|
|
28
|
+
async configure(mode) {
|
|
29
|
+
expect(mode).toBe("required");
|
|
30
|
+
return "ready";
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test("关闭扫描仍显式通知已交付的扫描执行器", async () => {
|
|
36
|
+
await configureProjectAntivirus(
|
|
37
|
+
{ packaged: true, enabled: false },
|
|
38
|
+
{
|
|
39
|
+
packaged: true,
|
|
40
|
+
async configure(mode) {
|
|
41
|
+
expect(mode).toBe("disabled");
|
|
42
|
+
return "disabled";
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test("扫描交付声明与项目装配不一致时拒绝启动", async () => {
|
|
49
|
+
let configured = false;
|
|
50
|
+
await expect(
|
|
51
|
+
configureProjectAntivirus(
|
|
52
|
+
{ packaged: false, enabled: false },
|
|
53
|
+
{
|
|
54
|
+
packaged: true,
|
|
55
|
+
async configure() {
|
|
56
|
+
configured = true;
|
|
57
|
+
return "disabled";
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
),
|
|
61
|
+
).rejects.toThrow("项目已装配扫描器");
|
|
62
|
+
expect(configured).toBe(false);
|
|
63
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { AntivirusEnvironmentPolicy } from "@southwind-ai/shared";
|
|
2
|
+
|
|
3
|
+
export interface ProjectAntivirusBinding {
|
|
4
|
+
readonly packaged: boolean;
|
|
5
|
+
configure(mode: "disabled" | "required"): Promise<"disabled" | "ready">;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// Project composition supplies the scanner wired to its protected ingestion path.
|
|
9
|
+
const projectAntivirusBinding: ProjectAntivirusBinding | undefined = undefined;
|
|
10
|
+
|
|
11
|
+
export async function configureProjectAntivirus(
|
|
12
|
+
policy: AntivirusEnvironmentPolicy | undefined,
|
|
13
|
+
binding: ProjectAntivirusBinding | undefined = projectAntivirusBinding,
|
|
14
|
+
): Promise<void> {
|
|
15
|
+
if (!policy) return;
|
|
16
|
+
if (policy.enabled && !policy.packaged)
|
|
17
|
+
throw new Error("病毒扫描未随项目交付,不能启用");
|
|
18
|
+
if (policy.packaged && !binding?.packaged)
|
|
19
|
+
throw new Error("环境预设声明了病毒扫描交付,但项目未装配扫描器");
|
|
20
|
+
if (!policy.packaged && binding?.packaged)
|
|
21
|
+
throw new Error("环境预设声明未交付病毒扫描,但项目已装配扫描器");
|
|
22
|
+
if (!binding?.packaged) return;
|
|
23
|
+
const state = await binding.configure(
|
|
24
|
+
policy.enabled ? "required" : "disabled",
|
|
25
|
+
);
|
|
26
|
+
if (state !== (policy.enabled ? "ready" : "disabled")) {
|
|
27
|
+
throw new Error("项目病毒扫描器未达到环境预设要求的状态");
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -9,7 +9,8 @@ function opened(socket: WebSocket): Promise<void> {
|
|
|
9
9
|
clearTimeout(timer);
|
|
10
10
|
resolve();
|
|
11
11
|
});
|
|
12
|
-
|
|
12
|
+
// Bun can emit another error while tearing down a rejected upgrade.
|
|
13
|
+
socket.on("error", () => {
|
|
13
14
|
clearTimeout(timer);
|
|
14
15
|
reject(new Error("Socket rejected"));
|
|
15
16
|
});
|
|
@@ -93,9 +93,9 @@ export class PlatformConfigApplyAdapter {
|
|
|
93
93
|
{
|
|
94
94
|
path: "enableAI",
|
|
95
95
|
label: "AI 能力总开关",
|
|
96
|
-
description: "控制
|
|
96
|
+
description: "控制 AI 与 Agent 服务的装配。",
|
|
97
97
|
input: "boolean",
|
|
98
|
-
applyMode: "
|
|
98
|
+
applyMode: "restart",
|
|
99
99
|
},
|
|
100
100
|
{
|
|
101
101
|
path: "cache.healthTimeoutMs",
|
|
@@ -134,13 +134,16 @@ export class PlatformConfigApplyAdapter {
|
|
|
134
134
|
1024,
|
|
135
135
|
10 * 1024 ** 3,
|
|
136
136
|
),
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
137
|
+
{
|
|
138
|
+
...integerField(
|
|
139
|
+
"storage.brandingLogoMaxByteSize",
|
|
140
|
+
"品牌 Logo 上传上限",
|
|
141
|
+
"限制单个 Logo 文件的大小,控制上传流量和存储占用。",
|
|
142
|
+
1024,
|
|
143
|
+
50 * 1024 ** 2,
|
|
144
|
+
),
|
|
145
|
+
unit: "bytes",
|
|
146
|
+
},
|
|
144
147
|
restartBooleanField(
|
|
145
148
|
"mail.enabled",
|
|
146
149
|
"启用邮件传输配置",
|
|
@@ -174,8 +177,9 @@ export class PlatformConfigApplyAdapter {
|
|
|
174
177
|
{
|
|
175
178
|
path: "regional.timeZone",
|
|
176
179
|
label: "显示时区",
|
|
177
|
-
description:
|
|
178
|
-
|
|
180
|
+
description:
|
|
181
|
+
"用于显示平台日期和时间。下拉选项显示当前 UTC 偏移,偏移可能随夏令时变化。",
|
|
182
|
+
input: "time-zone",
|
|
179
183
|
applyMode: "live",
|
|
180
184
|
},
|
|
181
185
|
],
|
|
@@ -15,11 +15,11 @@ import type { createServerRuntime } from "../runtime.js";
|
|
|
15
15
|
import {
|
|
16
16
|
governProviderInput,
|
|
17
17
|
ProviderInputGovernanceError,
|
|
18
|
-
} from "../
|
|
18
|
+
} from "../ai-runtime-security/provider-input-governance.js";
|
|
19
19
|
import {
|
|
20
20
|
ExecutionGrantStore,
|
|
21
21
|
type ExecutionGrant,
|
|
22
|
-
} from "../
|
|
22
|
+
} from "../ai-runtime-security/execution-grants.js";
|
|
23
23
|
import { DocumentRuntimeError } from "./contracts.js";
|
|
24
24
|
import type { DocumentRuntimePort } from "./contracts.js";
|
|
25
25
|
import { DocumentFacadeError } from "./errors.js";
|
|
@@ -10,8 +10,8 @@ import type {
|
|
|
10
10
|
} from "@southwind-ai/server-sdk";
|
|
11
11
|
import { evaluateAccessGuards } from "../access-guards.js";
|
|
12
12
|
import type { AiArtifactRuntime } from "../ai-artifact/runtime.js";
|
|
13
|
-
import { ExecutionGrantStore } from "../
|
|
14
|
-
import { scopedRuntimeIdempotencyKey } from "../
|
|
13
|
+
import { ExecutionGrantStore } from "../ai-runtime-security/execution-grants.js";
|
|
14
|
+
import { scopedRuntimeIdempotencyKey } from "../ai-runtime-security/idempotency-key.js";
|
|
15
15
|
import type { RequestGuardContext } from "../guards.js";
|
|
16
16
|
import type { InitializedModuleHosts } from "../module-host.js";
|
|
17
17
|
import { toModuleActor } from "../module-host.js";
|
|
@@ -15,16 +15,20 @@ export function createDocumentOutputRuntime(input: {
|
|
|
15
15
|
storage: ReturnType<typeof createStorageRuntime>;
|
|
16
16
|
resolveActor: (actorId: string) => Promise<RequestActor | undefined>;
|
|
17
17
|
db?: NodePgDatabase;
|
|
18
|
+
documentEnabled?: boolean;
|
|
19
|
+
speechEnabled?: boolean;
|
|
18
20
|
}) {
|
|
19
21
|
const referenceSecret =
|
|
20
22
|
process.env.AI_OUTPUT_ARTIFACT_REFERENCE_SECRET?.trim();
|
|
21
23
|
const identity = process.env.DOCUMENT_OUTPUT_ARTIFACT_SINK_IDENTITY?.trim();
|
|
22
24
|
const releaseDigest =
|
|
23
25
|
process.env.DOCUMENT_OUTPUT_ARTIFACT_SINK_RELEASE_DIGEST?.trim();
|
|
26
|
+
const bindings =
|
|
27
|
+
input.documentEnabled === false ? [] : documentOutputArtifactBindings;
|
|
28
|
+
const speechBindings =
|
|
29
|
+
input.speechEnabled === false ? [] : speechOutputArtifactBindings;
|
|
24
30
|
const composition = {
|
|
25
|
-
bindingCount:
|
|
26
|
-
documentOutputArtifactBindings.length +
|
|
27
|
-
speechOutputArtifactBindings.length,
|
|
31
|
+
bindingCount: bindings.length + speechBindings.length,
|
|
28
32
|
db: input.db,
|
|
29
33
|
referenceSecret,
|
|
30
34
|
sinkIdentity: identity,
|
|
@@ -33,8 +37,8 @@ export function createDocumentOutputRuntime(input: {
|
|
|
33
37
|
if (!documentOutputCompositionReady(composition)) return undefined;
|
|
34
38
|
return createDocumentOutputArtifactRuntime({
|
|
35
39
|
modules: input.modules,
|
|
36
|
-
bindings
|
|
37
|
-
speechBindings
|
|
40
|
+
bindings,
|
|
41
|
+
speechBindings,
|
|
38
42
|
readiness: input.readiness,
|
|
39
43
|
runtime: input.runtime,
|
|
40
44
|
storage: input.storage,
|
|
@@ -4,7 +4,7 @@ import type {
|
|
|
4
4
|
ModuleAiOperationReadyV1,
|
|
5
5
|
} from "@southwind-ai/server-sdk";
|
|
6
6
|
import type { AiArtifactRuntime } from "../ai-artifact/runtime.js";
|
|
7
|
-
import { ExecutionGrantStore } from "../
|
|
7
|
+
import { ExecutionGrantStore } from "../ai-runtime-security/execution-grants.js";
|
|
8
8
|
import { buildScopeContext } from "../data-access/context.js";
|
|
9
9
|
import { createRequestGuardContext, type RequestActor } from "../guards.js";
|
|
10
10
|
import { initializeModuleHosts } from "../module-host.js";
|
|
@@ -3,7 +3,7 @@ import type { ModuleManifest } from "@southwind-ai/modules";
|
|
|
3
3
|
import { resolveProviderEgress } from "@southwind-ai/modules";
|
|
4
4
|
import type { ModuleAiJsonValue } from "@southwind-ai/server-sdk";
|
|
5
5
|
import type { AiArtifactRuntime } from "../ai-artifact/runtime.js";
|
|
6
|
-
import { scopedRuntimeIdempotencyKey } from "../
|
|
6
|
+
import { scopedRuntimeIdempotencyKey } from "../ai-runtime-security/idempotency-key.js";
|
|
7
7
|
import type { RequestGuardContext } from "../guards.js";
|
|
8
8
|
import type { InitializedModuleHosts } from "../module-host.js";
|
|
9
9
|
import { toModuleActor } from "../module-host.js";
|
|
@@ -8,7 +8,7 @@ import type { RequestGuardContext } from "../guards.js";
|
|
|
8
8
|
import {
|
|
9
9
|
governProviderInput,
|
|
10
10
|
ProviderInputGovernanceError,
|
|
11
|
-
} from "../
|
|
11
|
+
} from "../ai-runtime-security/provider-input-governance.js";
|
|
12
12
|
import type { EmbeddingRuntimeItem } from "./contracts.js";
|
|
13
13
|
import { EmbeddingFacadeError } from "./error.js";
|
|
14
14
|
|
|
@@ -5,7 +5,7 @@ import type {
|
|
|
5
5
|
import type { RequestGuardContext } from "../guards.js";
|
|
6
6
|
import type { RouteApp } from "../system/route-types.js";
|
|
7
7
|
import { EmbeddingFacadeError } from "./error.js";
|
|
8
|
-
import { validInternalToken } from "../
|
|
8
|
+
import { validInternalToken } from "../ai-runtime-security/internal-token.js";
|
|
9
9
|
import type { EmbeddingFacade } from "./facade.js";
|
|
10
10
|
import type { EmbeddingFacadeItem } from "./input.js";
|
|
11
11
|
|