@wildo-ai/saas-backend-lib 1.1.12 → 1.1.13
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/esm/base-classes/models/manual-controllers.backend.definition.d.ts.map +1 -1
- package/dist/esm/base-classes/models/manual-controllers.backend.definition.js +2 -0
- package/dist/esm/base-classes/models/manual-controllers.backend.definition.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/stored-field-omission.backend.d.ts +4 -0
- package/dist/esm/base-classes/services/repositories/stored-field-omission.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/stored-field-omission.backend.js +20 -5
- package/dist/esm/base-classes/services/repositories/stored-field-omission.backend.js.map +1 -1
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-registry.backend.service.d.ts +3 -0
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-registry.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-registry.backend.service.js +10 -1
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-registry.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation.factory.backend.d.ts +22 -0
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation.factory.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation.factory.backend.js +25 -1
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation.factory.backend.js.map +1 -1
- package/dist/esm/base-classes/services/services/resource-operation-transaction-persistence.backend.utils.d.ts +38 -3
- package/dist/esm/base-classes/services/services/resource-operation-transaction-persistence.backend.utils.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/resource-operation-transaction-persistence.backend.utils.js +68 -5
- package/dist/esm/base-classes/services/services/resource-operation-transaction-persistence.backend.utils.js.map +1 -1
- package/dist/esm/base-classes/services/services/resource-status-transition.custom-impl.backend.service.d.ts +2 -2
- package/dist/esm/base-classes/services/services/resource-status-transition.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/resource-status-transition.custom-impl.backend.service.js +6 -3
- package/dist/esm/base-classes/services/services/resource-status-transition.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.d.ts +83 -0
- package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.js +217 -14
- package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.js.map +1 -1
- package/dist/esm/compliance/approval-seals/approval-seal-currency.backend.d.ts +32 -0
- package/dist/esm/compliance/approval-seals/approval-seal-currency.backend.d.ts.map +1 -0
- package/dist/esm/compliance/approval-seals/approval-seal-currency.backend.js +36 -0
- package/dist/esm/compliance/approval-seals/approval-seal-currency.backend.js.map +1 -0
- package/dist/esm/compliance/approval-seals/approval-seal-on-record.backend.d.ts +38 -0
- package/dist/esm/compliance/approval-seals/approval-seal-on-record.backend.d.ts.map +1 -0
- package/dist/esm/compliance/approval-seals/approval-seal-on-record.backend.js +83 -0
- package/dist/esm/compliance/approval-seals/approval-seal-on-record.backend.js.map +1 -0
- package/dist/esm/compliance/approval-seals/approval-seal-presentation-read.backend.d.ts +36 -0
- package/dist/esm/compliance/approval-seals/approval-seal-presentation-read.backend.d.ts.map +1 -0
- package/dist/esm/compliance/approval-seals/approval-seal-presentation-read.backend.js +51 -0
- package/dist/esm/compliance/approval-seals/approval-seal-presentation-read.backend.js.map +1 -0
- package/dist/esm/compliance/approval-seals/approval-seal-relay-store.backend.d.ts +46 -0
- package/dist/esm/compliance/approval-seals/approval-seal-relay-store.backend.d.ts.map +1 -1
- package/dist/esm/compliance/approval-seals/approval-seal-relay-store.backend.js +68 -0
- package/dist/esm/compliance/approval-seals/approval-seal-relay-store.backend.js.map +1 -1
- package/dist/esm/compliance/approval-seals/approval-seal-store.backend.d.ts +27 -0
- package/dist/esm/compliance/approval-seals/approval-seal-store.backend.d.ts.map +1 -1
- package/dist/esm/compliance/approval-seals/approval-seal-store.backend.js +42 -3
- package/dist/esm/compliance/approval-seals/approval-seal-store.backend.js.map +1 -1
- package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.contracts.d.ts +26 -1
- package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.contracts.d.ts.map +1 -1
- package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.contracts.js +10 -0
- package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.contracts.js.map +1 -1
- package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.controller.d.ts +10 -1
- package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.controller.d.ts.map +1 -1
- package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.controller.js +60 -28
- package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.controller.js.map +1 -1
- package/dist/esm/compliance/approval-seals/approval-seals-on-record.backend.controller.d.ts +90 -0
- package/dist/esm/compliance/approval-seals/approval-seals-on-record.backend.controller.d.ts.map +1 -0
- package/dist/esm/compliance/approval-seals/approval-seals-on-record.backend.controller.js +373 -0
- package/dist/esm/compliance/approval-seals/approval-seals-on-record.backend.controller.js.map +1 -0
- package/dist/esm/compliance/approval-seals/decision-presentation.backend.d.ts +29 -2
- package/dist/esm/compliance/approval-seals/decision-presentation.backend.d.ts.map +1 -1
- package/dist/esm/compliance/approval-seals/decision-presentation.backend.js +40 -3
- package/dist/esm/compliance/approval-seals/decision-presentation.backend.js.map +1 -1
- package/dist/esm/compliance/electronic-signatures/pdf-signature-structure.backend.d.ts.map +1 -1
- package/dist/esm/compliance/electronic-signatures/pdf-signature-structure.backend.js +34 -6
- package/dist/esm/compliance/electronic-signatures/pdf-signature-structure.backend.js.map +1 -1
- package/dist/esm/compliance/electronic-signatures/signature-request-evidence-files.backend.d.ts +30 -6
- package/dist/esm/compliance/electronic-signatures/signature-request-evidence-files.backend.d.ts.map +1 -1
- package/dist/esm/compliance/electronic-signatures/signature-request-evidence-files.backend.js +67 -22
- package/dist/esm/compliance/electronic-signatures/signature-request-evidence-files.backend.js.map +1 -1
- package/dist/esm/compliance/electronic-signatures/signature-request-poll.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/compliance/electronic-signatures/signature-request-poll.batch.backend.service.js +18 -1
- package/dist/esm/compliance/electronic-signatures/signature-request-poll.batch.backend.service.js.map +1 -1
- package/dist/esm/compliance/electronic-signatures/signature-requests.backend.service.d.ts +66 -1
- package/dist/esm/compliance/electronic-signatures/signature-requests.backend.service.d.ts.map +1 -1
- package/dist/esm/compliance/electronic-signatures/signature-requests.backend.service.js +161 -14
- package/dist/esm/compliance/electronic-signatures/signature-requests.backend.service.js.map +1 -1
- package/dist/esm/compliance/electronic-signatures/signed-document-validation.backend.d.ts +47 -0
- package/dist/esm/compliance/electronic-signatures/signed-document-validation.backend.d.ts.map +1 -1
- package/dist/esm/compliance/electronic-signatures/signed-document-validation.backend.js.map +1 -1
- package/dist/esm/external-providers/services/content-safety.backend.service.d.ts +27 -2
- package/dist/esm/external-providers/services/content-safety.backend.service.d.ts.map +1 -1
- package/dist/esm/external-providers/services/content-safety.backend.service.js +46 -1
- package/dist/esm/external-providers/services/content-safety.backend.service.js.map +1 -1
- package/dist/esm/external-providers/services/embeddings.backend.service.d.ts.map +1 -1
- package/dist/esm/external-providers/services/embeddings.backend.service.js +2 -0
- package/dist/esm/external-providers/services/embeddings.backend.service.js.map +1 -1
- package/dist/esm/external-providers/services/external-providers-registry.backend.service.d.ts +11 -0
- package/dist/esm/external-providers/services/external-providers-registry.backend.service.d.ts.map +1 -1
- package/dist/esm/external-providers/services/external-providers-registry.backend.service.js +23 -0
- package/dist/esm/external-providers/services/external-providers-registry.backend.service.js.map +1 -1
- package/dist/esm/external-providers/services/provider-service-account-token.backend.d.ts +19 -1
- package/dist/esm/external-providers/services/provider-service-account-token.backend.d.ts.map +1 -1
- package/dist/esm/external-providers/services/provider-service-account-token.backend.js +41 -1
- package/dist/esm/external-providers/services/provider-service-account-token.backend.js.map +1 -1
- package/dist/esm/files/utils/file-parent-read-context.backend.d.ts +27 -2
- package/dist/esm/files/utils/file-parent-read-context.backend.d.ts.map +1 -1
- package/dist/esm/files/utils/file-parent-read-context.backend.js +23 -4
- package/dist/esm/files/utils/file-parent-read-context.backend.js.map +1 -1
- package/dist/esm/flows-actors/content-guardrails/classifier-availability.backend.utils.d.ts +26 -0
- package/dist/esm/flows-actors/content-guardrails/classifier-availability.backend.utils.d.ts.map +1 -1
- package/dist/esm/flows-actors/content-guardrails/classifier-availability.backend.utils.js +100 -8
- package/dist/esm/flows-actors/content-guardrails/classifier-availability.backend.utils.js.map +1 -1
- package/dist/esm/flows-actors/content-guardrails/record-owner-policy.backend.d.ts +3 -1
- package/dist/esm/flows-actors/content-guardrails/record-owner-policy.backend.d.ts.map +1 -1
- package/dist/esm/flows-actors/content-guardrails/record-owner-policy.backend.js +8 -2
- package/dist/esm/flows-actors/content-guardrails/record-owner-policy.backend.js.map +1 -1
- package/dist/esm/flows-actors/models/function-tools.backend.definitions.d.ts +43 -0
- package/dist/esm/flows-actors/models/function-tools.backend.definitions.d.ts.map +1 -1
- package/dist/esm/flows-actors/models/function-tools.backend.definitions.js +37 -0
- package/dist/esm/flows-actors/models/function-tools.backend.definitions.js.map +1 -1
- package/dist/esm/flows-actors/services/agent-work-decisions.backend.service.d.ts +7 -0
- package/dist/esm/flows-actors/services/agent-work-decisions.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/agent-work-decisions.backend.service.js +8 -3
- package/dist/esm/flows-actors/services/agent-work-decisions.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/services/agents.backend.service.d.ts +31 -6
- package/dist/esm/flows-actors/services/agents.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/agents.backend.service.js +78 -30
- package/dist/esm/flows-actors/services/agents.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/services/autonomous-agent-turn.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/autonomous-agent-turn.backend.service.js +4 -0
- package/dist/esm/flows-actors/services/autonomous-agent-turn.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/services/conversational-execution.backend.service.d.ts +28 -2
- package/dist/esm/flows-actors/services/conversational-execution.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/conversational-execution.backend.service.js +132 -22
- package/dist/esm/flows-actors/services/conversational-execution.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/services/flow-actor-executions.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/flow-actor-executions.custom-impl.backend.service.js +12 -8
- package/dist/esm/flows-actors/services/flow-actor-executions.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/services/flows-actors-registry.service.d.ts +5 -0
- package/dist/esm/flows-actors/services/flows-actors-registry.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/flows-actors-registry.service.js +18 -2
- package/dist/esm/flows-actors/services/flows-actors-registry.service.js.map +1 -1
- package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.d.ts +33 -0
- package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.d.ts.map +1 -1
- package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.js +58 -0
- package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.js.map +1 -1
- package/dist/esm/inbound/services/inbound-delivery-dispatch.backend.service.d.ts +12 -1
- package/dist/esm/inbound/services/inbound-delivery-dispatch.backend.service.d.ts.map +1 -1
- package/dist/esm/inbound/services/inbound-delivery-dispatch.backend.service.js +23 -4
- package/dist/esm/inbound/services/inbound-delivery-dispatch.backend.service.js.map +1 -1
- package/dist/esm/inbound/services/inbound-delivery-receiver.backend.service.d.ts +12 -1
- package/dist/esm/inbound/services/inbound-delivery-receiver.backend.service.d.ts.map +1 -1
- package/dist/esm/inbound/services/inbound-delivery-receiver.backend.service.js +55 -17
- package/dist/esm/inbound/services/inbound-delivery-receiver.backend.service.js.map +1 -1
- package/dist/esm/inbound/services/inbound-delivery-store.backend.service.d.ts +22 -1
- package/dist/esm/inbound/services/inbound-delivery-store.backend.service.d.ts.map +1 -1
- package/dist/esm/inbound/services/inbound-delivery-store.backend.service.js +52 -9
- package/dist/esm/inbound/services/inbound-delivery-store.backend.service.js.map +1 -1
- package/dist/esm/inbound/services/inbound-delivery-stored-body.backend.service.d.ts +79 -0
- package/dist/esm/inbound/services/inbound-delivery-stored-body.backend.service.d.ts.map +1 -0
- package/dist/esm/inbound/services/inbound-delivery-stored-body.backend.service.js +211 -0
- package/dist/esm/inbound/services/inbound-delivery-stored-body.backend.service.js.map +1 -0
- package/dist/esm/inbound/services/inbound-delivery-subject-erasure-severance.backend.d.ts +2 -2
- package/dist/esm/inbound/services/inbound-delivery-subject-erasure-severance.backend.d.ts.map +1 -1
- package/dist/esm/inbound/services/inbound-delivery-subject-erasure-severance.backend.js +9 -1
- package/dist/esm/inbound/services/inbound-delivery-subject-erasure-severance.backend.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/inject/models/container.d.ts.map +1 -1
- package/dist/esm/inject/models/container.js +6 -0
- package/dist/esm/inject/models/container.js.map +1 -1
- package/dist/esm/inject/models/service-types.d.ts +5 -0
- package/dist/esm/inject/models/service-types.d.ts.map +1 -1
- package/dist/esm/inject/models/service-types.js +3 -0
- package/dist/esm/inject/models/service-types.js.map +1 -1
- package/dist/esm/monitoring/observability/models/observability.backend.schemas.d.ts +5 -0
- package/dist/esm/monitoring/observability/models/observability.backend.schemas.d.ts.map +1 -1
- package/dist/esm/monitoring/observability/models/observability.backend.schemas.js.map +1 -1
- package/dist/esm/monitoring/observability/services/metrics.service.d.ts +34 -1
- package/dist/esm/monitoring/observability/services/metrics.service.d.ts.map +1 -1
- package/dist/esm/monitoring/observability/services/metrics.service.js +49 -0
- package/dist/esm/monitoring/observability/services/metrics.service.js.map +1 -1
- package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.d.ts +6 -1
- package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.js +15 -4
- package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.js.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/services/m2m-webhook-delivery-log.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/services/m2m-webhook-delivery-log.custom-impl.backend.service.js +3 -1
- package/dist/esm/notifications/webhooks/outbound/services/m2m-webhook-delivery-log.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/runtime/services/http-server.backend.service.d.ts +3 -1
- package/dist/esm/runtime/services/http-server.backend.service.d.ts.map +1 -1
- package/dist/esm/runtime/services/http-server.backend.service.js +11 -3
- package/dist/esm/runtime/services/http-server.backend.service.js.map +1 -1
- package/dist/esm/runtime/services/utils/inbound-endpoint-raw-body.backend.utils.d.ts +22 -0
- package/dist/esm/runtime/services/utils/inbound-endpoint-raw-body.backend.utils.d.ts.map +1 -1
- package/dist/esm/runtime/services/utils/inbound-endpoint-raw-body.backend.utils.js +54 -0
- package/dist/esm/runtime/services/utils/inbound-endpoint-raw-body.backend.utils.js.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/auth-password-reset.backend.service.d.ts +51 -0
- package/dist/esm/security/authentications/services/auth-methods/auth-password-reset.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/auth-password-reset.backend.service.js +87 -15
- package/dist/esm/security/authentications/services/auth-methods/auth-password-reset.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/custom-impls/siem-delivery-dlq.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/custom-impls/siem-delivery-dlq.custom-impl.backend.service.js +5 -2
- package/dist/esm/security/authentications/services/custom-impls/siem-delivery-dlq.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/custom-impls/sso-config-domain-verification.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/custom-impls/sso-config-domain-verification.custom-impl.backend.service.js +65 -24
- package/dist/esm/security/authentications/services/custom-impls/sso-config-domain-verification.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/security/authorizations/super-admin-floor.backend.utils.d.ts +64 -1
- package/dist/esm/security/authorizations/super-admin-floor.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/authorizations/super-admin-floor.backend.utils.js +84 -2
- package/dist/esm/security/authorizations/super-admin-floor.backend.utils.js.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients.custom-impl.backend.service.d.ts +14 -0
- package/dist/esm/security/oauth-clients/oauth-clients.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients.custom-impl.backend.service.js +13 -5
- package/dist/esm/security/oauth-clients/oauth-clients.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/users/services/anonymous-consent.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/users/services/anonymous-consent.custom-impl.backend.service.js +6 -2
- package/dist/esm/users/services/anonymous-consent.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/users/services/user-force-password-reset.custom-impl.backend.service.d.ts +7 -0
- package/dist/esm/users/services/user-force-password-reset.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/users/services/user-force-password-reset.custom-impl.backend.service.js +65 -20
- package/dist/esm/users/services/user-force-password-reset.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/users/services/user-role-administration.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/users/services/user-role-administration.custom-impl.backend.service.js +11 -4
- package/dist/esm/users/services/user-role-administration.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/users/services/user-self-custom-implementations.backend.d.ts.map +1 -1
- package/dist/esm/users/services/user-self-custom-implementations.backend.js +4 -2
- package/dist/esm/users/services/user-self-custom-implementations.backend.js.map +1 -1
- package/dist/esm/users/services/user-super-admin-floor.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/users/services/user-super-admin-floor.custom-impl.backend.service.js +16 -0
- package/dist/esm/users/services/user-super-admin-floor.custom-impl.backend.service.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +10 -10
|
@@ -59,7 +59,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
59
59
|
* somebody else wrote, or a model wrote, about to be read.
|
|
60
60
|
*/
|
|
61
61
|
import { injectable, inject, optional } from 'inversify';
|
|
62
|
-
import { ProviderCallAccount, AgentCallOutcome, AgentCallTraceKind, AgentTraceabilityLevel, EngineCapability, ErrorCustomMessageReference, ErrorType, describeOutboundFetchFailure, A2ATokenBudgetDenialReason, ModelUsageUnit, tokenSpendCeilingOfModelUsageUnit, } from '@wildo-ai/saas-models';
|
|
62
|
+
import { ProviderCallAccount, AgentCallOutcome, AgentCallTraceKind, AgentTraceabilityLevel, EngineCapability, ErrorCustomMessageReference, ErrorType, describeOutboundFetchFailure, A2ATokenBudgetDenialReason, ModelUsageUnit, readEnvironmentAgentContentGuardrails, tokenSpendCeilingOfModelUsageUnit, } from '@wildo-ai/saas-models';
|
|
63
63
|
import { ProviderDataResidencyRefusedError, admitProviderCallUnderDataResidency } from '../../external-providers/data-residency/provider-call-data-residency-gate.backend.js';
|
|
64
64
|
import { ContentSafetyProvider_OperationKey, ContentSafety_HarmCategory, ContentSafety_HarmSeverity, ExternalProvider_ExchangeProtocol_Kind, ProviderProtocolRuntimeKind, contentSafetyHarmSeverityRank, ContentSafetyModerationOutcome, ContentSafetyScreeningOutcome, } from '@wildo-ai/external-connectors-models';
|
|
65
65
|
import { SAAS_SERVICE_TYPES } from '../../inject/models/service-types.js';
|
|
@@ -248,6 +248,51 @@ let ContentSafetyBackendService = class ContentSafetyBackendService {
|
|
|
248
248
|
this.logger.warn('A content-safety call could not be charged to its ceiling', { error: describeCaughtError(error) });
|
|
249
249
|
}
|
|
250
250
|
}
|
|
251
|
+
/**
|
|
252
|
+
* What this environment declared about agents' classifier-backed guardrails where no classifier serves them
|
|
253
|
+
* (`agentContentGuardrails` in `wildo.infra.<env>.config.ts`, projected to `WILDO_AGENT_CONTENT_GUARDRAILS`). Read once,
|
|
254
|
+
* when the service is built: the posture of a running process does not change under it. An unreadable value reads as
|
|
255
|
+
* REFUSE (fail closed), and the startup report says so.
|
|
256
|
+
*/
|
|
257
|
+
guardrailsWithoutClassifier = readEnvironmentAgentContentGuardrails(process.env);
|
|
258
|
+
/** The environment's declaration, as read when the service was built. */
|
|
259
|
+
agentGuardrailsWithoutClassifier() {
|
|
260
|
+
return this.guardrailsWithoutClassifier;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Whether a classifier for `operation` is PRESENT in this environment, as opposed to absent from it. Absent (`false`)
|
|
264
|
+
* in exactly three cases, each a fact of this environment's configuration:
|
|
265
|
+
*
|
|
266
|
+
* - the configuration declares no provider for `AI_CONTENT_SAFETY`;
|
|
267
|
+
* - the selected provider's contract does not offer `operation` (`openai-moderation` declares no screening);
|
|
268
|
+
* - the selected provider's credentials are not authored HERE: its API key slot, or the host slot it reads its endpoint
|
|
269
|
+
* from, is unset in this environment. The classifier is declared once for the whole application, so this is the one
|
|
270
|
+
* way an environment can be without it while another has it (staging without an Azure key, production with one).
|
|
271
|
+
*
|
|
272
|
+
* Everything else is `true` (present): a declared provider that did not load (a data residency refusal), a malformed
|
|
273
|
+
* host, a category it does not assess, a key that is set and wrong, an outage, and anything this cannot read. An
|
|
274
|
+
* environment that declares it runs agents unguarded where no classifier is present must still refuse, or withhold,
|
|
275
|
+
* when one is there and broken, because that is a failure, not the absence the environment declared.
|
|
276
|
+
*/
|
|
277
|
+
classifierPresentFor(operation) {
|
|
278
|
+
try {
|
|
279
|
+
const providerRef = this.externalProvidersRegistry.getPrimaryProviderForEngineCapability(EngineCapability.AI_CONTENT_SAFETY);
|
|
280
|
+
if (!providerRef)
|
|
281
|
+
return this.externalProvidersRegistry.declaresProviderForEngineCapability(EngineCapability.AI_CONTENT_SAFETY);
|
|
282
|
+
if (!this.externalProvidersRegistry.getContentSafetySemanticOperationKeys(providerRef).includes(operation))
|
|
283
|
+
return false;
|
|
284
|
+
if (!this.externalProvidersRegistry.getProviderApiKey(providerRef, ExternalProvider_ExchangeProtocol_Kind.CONTENT_SAFETY_PROVIDER))
|
|
285
|
+
return false;
|
|
286
|
+
const contract = this.externalProvidersRegistry.getProviderRuntimeContract(providerRef, ExternalProvider_ExchangeProtocol_Kind.CONTENT_SAFETY_PROVIDER);
|
|
287
|
+
const hostVariable = contract?.kind === ProviderProtocolRuntimeKind.CONTENT_SAFETY ? contract.baseUrlHostEnvVarName : undefined;
|
|
288
|
+
if (hostVariable !== undefined && !process.env[hostVariable]?.trim())
|
|
289
|
+
return false;
|
|
290
|
+
return true;
|
|
291
|
+
}
|
|
292
|
+
catch {
|
|
293
|
+
return true;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
251
296
|
/**
|
|
252
297
|
* Whether this process records the screenings it makes (a provider-call recorder is bound). An agent that declares
|
|
253
298
|
* screening refuses to run where it does not: a screening nobody can show happened is the gap R7 exists to close.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content-safety.backend.service.js","sourceRoot":"","sources":["../../../../src/external-providers/services/content-safety.backend.service.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Content-safety execution service (#2292): the ONE seam through which the engine asks a classifier about text. Two\n * questions, one per operation:\n *\n * - SCREENING (`screenForPromptInjection`): does third-party content about to reach a model carry instructions aimed\n * at it? Callers: the agent runtime, screening what an agent's tools return, and the autonomous turn, screening an\n * inbound delivery before the turn starts — for an agent that declares `contentGuardrails.promptInjection`.\n * - MODERATION (`moderateOutput`, Phase 3): how harmful is a text a model WROTE, per harm category? Caller: the agent\n * runtime's output moderator, for an agent that declares `contentGuardrails.outputModeration`. The service judges;\n * the agent's policy decides what is withheld.\n *\n * ## The line between engine and provider\n *\n * The DOCUMENT_EXTRACTION seam, at its simplest form. The provider declares PURE FUNCTIONS on its contract\n * (`promptInjection.buildScreenRequest` / `parseScreenResponse`, `outputModeration.buildModerationRequest` /\n * `parseModerationResponse`) and the limits its vendor documents; the engine owns:\n *\n * - the URL (the contract's `baseUrl`, or `https://<host>` from `baseUrlHostEnvVarName`, or a local double's\n * `http://127.0.0.1:<port>` in development and test, #2991), the API-key header, the timeout, redirects refused;\n * - SPLITTING: a text longer than one request carries is split into documents, with an overlap so an instruction of\n * up to 1,000 characters that straddles a boundary is still whole in one of them; screening batches them under both\n * declared limits, and moderation judges every part and keeps the worst severity per category;\n * - the FLOORS: a transport failure or timeout, a provider function that throws or returns the wrong shape, and a\n * verdict count that differs from the documents sent are each NOT_SCREENED. The caller withholds what was not\n * screened, so no floor can ever read as \"clean\".\n *\n * ## Outcomes\n *\n * Screening, {@link ContentSafetyScreeningOutcome}: CLEAN (every document screened, none flagged), ATTACK_DETECTED (some\n * document flagged), NOT_SCREENED (anything else). A caller releases the text on CLEAN only.\n *\n * Moderation, {@link ContentSafetyModerationOutcome}: MODERATED (a severity for EVERY category asked about, the worst\n * across the text's parts) or NOT_MODERATED (anything else — a category missing from an answer included, never read as\n * SAFE). A caller withholds what was not moderated.\n *\n * ## The organization's content-screening ceiling (#3030)\n *\n * Every screening and moderation is asked of the organization's `ai.contentSafety.textRecordsPerPeriod` ceiling before\n * anything is sent, and charged the text records it sent. A spent or unverifiable ceiling sends nothing: the result is\n * NOT_SCREENED / NOT_MODERATED carrying `spendCeilingRefusal`, so a guarded agent fails closed as it does when no\n * classifier answers, while the reason and the `MODEL_SPEND_LIMIT_REFUSED` row say it was the ceiling.\n *\n * ## Observability\n *\n * One trace per screening or moderation, through the provider-call recorder and the trace sink. Summaries only —\n * characters, documents, requests, outcome. The text never enters a trace, a log or an error context: it is content\n * somebody else wrote, or a model wrote, about to be read.\n */\nimport { injectable, inject, optional } from 'inversify';\nimport {\n ProviderCallAccount,\n AgentCallOutcome,\n AgentCallTraceKind,\n AgentTraceabilityLevel,\n EngineCapability,\n ErrorCustomMessageReference,\n ErrorType,\n describeOutboundFetchFailure,\n type AgentCallTrace,\n type AgentCallTraceSink,\n type AgentTraceabilityPolicy,\n A2ATokenBudgetDenialReason,\n ModelUsageUnit,\n tokenSpendCeilingOfModelUsageUnit,\n type TokenSpendCeiling,\n} from '@wildo-ai/saas-models';\nimport { ProviderDataResidencyRefusedError, admitProviderCallUnderDataResidency } from '~wildo-backend-lib/external-providers/data-residency/provider-call-data-residency-gate.backend';\nimport {\n ContentSafetyProvider_OperationKey,\n ContentSafety_HarmCategory,\n ContentSafety_HarmSeverity,\n ExternalProvider_ExchangeProtocol_Kind,\n ProviderProtocolRuntimeKind,\n contentSafetyHarmSeverityRank,\n type ContentSafety_HarmCategoryVerdict,\n type ContentSafety_OutputModerationLimits,\n type ContentSafety_PromptInjectionLimits,\n type ContentSafety_ProviderModeration,\n type ContentSafety_ProviderScreening,\n ContentSafetyModerationOutcome,\n ContentSafetyScreeningOutcome,\n} from '@wildo-ai/external-connectors-models';\nimport type { ContentSafetyProviderScreenResponseInput, ProviderProtocolRuntimeContract } from '@wildo-ai/external-connectors-private/backend';\n\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\nimport type { LoggerService } from '~wildo-backend-lib/monitoring/logger/services/logger.service';\nimport type { ErrorBuilderBackendService } from '~wildo-backend-lib/errors/services/error-builder.backend.service';\nimport type { ExternalProvidersRegistryBackendService } from '~wildo-backend-lib/external-providers/services/external-providers-registry.backend.service';\nimport type { ProviderCallRecorderBackendService } from '~wildo-backend-lib/flows-actors/services/provider-call-recorder.backend.service';\nimport { withEngineOwnedHeaders } from '~wildo-backend-lib/security/outbound/outbound-request-headers.backend.utils';\nimport { resolveProviderContractBaseUrl } from '~wildo-backend-lib/external-providers/services/provider-http-access.backend';\nimport { describeCaughtError } from '~wildo-backend-lib/errors/utils/error-log-level-classification.backend.utils';\nimport type { ModelUsageCall, ModelUsageMeter } from '~wildo-backend-lib/flows-actors/a2a/services/a2a-token-budget.backend.service';\nimport { admitModelUsageCall, describeModelUsageCeilingRefusal, resolveModelUsageCall } from '~wildo-backend-lib/flows-actors/a2a/services/model-usage-ceiling.backend.utils';\n\n/** Per-request timeout. A classifier answers in well under a second; this bounds a hung one, and an agent waits on it. */\nexport const CONTENT_SAFETY_REQUEST_TIMEOUT_MS = 15_000;\n\n/** Attempts per request, the first included. One retry covers a dropped connection or a throttled burst. */\nexport const CONTENT_SAFETY_MAX_ATTEMPTS = 2;\n\n/**\n * The most characters the engine screens for one text. Beyond it the text is NOT_SCREENED (and so withheld) rather than\n * sent as dozens of requests: a tool result that size is not one a model should read whole either, and the bound keeps\n * one tool call from turning into an unbounded spend at the classifier.\n */\nexport const CONTENT_SAFETY_ENGINE_MAX_SCREENED_CHARACTERS = 200_000;\n\n/** The agent ref a screening trace is recorded under. */\nexport const CONTENT_SAFETY_TRACE_AGENT_REF = 'engine:content-safety';\n\n/**\n * Why a screening or a moderation was not even sent (#3030): the organization's content-screening ceiling\n * (`ai.contentSafety.textRecordsPerPeriod`) is spent or could not be checked. Its presence is what tells a ceiling from a\n * classifier that did not answer; both are NOT_SCREENED / NOT_MODERATED, so the caller withholds either way.\n */\nexport interface ContentSafetySpendCeilingRefusal {\n readonly ceiling: TokenSpendCeiling;\n readonly reason: A2ATokenBudgetDenialReason;\n}\n\n/** The result of one screening. */\nexport type ContentSafetyScreeningResult =\n | { readonly outcome: ContentSafetyScreeningOutcome.CLEAN | ContentSafetyScreeningOutcome.ATTACK_DETECTED; readonly providerRef: string }\n | {\n readonly outcome: ContentSafetyScreeningOutcome.NOT_SCREENED;\n readonly providerRef?: string;\n /** Operator-facing; never the screened text or the vendor's response body. Names the ceiling when it refused. */\n readonly reason: string;\n /** Set only when the screening was not sent because the content-screening ceiling refused it (#3030). */\n readonly spendCeilingRefusal?: ContentSafetySpendCeilingRefusal;\n };\n\n/** The result of one moderation. */\nexport type ContentSafetyModerationResult =\n | {\n readonly outcome: ContentSafetyModerationOutcome.MODERATED;\n readonly providerRef: string;\n /** One per category asked about, in the order asked: the WORST severity any part of the text reached. */\n readonly categories: readonly ContentSafety_HarmCategoryVerdict[];\n }\n | {\n readonly outcome: ContentSafetyModerationOutcome.NOT_MODERATED;\n readonly providerRef?: string;\n /** Operator-facing; never the text or the vendor's response body. Names the ceiling when it refused. */\n readonly reason: string;\n /** Set only when the moderation was not sent because the content-screening ceiling refused it (#3030). */\n readonly spendCeilingRefusal?: ContentSafetySpendCeilingRefusal;\n };\n\ntype ContentSafetyContract = Extract<ProviderProtocolRuntimeContract, { kind: typeof ProviderProtocolRuntimeKind.CONTENT_SAFETY }>;\n\n/** The resolved provider and everything a request needs, except the key and the operation's own arm. */\ninterface ContentSafetyEndpoint {\n providerRef: string;\n baseUrl: string;\n apiKeyHeaderName: string;\n apiKeyPrefix: string;\n}\n\n/** The endpoint and a held-to-shape `promptInjection` arm. */\ninterface ContentSafetyBinding extends ContentSafetyEndpoint {\n promptInjection: NonNullable<ContentSafetyContract['promptInjection']>;\n}\n\n/** The endpoint and a held-to-shape `outputModeration` arm. */\ninterface ContentSafetyModerationBinding extends ContentSafetyEndpoint {\n outputModeration: NonNullable<ContentSafetyContract['outputModeration']>;\n}\n\n/** \"Can this operation run here?\" Absent only when no provider fills the slot; a selected provider that cannot serve throws. */\nexport type ContentSafetyBindingResolution =\n | { configured: true; providerRef: string }\n | { configured: false; reason: 'no_provider_for_capability' };\n\n/** Why a screening could not complete, carried to NOT_SCREENED. */\nclass ContentSafetyNotScreened extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ContentSafetyNotScreened';\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.length > 0;\n}\n\n/**\n * Split a text into documents no longer than `maxCharacters`, each overlapping the previous one by a tenth of the window\n * (at most 1,000), so an instruction up to that long that straddles a boundary is whole in one of them; a longer one is\n * split like any text. Lengths are measured in UTF-16 code units (a JavaScript string's `length`), which is never fewer\n * than code points, so a document fits a limit stated in characters whichever of the two a vendor counts; and a\n * document is only ever cut between code points, never inside a surrogate pair.\n */\nexport function splitForScreening(text: string, maxCharacters: number): string[] {\n if (text.length <= maxCharacters) return [text];\n const codePoints = Array.from(text);\n const overlap = Math.min(1_000, Math.floor(maxCharacters / 10));\n const documents: string[] = [];\n let start = 0;\n while (start < codePoints.length) {\n // Take code points while the document still fits.\n let end = start;\n let units = 0;\n while (end < codePoints.length && units + codePoints[end]!.length <= maxCharacters) {\n units += codePoints[end]!.length;\n end += 1;\n }\n if (end === start) end = start + 1; // A single code point longer than the window cannot occur for a window ≥ 2.\n documents.push(codePoints.slice(start, end).join(''));\n if (end >= codePoints.length) break;\n // Step back by the overlap, measured in code units, but always forward.\n let back = end;\n let backUnits = 0;\n while (back > start + 1 && backUnits + codePoints[back - 1]!.length <= overlap) {\n backUnits += codePoints[back - 1]!.length;\n back -= 1;\n }\n start = back;\n }\n return documents;\n}\n\n/**\n * The text records one document sent to a content-safety vendor is billed as (#2889): one per started block of 1,000\n * characters counted in Unicode code points, and at least one for a document that was sent at all. How Azure AI Content\n * Safety bills its Text API: \"A text record in the S tier contains up to 1,000 characters as measured by Unicode code\n * points\", one \"for each unit of 1,000 characters\".\n * spec-cite: https://azure.microsoft.com/en-us/pricing/details/cognitive-services/content-safety/\n */\nexport function contentSafetyTextRecordsOf(document: string): number {\n let codePoints = 0;\n for (const _ of document) codePoints += 1;\n return Math.max(1, Math.ceil(codePoints / 1_000));\n}\n\n/** Group documents into requests under both limits, in order. Each document already fits one request on its own. */\nexport function batchForScreening(documents: readonly string[], limits: ContentSafety_PromptInjectionLimits): string[][] {\n const batches: string[][] = [];\n let current: string[] = [];\n let currentCharacters = 0;\n for (const document of documents) {\n const characters = document.length;\n if (current.length > 0 && (current.length >= limits.maxDocumentsPerRequest || currentCharacters + characters > limits.maxCharactersPerRequest)) {\n batches.push(current);\n current = [];\n currentCharacters = 0;\n }\n current.push(document);\n currentCharacters += characters;\n }\n if (current.length > 0) batches.push(current);\n return batches;\n}\n\n/** Why a provider function's return value is not the contract's shape, or `undefined`. */\nfunction describeScreeningDefect(value: unknown, documentsSent: number): string | undefined {\n if (!isRecord(value) || typeof value.screened !== 'boolean') return 'returned no `screened` verdict';\n if (!value.screened) return typeof value.message === 'string' ? undefined : 'returned a refusal without a message';\n const documents = value.documents;\n if (!Array.isArray(documents) || !documents.every((verdict) => isRecord(verdict) && typeof verdict.attackDetected === 'boolean')) {\n return 'returned verdicts without a boolean `attackDetected` each';\n }\n return documents.length === documentsSent ? undefined : `returned ${documents.length} verdict(s) for ${documentsSent} document(s)`;\n}\n\n/** Why a moderation parser's return value is not the contract's shape, or `undefined`. */\nfunction describeModerationDefect(value: unknown): string | undefined {\n if (!isRecord(value) || typeof value.moderated !== 'boolean') return 'returned no `moderated` verdict';\n if (!value.moderated) return typeof value.message === 'string' ? undefined : 'returned a refusal without a message';\n const categories = value.categories;\n const knownCategories = Object.values(ContentSafety_HarmCategory) as string[];\n const knownSeverities = Object.values(ContentSafety_HarmSeverity) as string[];\n if (!Array.isArray(categories) || !categories.every((verdict) => isRecord(verdict)\n && knownCategories.includes(verdict.category as string) && knownSeverities.includes(verdict.severity as string))) {\n return 'returned verdicts that are not a known category with a known severity each';\n }\n return undefined;\n}\n\nfunction describeRequestDefect(value: unknown): string | undefined {\n if (!isRecord(value) || typeof value.body !== 'string') return 'returned no string `body`';\n return value.transportHeaders === undefined || isRecord(value.transportHeaders) ? undefined : 'returned `transportHeaders` that are not an object';\n}\n\n@injectable()\nexport class ContentSafetyBackendService {\n constructor(\n @inject(SAAS_SERVICE_TYPES.Logger) private readonly logger: LoggerService,\n @inject(SAAS_SERVICE_TYPES.ErrorBuilderService) private readonly errorBuilder: ErrorBuilderBackendService,\n @inject(SAAS_SERVICE_TYPES.ExternalProvidersRegistryService) private readonly externalProvidersRegistry: ExternalProvidersRegistryBackendService,\n @inject(SAAS_SERVICE_TYPES.AgentCallTraceSink) @optional() private readonly agentTraceSink?: AgentCallTraceSink,\n @inject(SAAS_SERVICE_TYPES.AgentTraceabilityPolicy) @optional() private readonly agentTracePolicy?: AgentTraceabilityPolicy,\n @inject(SAAS_SERVICE_TYPES.ProviderCallRecorder) @optional() private readonly providerCallRecorder?: ProviderCallRecorderBackendService,\n // #3030: the organization's content-screening ceiling, asked before every screening and moderation and charged the\n // text records each sent. Appended LAST.\n @inject(SAAS_SERVICE_TYPES.A2ATokenBudgetService) @optional() private readonly modelUsage?: ModelUsageMeter,\n ) {}\n\n /**\n * #3030: ask the content-screening ceiling for the call about to be made. `undefined` when it may be sent; otherwise the\n * refusal, worded for the NOT_SCREENED / NOT_MODERATED reason. Never throws: a gate that could not even be asked is\n * read as an unverifiable ceiling and refuses (fail closed), since every failure on this path must be a withheld text.\n */\n private async admitScreening(): Promise<{ call: ModelUsageCall | undefined; refusal?: { reason: string; spendCeilingRefusal: ContentSafetySpendCeilingRefusal } }> {\n try {\n const call = await resolveModelUsageCall(ModelUsageUnit.SCREENING_TEXT_RECORDS, undefined, this.providerCallRecorder);\n const refusal = await admitModelUsageCall(this.modelUsage, call);\n if (!refusal) return { call };\n return { call, refusal: { reason: describeModelUsageCeilingRefusal(refusal), spendCeilingRefusal: { ceiling: refusal.ceiling, reason: refusal.reason } } };\n } catch (error) {\n this.logger.warn('The content-screening ceiling could not be asked; the text is not screened', { error: describeCaughtError(error) });\n // The sentence is the shared one (`describeModelUsageCeilingRefusal`), so this path cannot word it differently.\n const unverifiable = { unit: ModelUsageUnit.SCREENING_TEXT_RECORDS, reason: A2ATokenBudgetDenialReason.ALLOWANCE_UNVERIFIABLE };\n return {\n call: undefined,\n refusal: {\n reason: describeModelUsageCeilingRefusal(unverifiable),\n spendCeilingRefusal: { ceiling: tokenSpendCeilingOfModelUsageUnit(unverifiable.unit), reason: unverifiable.reason },\n },\n };\n }\n }\n\n /** #3030: charge the text records a screening or moderation sent (counted once the vendor answered). Never throws. */\n private chargeScreening(call: ModelUsageCall | undefined, textRecords: number): void {\n if (!call) return;\n try {\n this.modelUsage?.recordModelUsage(call, textRecords);\n } catch (error) {\n this.logger.warn('A content-safety call could not be charged to its ceiling', { error: describeCaughtError(error) });\n }\n }\n\n /**\n * Whether this process records the screenings it makes (a provider-call recorder is bound). An agent that declares\n * screening refuses to run where it does not: a screening nobody can show happened is the gap R7 exists to close.\n */\n public recordsScreenings(): boolean {\n return this.providerCallRecorder !== undefined;\n }\n\n /**\n * Whether a classifier is selected for `AI_CONTENT_SAFETY`, and serves prompt-injection screening. `configured: false`\n * only when nothing is selected; a selected provider that cannot serve THROWS a named CONFIGURATION error, because an\n * operator's mistake must not read as a deliberate absence.\n */\n public resolvePromptInjectionBinding(): ContentSafetyBindingResolution {\n const binding = this.resolveFullBinding();\n return binding === undefined ? { configured: false, reason: 'no_provider_for_capability' } : { configured: true, providerRef: binding.providerRef };\n }\n\n /**\n * Whether a classifier is selected for `AI_CONTENT_SAFETY` that moderates output in EVERY one of `categories`. Same\n * contract as {@link resolvePromptInjectionBinding}: absent only when nothing is selected, and a selected provider that\n * cannot serve — no `moderateOutput` operation, or a category it does not assess — throws a CONFIGURATION error.\n */\n public resolveOutputModerationBinding(categories: readonly ContentSafety_HarmCategory[]): ContentSafetyBindingResolution {\n const binding = this.resolveFullModerationBinding(categories);\n return binding === undefined ? { configured: false, reason: 'no_provider_for_capability' } : { configured: true, providerRef: binding.providerRef };\n }\n\n /**\n * Screen one text for a prompt-injection attack, as a DOCUMENT (content somebody else wrote, about to reach a model).\n * Never throws: every failure is NOT_SCREENED, which the caller withholds.\n *\n * assurance-control: WILDO.SECURITY.FAIL_CLOSED — a text that could not be fully screened is NOT_SCREENED, never clean.\n * assurance-control: WILDO.INTEGRATION.OUTBOUND_ACTIVITY_AUDIT — every screening leaves one provider-call record\n * (provider, characters, documents, requests, outcome), never the text.\n * assurance-control: WILDO.PRIVACY.DATA_MINIMIZATION — the provider's request builder receives the documents and\n * nothing else: no tenant, user, record or agent.\n */\n public async screenForPromptInjection(text: string): Promise<ContentSafetyScreeningResult> {\n let binding: ContentSafetyBinding | undefined;\n try {\n binding = this.resolveFullBinding();\n } catch (error) {\n return { outcome: ContentSafetyScreeningOutcome.NOT_SCREENED, reason: describeCaughtError(error) };\n }\n if (binding === undefined) {\n return { outcome: ContentSafetyScreeningOutcome.NOT_SCREENED, reason: 'No provider is selected for AI_CONTENT_SAFETY.' };\n }\n // #3030: a spent or unverifiable content-screening ceiling sends nothing and leaves no provider-call record: the text\n // is NOT_SCREENED, so the caller withholds it exactly as when no classifier answers, and the reason names the ceiling.\n const admission = await this.admitScreening();\n if (admission.refusal) {\n return { outcome: ContentSafetyScreeningOutcome.NOT_SCREENED, providerRef: binding.providerRef, ...admission.refusal };\n }\n const startTime = Date.now();\n const characters = text.length;\n const summary = { characters, documents: 0, requests: 0, textRecords: 0 };\n let result: ContentSafetyScreeningResult;\n try {\n result = await this.screen(binding, text, characters, summary);\n } catch (error) {\n result = {\n outcome: ContentSafetyScreeningOutcome.NOT_SCREENED,\n providerRef: binding.providerRef,\n reason: error instanceof ContentSafetyNotScreened ? error.message : describeCaughtError(error),\n };\n }\n this.chargeScreening(admission.call, summary.textRecords);\n await this.emitTrace(binding.providerRef, ContentSafetyProvider_OperationKey.SCREEN_PROMPT_INJECTION,\n result.outcome === ContentSafetyScreeningOutcome.NOT_SCREENED ? { failure: result.reason } : { outcome: result.outcome }, summary, startTime);\n return result;\n }\n\n /**\n * Judge one text a model WROTE in each of `categories`, which must be non-empty. Never throws: every failure is\n * NOT_MODERATED, which the caller withholds. A text longer than one request is split (with the screening splitter's\n * overlap, so a phrase across a boundary is whole in one part) and every part judged; each category's verdict is the\n * worst severity any part reached.\n *\n * assurance-control: WILDO.SECURITY.FAIL_CLOSED — a text not judged in every category asked about is NOT_MODERATED,\n * never SAFE.\n * assurance-control: WILDO.INTEGRATION.OUTBOUND_ACTIVITY_AUDIT — every moderation leaves one provider-call record\n * (provider, characters, parts, requests, outcome), never the text.\n * assurance-control: WILDO.PRIVACY.DATA_MINIMIZATION — the provider's request builder receives the text and the\n * categories, nothing else.\n */\n public async moderateOutput(text: string, categories: readonly ContentSafety_HarmCategory[]): Promise<ContentSafetyModerationResult> {\n if (categories.length === 0) {\n return { outcome: ContentSafetyModerationOutcome.NOT_MODERATED, reason: 'No harm category was asked about.' };\n }\n let binding: ContentSafetyModerationBinding | undefined;\n try {\n binding = this.resolveFullModerationBinding(categories);\n } catch (error) {\n return { outcome: ContentSafetyModerationOutcome.NOT_MODERATED, reason: describeCaughtError(error) };\n }\n if (binding === undefined) {\n return { outcome: ContentSafetyModerationOutcome.NOT_MODERATED, reason: 'No provider is selected for AI_CONTENT_SAFETY.' };\n }\n // #3030: the same ceiling as screening (a moderation is billed in the same text records): refused, nothing is sent,\n // and the output is NOT_MODERATED, so it is withheld, with the ceiling named.\n const admission = await this.admitScreening();\n if (admission.refusal) {\n return { outcome: ContentSafetyModerationOutcome.NOT_MODERATED, providerRef: binding.providerRef, ...admission.refusal };\n }\n const startTime = Date.now();\n const summary = { characters: text.length, documents: 0, requests: 0, textRecords: 0 };\n let result: ContentSafetyModerationResult;\n try {\n result = await this.moderate(binding, text, categories, summary);\n } catch (error) {\n result = {\n outcome: ContentSafetyModerationOutcome.NOT_MODERATED,\n providerRef: binding.providerRef,\n reason: error instanceof ContentSafetyNotScreened ? error.message : describeCaughtError(error),\n };\n }\n this.chargeScreening(admission.call, summary.textRecords);\n await this.emitTrace(binding.providerRef, ContentSafetyProvider_OperationKey.MODERATE_OUTPUT,\n result.outcome === ContentSafetyModerationOutcome.NOT_MODERATED ? { failure: result.reason } : { outcome: result.outcome }, summary, startTime);\n return result;\n }\n\n /**\n * #2294: an organization's data residency, before the text leaves. A refusal is reported as text NOT screened, the\n * one answer every caller already handles (each applies its own fail-closed or fail-open posture), with the gate's\n * audit row saying why.\n */\n private async admitUnderDataResidency(providerRef: string): Promise<void> {\n try {\n await admitProviderCallUnderDataResidency({ providerRef, account: ProviderCallAccount.APPLICATION });\n } catch (error) {\n if (error instanceof ProviderDataResidencyRefusedError) throw new ContentSafetyNotScreened(error.message);\n throw error;\n }\n }\n\n private async moderate(\n binding: ContentSafetyModerationBinding,\n text: string,\n categories: readonly ContentSafety_HarmCategory[],\n summary: { documents: number; requests: number; textRecords: number },\n ): Promise<ContentSafetyModerationResult> {\n if (text.length > CONTENT_SAFETY_ENGINE_MAX_SCREENED_CHARACTERS) {\n throw new ContentSafetyNotScreened(`The text is ${text.length} characters long, over the ${CONTENT_SAFETY_ENGINE_MAX_SCREENED_CHARACTERS} the engine moderates.`);\n }\n await this.admitUnderDataResidency(binding.providerRef);\n const apiKey = this.externalProvidersRegistry.getProviderApiKey(binding.providerRef, ExternalProvider_ExchangeProtocol_Kind.CONTENT_SAFETY_PROVIDER);\n if (!apiKey) {\n throw new ContentSafetyNotScreened(this.externalProvidersRegistry.describeMissingProviderApiKey(binding.providerRef, ExternalProvider_ExchangeProtocol_Kind.CONTENT_SAFETY_PROVIDER));\n }\n const parts = splitForScreening(text, Math.min(binding.outputModeration.limits.maxCharactersPerRequest, CONTENT_SAFETY_ENGINE_MAX_SCREENED_CHARACTERS));\n summary.documents = parts.length;\n const worst = new Map<ContentSafety_HarmCategory, ContentSafety_HarmSeverity>();\n for (const part of parts) {\n summary.requests += 1;\n const moderation = await this.moderatePart(binding, apiKey, part, categories);\n // Counted once the vendor ANSWERED (#2889, review F5): the count is a claim of what was billed, and an answer is\n // the evidence that the text was processed. A request that failed in transport or was refused is not counted.\n summary.textRecords += contentSafetyTextRecordsOf(part);\n for (const category of categories) {\n const verdict = moderation.categories.find((candidate) => candidate.category === category);\n // A category asked about and not answered was not judged: never read as SAFE.\n if (verdict === undefined) {\n throw new ContentSafetyNotScreened(`Content-safety provider \"${binding.providerRef}\" returned no verdict for the '${category}' category.`);\n }\n const previous = worst.get(category);\n if (previous === undefined || contentSafetyHarmSeverityRank(verdict.severity) > contentSafetyHarmSeverityRank(previous)) worst.set(category, verdict.severity);\n }\n }\n return {\n outcome: ContentSafetyModerationOutcome.MODERATED,\n providerRef: binding.providerRef,\n categories: categories.map((category) => ({ category, severity: worst.get(category)! })),\n };\n }\n\n /** One moderation request, retried once on any failure; a refusal or a defect after the last attempt is NOT_MODERATED. */\n private async moderatePart(\n binding: ContentSafetyModerationBinding,\n apiKey: string,\n text: string,\n categories: readonly ContentSafety_HarmCategory[],\n ): Promise<Extract<ContentSafety_ProviderModeration, { moderated: true }>> {\n let lastFailure = 'no attempt was made';\n for (let attempt = 1; attempt <= CONTENT_SAFETY_MAX_ATTEMPTS; attempt += 1) {\n try {\n const request = this.runProvider(binding, 'moderation request builder',\n () => binding.outputModeration.buildModerationRequest({ text, categories }), describeRequestDefect);\n const response = await this.send(binding, apiKey, binding.outputModeration.endpointPath, request.body, request.transportHeaders);\n const moderation = this.runProvider(binding, 'moderation response parser',\n () => binding.outputModeration.parseModerationResponse(response), describeModerationDefect);\n // `=== true`: this compiler configuration narrows the literal discriminant only on the explicit comparison.\n if (moderation.moderated === true) return moderation;\n if (moderation.moderated === false) lastFailure = `Content-safety provider \"${binding.providerRef}\" refused the moderation: ${moderation.message}`;\n } catch (error) {\n lastFailure = error instanceof ContentSafetyNotScreened ? error.message : describeCaughtError(error);\n }\n }\n throw new ContentSafetyNotScreened(lastFailure);\n }\n\n private async screen(\n binding: ContentSafetyBinding,\n text: string,\n characters: number,\n summary: { documents: number; requests: number; textRecords: number },\n ): Promise<ContentSafetyScreeningResult> {\n if (characters > CONTENT_SAFETY_ENGINE_MAX_SCREENED_CHARACTERS) {\n throw new ContentSafetyNotScreened(`The text is ${characters} characters long, over the ${CONTENT_SAFETY_ENGINE_MAX_SCREENED_CHARACTERS} the engine screens.`);\n }\n await this.admitUnderDataResidency(binding.providerRef);\n const apiKey = this.externalProvidersRegistry.getProviderApiKey(binding.providerRef, ExternalProvider_ExchangeProtocol_Kind.CONTENT_SAFETY_PROVIDER);\n if (!apiKey) {\n throw new ContentSafetyNotScreened(this.externalProvidersRegistry.describeMissingProviderApiKey(binding.providerRef, ExternalProvider_ExchangeProtocol_Kind.CONTENT_SAFETY_PROVIDER));\n }\n const { limits } = binding.promptInjection;\n // A document never exceeds what one request may carry, so every batch below holds at least one.\n const documents = splitForScreening(text, Math.min(limits.maxCharactersPerRequest, CONTENT_SAFETY_ENGINE_MAX_SCREENED_CHARACTERS));\n summary.documents = documents.length;\n for (const batch of batchForScreening(documents, limits)) {\n summary.requests += 1;\n const screening = await this.screenBatch(binding, apiKey, batch);\n // Only the batches the vendor answered are counted (#2889, review F5): screening stops at the first attack, and a\n // request that failed in transport or was refused is no evidence the text was processed.\n for (const document of batch) summary.textRecords += contentSafetyTextRecordsOf(document);\n if (screening.documents.some((verdict) => verdict.attackDetected)) {\n return { outcome: ContentSafetyScreeningOutcome.ATTACK_DETECTED, providerRef: binding.providerRef };\n }\n }\n return { outcome: ContentSafetyScreeningOutcome.CLEAN, providerRef: binding.providerRef };\n }\n\n /** One request, retried once on any failure; a refusal or a defect after the last attempt is NOT_SCREENED. */\n private async screenBatch(\n binding: ContentSafetyBinding,\n apiKey: string,\n documents: readonly string[],\n ): Promise<Extract<ContentSafety_ProviderScreening, { screened: true }>> {\n let lastFailure = 'no attempt was made';\n for (let attempt = 1; attempt <= CONTENT_SAFETY_MAX_ATTEMPTS; attempt += 1) {\n try {\n const request = this.runProvider(binding, 'request builder', () => binding.promptInjection.buildScreenRequest({ documents }), describeRequestDefect);\n const response = await this.send(binding, apiKey, binding.promptInjection.endpointPath, request.body, request.transportHeaders);\n const screening = this.runProvider(binding, 'response parser', () => binding.promptInjection.parseScreenResponse(response),\n (value) => describeScreeningDefect(value, documents.length));\n // `=== true`: this compiler configuration narrows the literal discriminant only on the explicit comparison.\n if (screening.screened === true) return screening;\n if (screening.screened === false) lastFailure = `Content-safety provider \"${binding.providerRef}\" refused the screening: ${screening.message}`;\n } catch (error) {\n lastFailure = error instanceof ContentSafetyNotScreened ? error.message : describeCaughtError(error);\n }\n }\n throw new ContentSafetyNotScreened(lastFailure);\n }\n\n private async send(\n binding: ContentSafetyEndpoint,\n apiKey: string,\n endpointPath: string,\n body: string,\n transportHeaders: Readonly<Record<string, string>> | undefined,\n ): Promise<ContentSafetyProviderScreenResponseInput> {\n const url = `${binding.baseUrl.replace(/\\/+$/, '')}/${endpointPath.replace(/^\\/+/, '')}`;\n const abortController = new AbortController();\n const timeout = setTimeout(() => abortController.abort(), CONTENT_SAFETY_REQUEST_TIMEOUT_MS);\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: withEngineOwnedHeaders(transportHeaders ?? {}, { [binding.apiKeyHeaderName]: `${binding.apiKeyPrefix}${apiKey}` }),\n body,\n signal: abortController.signal,\n redirect: 'error',\n });\n const responseText = await response.text();\n const headers: Record<string, string> = {};\n response.headers.forEach((value, key) => { headers[key.toLowerCase()] = value; });\n let parsedBody: unknown = undefined;\n if (responseText.length > 0) {\n try { parsedBody = JSON.parse(responseText); } catch { parsedBody = responseText; }\n }\n return { status: response.status, headers, body: parsedBody };\n } catch (transportError) {\n // By name and code only (#2407): fetch's own message can restate the key sent in a header.\n throw new ContentSafetyNotScreened(`Content-safety provider \"${binding.providerRef}\" was unreachable: ${describeOutboundFetchFailure(transportError)}`);\n } finally {\n clearTimeout(timeout);\n }\n }\n\n /** Run one provider function: a throw or a wrong shape is NOT_SCREENED, never a crash and never \"clean\". */\n private runProvider<T>(binding: ContentSafetyEndpoint, what: string, run: () => T, describeDefect: (value: unknown) => string | undefined): T {\n let result: T;\n try {\n result = run();\n } catch (providerError) {\n throw new ContentSafetyNotScreened(`Content-safety provider \"${binding.providerRef}\" ${what} threw: ${describeCaughtError(providerError)}`);\n }\n const defect = describeDefect(result);\n if (defect !== undefined) throw new ContentSafetyNotScreened(`Content-safety provider \"${binding.providerRef}\" ${what} ${defect}.`);\n return result;\n }\n\n /**\n * The selected provider's endpoint and contract, for one operation it must declare; `undefined` when no provider is\n * selected. Throws a named CONFIGURATION error for a selected provider that cannot serve the operation.\n */\n private resolveSelectedContract(operation: ContentSafetyProvider_OperationKey): {\n providerRef: string;\n contract: ContentSafetyContract;\n configurationError: (message: string) => unknown;\n } | undefined {\n const providerRef = this.externalProvidersRegistry.getPrimaryProviderForEngineCapability(EngineCapability.AI_CONTENT_SAFETY);\n if (!providerRef) return undefined;\n const configurationError = (message: string) => this.errorBuilder.buildError(ErrorType.CONFIGURATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.CONFIGURATION,\n context: { providerRef, message },\n });\n const contract = this.externalProvidersRegistry.getProviderRuntimeContract(providerRef, ExternalProvider_ExchangeProtocol_Kind.CONTENT_SAFETY_PROVIDER);\n if (contract?.kind !== ProviderProtocolRuntimeKind.CONTENT_SAFETY) {\n throw configurationError(`Provider \"${providerRef}\" is selected for AI_CONTENT_SAFETY but declares no CONTENT_SAFETY_PROVIDER runtime contract.`);\n }\n if (!this.externalProvidersRegistry.getContentSafetySemanticOperationKeys(providerRef).includes(operation)) {\n throw configurationError(`Provider \"${providerRef}\"'s content-safety contract does not declare the '${operation}' operation.`);\n }\n return { providerRef, contract, configurationError };\n }\n\n /**\n * The endpoint every request of the contract shares: the base URL, and the API-key header. Refuses, as a CONFIGURATION\n * error, a provider whose API key is not set, exactly as an unset host slot is refused: a binding that resolves without\n * its key would read as served (to an agent's guardrail check, the organization-policy door and the boot report) and then\n * fail every call as NOT_SCREENED, so the guarded turn would run with every result withheld instead of being refused.\n * The key itself is read again at each request (`screen`, `moderate`), which is where its value is used.\n */\n private endpointOf(providerRef: string, contract: ContentSafetyContract, configurationError: (message: string) => unknown): ContentSafetyEndpoint {\n const baseUrl = this.resolveBaseUrl(providerRef, contract, configurationError);\n if (!this.externalProvidersRegistry.getProviderApiKey(providerRef, ExternalProvider_ExchangeProtocol_Kind.CONTENT_SAFETY_PROVIDER)) {\n throw configurationError(this.externalProvidersRegistry.describeMissingProviderApiKey(providerRef, ExternalProvider_ExchangeProtocol_Kind.CONTENT_SAFETY_PROVIDER));\n }\n return {\n providerRef,\n baseUrl,\n apiKeyHeaderName: contract.apiKey.headerName,\n apiKeyPrefix: contract.apiKey.prefix ?? '',\n };\n }\n\n /**\n * The selected provider's moderation binding, `undefined` when none is selected. Throws a CONFIGURATION error when the\n * provider declares no usable `outputModeration` arm, or does not assess one of `categories`: an agent asking for a\n * category its classifier cannot judge must not run as though it were judged.\n */\n private resolveFullModerationBinding(categories: readonly ContentSafety_HarmCategory[]): ContentSafetyModerationBinding | undefined {\n const selected = this.resolveSelectedContract(ContentSafetyProvider_OperationKey.MODERATE_OUTPUT);\n if (selected === undefined) return undefined;\n const { providerRef, contract, configurationError } = selected;\n // Held to shape for the reason given in `resolveFullBinding`.\n const moderation = contract.outputModeration as Partial<NonNullable<ContentSafetyContract['outputModeration']>> | undefined;\n const limits = moderation?.limits as Partial<ContentSafety_OutputModerationLimits> | undefined;\n const knownCategories = Object.values(ContentSafety_HarmCategory) as string[];\n if (!moderation || !isNonEmptyString(moderation.endpointPath)\n || typeof moderation.buildModerationRequest !== 'function' || typeof moderation.parseModerationResponse !== 'function'\n || !limits || !Number.isInteger(limits.maxCharactersPerRequest) || (limits.maxCharactersPerRequest ?? 0) < 1\n || !Array.isArray(moderation.assessedCategories) || !moderation.assessedCategories.every((category) => knownCategories.includes(category as string))) {\n throw configurationError(\n `Provider \"${providerRef}\" declares a content-safety contract without a usable \\`outputModeration\\` (endpointPath, `\n + 'buildModerationRequest, parseModerationResponse, a positive integer limits.maxCharactersPerRequest, and '\n + 'assessedCategories drawn from ContentSafety_HarmCategory), and cannot be used.',\n );\n }\n const unassessed = categories.filter((category) => !moderation.assessedCategories!.includes(category));\n if (unassessed.length > 0) {\n throw configurationError(`Provider \"${providerRef}\" does not assess the harm categories ${unassessed.map((category) => `'${category}'`).join(', ')}, `\n + 'which an agent\\'s output moderation asks for. Select a provider that does, or narrow the agent\\'s policy.');\n }\n return { ...this.endpointOf(providerRef, contract, configurationError), outputModeration: contract.outputModeration! };\n }\n\n /** The selected provider's screening binding, `undefined` when none is selected; throws a named CONFIGURATION error otherwise. */\n private resolveFullBinding(): ContentSafetyBinding | undefined {\n const selected = this.resolveSelectedContract(ContentSafetyProvider_OperationKey.SCREEN_PROMPT_INJECTION);\n if (selected === undefined) return undefined;\n const { providerRef, contract, configurationError } = selected;\n /*\n * The contract may come from a module no compilation here checked (a provider installed from the module registry\n * reaches the application through a loosely parsed companion contribution), so its functions and limits are held\n * to their shape before anything is sent — the DOCUMENT_EXTRACTION arm's refusal, for the same reason.\n */\n const promptInjection = contract.promptInjection as Partial<NonNullable<ContentSafetyContract['promptInjection']>> | undefined;\n const limits = promptInjection?.limits as Partial<ContentSafety_PromptInjectionLimits> | undefined;\n if (!promptInjection || !isNonEmptyString(promptInjection.endpointPath)\n || typeof promptInjection.buildScreenRequest !== 'function' || typeof promptInjection.parseScreenResponse !== 'function'\n || !limits || !Number.isInteger(limits.maxDocumentsPerRequest) || (limits.maxDocumentsPerRequest ?? 0) < 1\n || !Number.isInteger(limits.maxCharactersPerRequest) || (limits.maxCharactersPerRequest ?? 0) < 1) {\n throw configurationError(\n `Provider \"${providerRef}\" declares a content-safety contract without a usable \\`promptInjection\\` (endpointPath, `\n + 'buildScreenRequest, parseScreenResponse, and positive integer limits.maxDocumentsPerRequest and '\n + 'limits.maxCharactersPerRequest), and cannot be used.',\n );\n }\n return { ...this.endpointOf(providerRef, contract, configurationError), promptInjection: contract.promptInjection! };\n }\n\n /** Exactly one of `baseUrl` and `baseUrlHostEnvVarName`, through `resolveProviderContractBaseUrl` (every non-REST arm's rule). */\n private resolveBaseUrl(\n providerRef: string,\n contract: { baseUrl?: string; baseUrlHostEnvVarName?: string; apiKey?: { secretRef?: string } },\n configurationError: (message: string) => unknown,\n ): string {\n const resolution = resolveProviderContractBaseUrl({\n providerRef,\n contractLabel: 'content-safety',\n contract,\n hostAdmission: () => ({\n declaredSlots: this.externalProvidersRegistry.getProviderSecretSlots(providerRef),\n environment: this.externalProvidersRegistry.getDeclaredApplicationEnvironment(),\n }),\n });\n if ('refusal' in resolution) throw configurationError(resolution.refusal);\n return resolution.baseUrl;\n }\n\n /**\n * One trace per screening or moderation: summaries only, recorded ungated, then the sink when tracing is on. Never\n * throws. `conclusion` is the outcome that was reached, or the failure that prevented one.\n */\n private async emitTrace(\n providerRef: string,\n operation: ContentSafetyProvider_OperationKey,\n conclusion: { readonly outcome: string } | { readonly failure: string },\n summary: { characters: number; documents: number; requests: number; textRecords: number },\n startTime: number,\n ): Promise<void> {\n const callTimestamp = new Date(startTime).toISOString();\n const failed = 'failure' in conclusion;\n const trace: AgentCallTrace = {\n agentRef: CONTENT_SAFETY_TRACE_AGENT_REF,\n // A classifier call: not a model call, billed by the text records it sent (#2889), counted apart in every cost view.\n kind: AgentCallTraceKind.CLASSIFICATION,\n provider: providerRef,\n model: operation,\n callTimestamp,\n outcome: failed ? AgentCallOutcome.FAILURE : AgentCallOutcome.SUCCESS,\n input: { characters: summary.characters, documents: summary.documents, requests: summary.requests },\n // What the vendor bills (#2889): priced by a TEXT_RECORDS authority, never by tokens.\n meteredUnits: { textRecords: summary.textRecords },\n ...('outcome' in conclusion ? { output: { outcome: conclusion.outcome } } : {}),\n context: {\n callTimestamp,\n executionTime: Date.now() - startTime,\n finishedAt: new Date().toISOString(),\n // A classifier reports no tokens and requires none, so no required dimension is missing.\n usage: { tokenUsageComplete: true },\n },\n ...('failure' in conclusion ? {\n error: {\n name: operation === ContentSafetyProvider_OperationKey.MODERATE_OUTPUT ? ContentSafetyModerationOutcome.NOT_MODERATED : ContentSafetyScreeningOutcome.NOT_SCREENED,\n message: conclusion.failure,\n },\n } : {}),\n };\n try {\n await this.providerCallRecorder?.record(trace);\n } catch (recordError) {\n this.logger.warn('A content-safety call could not be recorded', { providerRef, operation, error: describeCaughtError(recordError) });\n }\n const level = this.agentTracePolicy?.level ?? AgentTraceabilityLevel.NONE;\n if (!this.agentTraceSink || level === AgentTraceabilityLevel.NONE) return;\n try {\n await this.agentTraceSink.recordAgentCall({ trace, level });\n } catch {\n // A sink failure never turns a screening into a failed one.\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"content-safety.backend.service.js","sourceRoot":"","sources":["../../../../src/external-providers/services/content-safety.backend.service.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Content-safety execution service (#2292): the ONE seam through which the engine asks a classifier about text. Two\n * questions, one per operation:\n *\n * - SCREENING (`screenForPromptInjection`): does third-party content about to reach a model carry instructions aimed\n * at it? Callers: the agent runtime, screening what an agent's tools return, and the autonomous turn, screening an\n * inbound delivery before the turn starts — for an agent that declares `contentGuardrails.promptInjection`.\n * - MODERATION (`moderateOutput`, Phase 3): how harmful is a text a model WROTE, per harm category? Caller: the agent\n * runtime's output moderator, for an agent that declares `contentGuardrails.outputModeration`. The service judges;\n * the agent's policy decides what is withheld.\n *\n * ## The line between engine and provider\n *\n * The DOCUMENT_EXTRACTION seam, at its simplest form. The provider declares PURE FUNCTIONS on its contract\n * (`promptInjection.buildScreenRequest` / `parseScreenResponse`, `outputModeration.buildModerationRequest` /\n * `parseModerationResponse`) and the limits its vendor documents; the engine owns:\n *\n * - the URL (the contract's `baseUrl`, or `https://<host>` from `baseUrlHostEnvVarName`, or a local double's\n * `http://127.0.0.1:<port>` in development and test, #2991), the API-key header, the timeout, redirects refused;\n * - SPLITTING: a text longer than one request carries is split into documents, with an overlap so an instruction of\n * up to 1,000 characters that straddles a boundary is still whole in one of them; screening batches them under both\n * declared limits, and moderation judges every part and keeps the worst severity per category;\n * - the FLOORS: a transport failure or timeout, a provider function that throws or returns the wrong shape, and a\n * verdict count that differs from the documents sent are each NOT_SCREENED. The caller withholds what was not\n * screened, so no floor can ever read as \"clean\".\n *\n * ## Outcomes\n *\n * Screening, {@link ContentSafetyScreeningOutcome}: CLEAN (every document screened, none flagged), ATTACK_DETECTED (some\n * document flagged), NOT_SCREENED (anything else). A caller releases the text on CLEAN only.\n *\n * Moderation, {@link ContentSafetyModerationOutcome}: MODERATED (a severity for EVERY category asked about, the worst\n * across the text's parts) or NOT_MODERATED (anything else — a category missing from an answer included, never read as\n * SAFE). A caller withholds what was not moderated.\n *\n * ## The organization's content-screening ceiling (#3030)\n *\n * Every screening and moderation is asked of the organization's `ai.contentSafety.textRecordsPerPeriod` ceiling before\n * anything is sent, and charged the text records it sent. A spent or unverifiable ceiling sends nothing: the result is\n * NOT_SCREENED / NOT_MODERATED carrying `spendCeilingRefusal`, so a guarded agent fails closed as it does when no\n * classifier answers, while the reason and the `MODEL_SPEND_LIMIT_REFUSED` row say it was the ceiling.\n *\n * ## Observability\n *\n * One trace per screening or moderation, through the provider-call recorder and the trace sink. Summaries only —\n * characters, documents, requests, outcome. The text never enters a trace, a log or an error context: it is content\n * somebody else wrote, or a model wrote, about to be read.\n */\nimport { injectable, inject, optional } from 'inversify';\nimport {\n ProviderCallAccount,\n AgentCallOutcome,\n AgentCallTraceKind,\n AgentTraceabilityLevel,\n EngineCapability,\n ErrorCustomMessageReference,\n ErrorType,\n describeOutboundFetchFailure,\n type AgentCallTrace,\n type AgentCallTraceSink,\n type AgentTraceabilityPolicy,\n A2ATokenBudgetDenialReason,\n ModelUsageUnit,\n readEnvironmentAgentContentGuardrails,\n tokenSpendCeilingOfModelUsageUnit,\n type EnvironmentAgentContentGuardrailsReading,\n type TokenSpendCeiling,\n} from '@wildo-ai/saas-models';\nimport { ProviderDataResidencyRefusedError, admitProviderCallUnderDataResidency } from '~wildo-backend-lib/external-providers/data-residency/provider-call-data-residency-gate.backend';\nimport {\n ContentSafetyProvider_OperationKey,\n ContentSafety_HarmCategory,\n ContentSafety_HarmSeverity,\n ExternalProvider_ExchangeProtocol_Kind,\n ProviderProtocolRuntimeKind,\n contentSafetyHarmSeverityRank,\n type ContentSafety_HarmCategoryVerdict,\n type ContentSafety_OutputModerationLimits,\n type ContentSafety_PromptInjectionLimits,\n type ContentSafety_ProviderModeration,\n type ContentSafety_ProviderScreening,\n ContentSafetyModerationOutcome,\n ContentSafetyScreeningOutcome,\n} from '@wildo-ai/external-connectors-models';\nimport type { ContentSafetyProviderScreenResponseInput, ProviderProtocolRuntimeContract } from '@wildo-ai/external-connectors-private/backend';\n\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\nimport type { LoggerService } from '~wildo-backend-lib/monitoring/logger/services/logger.service';\nimport type { ErrorBuilderBackendService } from '~wildo-backend-lib/errors/services/error-builder.backend.service';\nimport type { ExternalProvidersRegistryBackendService } from '~wildo-backend-lib/external-providers/services/external-providers-registry.backend.service';\nimport type { ProviderCallRecorderBackendService } from '~wildo-backend-lib/flows-actors/services/provider-call-recorder.backend.service';\nimport { withEngineOwnedHeaders } from '~wildo-backend-lib/security/outbound/outbound-request-headers.backend.utils';\nimport { resolveProviderContractBaseUrl } from '~wildo-backend-lib/external-providers/services/provider-http-access.backend';\nimport { describeCaughtError } from '~wildo-backend-lib/errors/utils/error-log-level-classification.backend.utils';\nimport type { ModelUsageCall, ModelUsageMeter } from '~wildo-backend-lib/flows-actors/a2a/services/a2a-token-budget.backend.service';\nimport { admitModelUsageCall, describeModelUsageCeilingRefusal, resolveModelUsageCall } from '~wildo-backend-lib/flows-actors/a2a/services/model-usage-ceiling.backend.utils';\n\n/** Per-request timeout. A classifier answers in well under a second; this bounds a hung one, and an agent waits on it. */\nexport const CONTENT_SAFETY_REQUEST_TIMEOUT_MS = 15_000;\n\n/** Attempts per request, the first included. One retry covers a dropped connection or a throttled burst. */\nexport const CONTENT_SAFETY_MAX_ATTEMPTS = 2;\n\n/**\n * The most characters the engine screens for one text. Beyond it the text is NOT_SCREENED (and so withheld) rather than\n * sent as dozens of requests: a tool result that size is not one a model should read whole either, and the bound keeps\n * one tool call from turning into an unbounded spend at the classifier.\n */\nexport const CONTENT_SAFETY_ENGINE_MAX_SCREENED_CHARACTERS = 200_000;\n\n/** The agent ref a screening trace is recorded under. */\nexport const CONTENT_SAFETY_TRACE_AGENT_REF = 'engine:content-safety';\n\n/**\n * Why a screening or a moderation was not even sent (#3030): the organization's content-screening ceiling\n * (`ai.contentSafety.textRecordsPerPeriod`) is spent or could not be checked. Its presence is what tells a ceiling from a\n * classifier that did not answer; both are NOT_SCREENED / NOT_MODERATED, so the caller withholds either way.\n */\nexport interface ContentSafetySpendCeilingRefusal {\n readonly ceiling: TokenSpendCeiling;\n readonly reason: A2ATokenBudgetDenialReason;\n}\n\n/** The result of one screening. */\nexport type ContentSafetyScreeningResult =\n | { readonly outcome: ContentSafetyScreeningOutcome.CLEAN | ContentSafetyScreeningOutcome.ATTACK_DETECTED; readonly providerRef: string }\n | {\n readonly outcome: ContentSafetyScreeningOutcome.NOT_SCREENED;\n readonly providerRef?: string;\n /** Operator-facing; never the screened text or the vendor's response body. Names the ceiling when it refused. */\n readonly reason: string;\n /** Set only when the screening was not sent because the content-screening ceiling refused it (#3030). */\n readonly spendCeilingRefusal?: ContentSafetySpendCeilingRefusal;\n };\n\n/** The result of one moderation. */\nexport type ContentSafetyModerationResult =\n | {\n readonly outcome: ContentSafetyModerationOutcome.MODERATED;\n readonly providerRef: string;\n /** One per category asked about, in the order asked: the WORST severity any part of the text reached. */\n readonly categories: readonly ContentSafety_HarmCategoryVerdict[];\n }\n | {\n readonly outcome: ContentSafetyModerationOutcome.NOT_MODERATED;\n readonly providerRef?: string;\n /** Operator-facing; never the text or the vendor's response body. Names the ceiling when it refused. */\n readonly reason: string;\n /** Set only when the moderation was not sent because the content-screening ceiling refused it (#3030). */\n readonly spendCeilingRefusal?: ContentSafetySpendCeilingRefusal;\n };\n\ntype ContentSafetyContract = Extract<ProviderProtocolRuntimeContract, { kind: typeof ProviderProtocolRuntimeKind.CONTENT_SAFETY }>;\n\n/** The resolved provider and everything a request needs, except the key and the operation's own arm. */\ninterface ContentSafetyEndpoint {\n providerRef: string;\n baseUrl: string;\n apiKeyHeaderName: string;\n apiKeyPrefix: string;\n}\n\n/** The endpoint and a held-to-shape `promptInjection` arm. */\ninterface ContentSafetyBinding extends ContentSafetyEndpoint {\n promptInjection: NonNullable<ContentSafetyContract['promptInjection']>;\n}\n\n/** The endpoint and a held-to-shape `outputModeration` arm. */\ninterface ContentSafetyModerationBinding extends ContentSafetyEndpoint {\n outputModeration: NonNullable<ContentSafetyContract['outputModeration']>;\n}\n\n/** \"Can this operation run here?\" Absent only when no provider fills the slot; a selected provider that cannot serve throws. */\nexport type ContentSafetyBindingResolution =\n | { configured: true; providerRef: string }\n | { configured: false; reason: 'no_provider_for_capability' };\n\n/** Why a screening could not complete, carried to NOT_SCREENED. */\nclass ContentSafetyNotScreened extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ContentSafetyNotScreened';\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.length > 0;\n}\n\n/**\n * Split a text into documents no longer than `maxCharacters`, each overlapping the previous one by a tenth of the window\n * (at most 1,000), so an instruction up to that long that straddles a boundary is whole in one of them; a longer one is\n * split like any text. Lengths are measured in UTF-16 code units (a JavaScript string's `length`), which is never fewer\n * than code points, so a document fits a limit stated in characters whichever of the two a vendor counts; and a\n * document is only ever cut between code points, never inside a surrogate pair.\n */\nexport function splitForScreening(text: string, maxCharacters: number): string[] {\n if (text.length <= maxCharacters) return [text];\n const codePoints = Array.from(text);\n const overlap = Math.min(1_000, Math.floor(maxCharacters / 10));\n const documents: string[] = [];\n let start = 0;\n while (start < codePoints.length) {\n // Take code points while the document still fits.\n let end = start;\n let units = 0;\n while (end < codePoints.length && units + codePoints[end]!.length <= maxCharacters) {\n units += codePoints[end]!.length;\n end += 1;\n }\n if (end === start) end = start + 1; // A single code point longer than the window cannot occur for a window ≥ 2.\n documents.push(codePoints.slice(start, end).join(''));\n if (end >= codePoints.length) break;\n // Step back by the overlap, measured in code units, but always forward.\n let back = end;\n let backUnits = 0;\n while (back > start + 1 && backUnits + codePoints[back - 1]!.length <= overlap) {\n backUnits += codePoints[back - 1]!.length;\n back -= 1;\n }\n start = back;\n }\n return documents;\n}\n\n/**\n * The text records one document sent to a content-safety vendor is billed as (#2889): one per started block of 1,000\n * characters counted in Unicode code points, and at least one for a document that was sent at all. How Azure AI Content\n * Safety bills its Text API: \"A text record in the S tier contains up to 1,000 characters as measured by Unicode code\n * points\", one \"for each unit of 1,000 characters\".\n * spec-cite: https://azure.microsoft.com/en-us/pricing/details/cognitive-services/content-safety/\n */\nexport function contentSafetyTextRecordsOf(document: string): number {\n let codePoints = 0;\n for (const _ of document) codePoints += 1;\n return Math.max(1, Math.ceil(codePoints / 1_000));\n}\n\n/** Group documents into requests under both limits, in order. Each document already fits one request on its own. */\nexport function batchForScreening(documents: readonly string[], limits: ContentSafety_PromptInjectionLimits): string[][] {\n const batches: string[][] = [];\n let current: string[] = [];\n let currentCharacters = 0;\n for (const document of documents) {\n const characters = document.length;\n if (current.length > 0 && (current.length >= limits.maxDocumentsPerRequest || currentCharacters + characters > limits.maxCharactersPerRequest)) {\n batches.push(current);\n current = [];\n currentCharacters = 0;\n }\n current.push(document);\n currentCharacters += characters;\n }\n if (current.length > 0) batches.push(current);\n return batches;\n}\n\n/** Why a provider function's return value is not the contract's shape, or `undefined`. */\nfunction describeScreeningDefect(value: unknown, documentsSent: number): string | undefined {\n if (!isRecord(value) || typeof value.screened !== 'boolean') return 'returned no `screened` verdict';\n if (!value.screened) return typeof value.message === 'string' ? undefined : 'returned a refusal without a message';\n const documents = value.documents;\n if (!Array.isArray(documents) || !documents.every((verdict) => isRecord(verdict) && typeof verdict.attackDetected === 'boolean')) {\n return 'returned verdicts without a boolean `attackDetected` each';\n }\n return documents.length === documentsSent ? undefined : `returned ${documents.length} verdict(s) for ${documentsSent} document(s)`;\n}\n\n/** Why a moderation parser's return value is not the contract's shape, or `undefined`. */\nfunction describeModerationDefect(value: unknown): string | undefined {\n if (!isRecord(value) || typeof value.moderated !== 'boolean') return 'returned no `moderated` verdict';\n if (!value.moderated) return typeof value.message === 'string' ? undefined : 'returned a refusal without a message';\n const categories = value.categories;\n const knownCategories = Object.values(ContentSafety_HarmCategory) as string[];\n const knownSeverities = Object.values(ContentSafety_HarmSeverity) as string[];\n if (!Array.isArray(categories) || !categories.every((verdict) => isRecord(verdict)\n && knownCategories.includes(verdict.category as string) && knownSeverities.includes(verdict.severity as string))) {\n return 'returned verdicts that are not a known category with a known severity each';\n }\n return undefined;\n}\n\nfunction describeRequestDefect(value: unknown): string | undefined {\n if (!isRecord(value) || typeof value.body !== 'string') return 'returned no string `body`';\n return value.transportHeaders === undefined || isRecord(value.transportHeaders) ? undefined : 'returned `transportHeaders` that are not an object';\n}\n\n@injectable()\nexport class ContentSafetyBackendService {\n constructor(\n @inject(SAAS_SERVICE_TYPES.Logger) private readonly logger: LoggerService,\n @inject(SAAS_SERVICE_TYPES.ErrorBuilderService) private readonly errorBuilder: ErrorBuilderBackendService,\n @inject(SAAS_SERVICE_TYPES.ExternalProvidersRegistryService) private readonly externalProvidersRegistry: ExternalProvidersRegistryBackendService,\n @inject(SAAS_SERVICE_TYPES.AgentCallTraceSink) @optional() private readonly agentTraceSink?: AgentCallTraceSink,\n @inject(SAAS_SERVICE_TYPES.AgentTraceabilityPolicy) @optional() private readonly agentTracePolicy?: AgentTraceabilityPolicy,\n @inject(SAAS_SERVICE_TYPES.ProviderCallRecorder) @optional() private readonly providerCallRecorder?: ProviderCallRecorderBackendService,\n // #3030: the organization's content-screening ceiling, asked before every screening and moderation and charged the\n // text records each sent. Appended LAST.\n @inject(SAAS_SERVICE_TYPES.A2ATokenBudgetService) @optional() private readonly modelUsage?: ModelUsageMeter,\n ) {}\n\n /**\n * #3030: ask the content-screening ceiling for the call about to be made. `undefined` when it may be sent; otherwise the\n * refusal, worded for the NOT_SCREENED / NOT_MODERATED reason. Never throws: a gate that could not even be asked is\n * read as an unverifiable ceiling and refuses (fail closed), since every failure on this path must be a withheld text.\n */\n private async admitScreening(): Promise<{ call: ModelUsageCall | undefined; refusal?: { reason: string; spendCeilingRefusal: ContentSafetySpendCeilingRefusal } }> {\n try {\n const call = await resolveModelUsageCall(ModelUsageUnit.SCREENING_TEXT_RECORDS, undefined, this.providerCallRecorder);\n const refusal = await admitModelUsageCall(this.modelUsage, call);\n if (!refusal) return { call };\n return { call, refusal: { reason: describeModelUsageCeilingRefusal(refusal), spendCeilingRefusal: { ceiling: refusal.ceiling, reason: refusal.reason } } };\n } catch (error) {\n this.logger.warn('The content-screening ceiling could not be asked; the text is not screened', { error: describeCaughtError(error) });\n // The sentence is the shared one (`describeModelUsageCeilingRefusal`), so this path cannot word it differently.\n const unverifiable = { unit: ModelUsageUnit.SCREENING_TEXT_RECORDS, reason: A2ATokenBudgetDenialReason.ALLOWANCE_UNVERIFIABLE };\n return {\n call: undefined,\n refusal: {\n reason: describeModelUsageCeilingRefusal(unverifiable),\n spendCeilingRefusal: { ceiling: tokenSpendCeilingOfModelUsageUnit(unverifiable.unit), reason: unverifiable.reason },\n },\n };\n }\n }\n\n /** #3030: charge the text records a screening or moderation sent (counted once the vendor answered). Never throws. */\n private chargeScreening(call: ModelUsageCall | undefined, textRecords: number): void {\n if (!call) return;\n try {\n this.modelUsage?.recordModelUsage(call, textRecords);\n } catch (error) {\n this.logger.warn('A content-safety call could not be charged to its ceiling', { error: describeCaughtError(error) });\n }\n }\n\n /**\n * What this environment declared about agents' classifier-backed guardrails where no classifier serves them\n * (`agentContentGuardrails` in `wildo.infra.<env>.config.ts`, projected to `WILDO_AGENT_CONTENT_GUARDRAILS`). Read once,\n * when the service is built: the posture of a running process does not change under it. An unreadable value reads as\n * REFUSE (fail closed), and the startup report says so.\n */\n private readonly guardrailsWithoutClassifier: EnvironmentAgentContentGuardrailsReading = readEnvironmentAgentContentGuardrails(process.env);\n\n /** The environment's declaration, as read when the service was built. */\n public agentGuardrailsWithoutClassifier(): EnvironmentAgentContentGuardrailsReading {\n return this.guardrailsWithoutClassifier;\n }\n\n /**\n * Whether a classifier for `operation` is PRESENT in this environment, as opposed to absent from it. Absent (`false`)\n * in exactly three cases, each a fact of this environment's configuration:\n *\n * - the configuration declares no provider for `AI_CONTENT_SAFETY`;\n * - the selected provider's contract does not offer `operation` (`openai-moderation` declares no screening);\n * - the selected provider's credentials are not authored HERE: its API key slot, or the host slot it reads its endpoint\n * from, is unset in this environment. The classifier is declared once for the whole application, so this is the one\n * way an environment can be without it while another has it (staging without an Azure key, production with one).\n *\n * Everything else is `true` (present): a declared provider that did not load (a data residency refusal), a malformed\n * host, a category it does not assess, a key that is set and wrong, an outage, and anything this cannot read. An\n * environment that declares it runs agents unguarded where no classifier is present must still refuse, or withhold,\n * when one is there and broken, because that is a failure, not the absence the environment declared.\n */\n public classifierPresentFor(operation: ContentSafetyProvider_OperationKey): boolean {\n try {\n const providerRef = this.externalProvidersRegistry.getPrimaryProviderForEngineCapability(EngineCapability.AI_CONTENT_SAFETY);\n if (!providerRef) return this.externalProvidersRegistry.declaresProviderForEngineCapability(EngineCapability.AI_CONTENT_SAFETY);\n if (!this.externalProvidersRegistry.getContentSafetySemanticOperationKeys(providerRef).includes(operation)) return false;\n if (!this.externalProvidersRegistry.getProviderApiKey(providerRef, ExternalProvider_ExchangeProtocol_Kind.CONTENT_SAFETY_PROVIDER)) return false;\n const contract = this.externalProvidersRegistry.getProviderRuntimeContract(providerRef, ExternalProvider_ExchangeProtocol_Kind.CONTENT_SAFETY_PROVIDER);\n const hostVariable = contract?.kind === ProviderProtocolRuntimeKind.CONTENT_SAFETY ? contract.baseUrlHostEnvVarName : undefined;\n if (hostVariable !== undefined && !process.env[hostVariable]?.trim()) return false;\n return true;\n } catch {\n return true;\n }\n }\n\n /**\n * Whether this process records the screenings it makes (a provider-call recorder is bound). An agent that declares\n * screening refuses to run where it does not: a screening nobody can show happened is the gap R7 exists to close.\n */\n public recordsScreenings(): boolean {\n return this.providerCallRecorder !== undefined;\n }\n\n /**\n * Whether a classifier is selected for `AI_CONTENT_SAFETY`, and serves prompt-injection screening. `configured: false`\n * only when nothing is selected; a selected provider that cannot serve THROWS a named CONFIGURATION error, because an\n * operator's mistake must not read as a deliberate absence.\n */\n public resolvePromptInjectionBinding(): ContentSafetyBindingResolution {\n const binding = this.resolveFullBinding();\n return binding === undefined ? { configured: false, reason: 'no_provider_for_capability' } : { configured: true, providerRef: binding.providerRef };\n }\n\n /**\n * Whether a classifier is selected for `AI_CONTENT_SAFETY` that moderates output in EVERY one of `categories`. Same\n * contract as {@link resolvePromptInjectionBinding}: absent only when nothing is selected, and a selected provider that\n * cannot serve — no `moderateOutput` operation, or a category it does not assess — throws a CONFIGURATION error.\n */\n public resolveOutputModerationBinding(categories: readonly ContentSafety_HarmCategory[]): ContentSafetyBindingResolution {\n const binding = this.resolveFullModerationBinding(categories);\n return binding === undefined ? { configured: false, reason: 'no_provider_for_capability' } : { configured: true, providerRef: binding.providerRef };\n }\n\n /**\n * Screen one text for a prompt-injection attack, as a DOCUMENT (content somebody else wrote, about to reach a model).\n * Never throws: every failure is NOT_SCREENED, which the caller withholds.\n *\n * assurance-control: WILDO.SECURITY.FAIL_CLOSED — a text that could not be fully screened is NOT_SCREENED, never clean.\n * assurance-control: WILDO.INTEGRATION.OUTBOUND_ACTIVITY_AUDIT — every screening leaves one provider-call record\n * (provider, characters, documents, requests, outcome), never the text.\n * assurance-control: WILDO.PRIVACY.DATA_MINIMIZATION — the provider's request builder receives the documents and\n * nothing else: no tenant, user, record or agent.\n */\n public async screenForPromptInjection(text: string): Promise<ContentSafetyScreeningResult> {\n let binding: ContentSafetyBinding | undefined;\n try {\n binding = this.resolveFullBinding();\n } catch (error) {\n return { outcome: ContentSafetyScreeningOutcome.NOT_SCREENED, reason: describeCaughtError(error) };\n }\n if (binding === undefined) {\n return { outcome: ContentSafetyScreeningOutcome.NOT_SCREENED, reason: 'No provider is selected for AI_CONTENT_SAFETY.' };\n }\n // #3030: a spent or unverifiable content-screening ceiling sends nothing and leaves no provider-call record: the text\n // is NOT_SCREENED, so the caller withholds it exactly as when no classifier answers, and the reason names the ceiling.\n const admission = await this.admitScreening();\n if (admission.refusal) {\n return { outcome: ContentSafetyScreeningOutcome.NOT_SCREENED, providerRef: binding.providerRef, ...admission.refusal };\n }\n const startTime = Date.now();\n const characters = text.length;\n const summary = { characters, documents: 0, requests: 0, textRecords: 0 };\n let result: ContentSafetyScreeningResult;\n try {\n result = await this.screen(binding, text, characters, summary);\n } catch (error) {\n result = {\n outcome: ContentSafetyScreeningOutcome.NOT_SCREENED,\n providerRef: binding.providerRef,\n reason: error instanceof ContentSafetyNotScreened ? error.message : describeCaughtError(error),\n };\n }\n this.chargeScreening(admission.call, summary.textRecords);\n await this.emitTrace(binding.providerRef, ContentSafetyProvider_OperationKey.SCREEN_PROMPT_INJECTION,\n result.outcome === ContentSafetyScreeningOutcome.NOT_SCREENED ? { failure: result.reason } : { outcome: result.outcome }, summary, startTime);\n return result;\n }\n\n /**\n * Judge one text a model WROTE in each of `categories`, which must be non-empty. Never throws: every failure is\n * NOT_MODERATED, which the caller withholds. A text longer than one request is split (with the screening splitter's\n * overlap, so a phrase across a boundary is whole in one part) and every part judged; each category's verdict is the\n * worst severity any part reached.\n *\n * assurance-control: WILDO.SECURITY.FAIL_CLOSED — a text not judged in every category asked about is NOT_MODERATED,\n * never SAFE.\n * assurance-control: WILDO.INTEGRATION.OUTBOUND_ACTIVITY_AUDIT — every moderation leaves one provider-call record\n * (provider, characters, parts, requests, outcome), never the text.\n * assurance-control: WILDO.PRIVACY.DATA_MINIMIZATION — the provider's request builder receives the text and the\n * categories, nothing else.\n */\n public async moderateOutput(text: string, categories: readonly ContentSafety_HarmCategory[]): Promise<ContentSafetyModerationResult> {\n if (categories.length === 0) {\n return { outcome: ContentSafetyModerationOutcome.NOT_MODERATED, reason: 'No harm category was asked about.' };\n }\n let binding: ContentSafetyModerationBinding | undefined;\n try {\n binding = this.resolveFullModerationBinding(categories);\n } catch (error) {\n return { outcome: ContentSafetyModerationOutcome.NOT_MODERATED, reason: describeCaughtError(error) };\n }\n if (binding === undefined) {\n return { outcome: ContentSafetyModerationOutcome.NOT_MODERATED, reason: 'No provider is selected for AI_CONTENT_SAFETY.' };\n }\n // #3030: the same ceiling as screening (a moderation is billed in the same text records): refused, nothing is sent,\n // and the output is NOT_MODERATED, so it is withheld, with the ceiling named.\n const admission = await this.admitScreening();\n if (admission.refusal) {\n return { outcome: ContentSafetyModerationOutcome.NOT_MODERATED, providerRef: binding.providerRef, ...admission.refusal };\n }\n const startTime = Date.now();\n const summary = { characters: text.length, documents: 0, requests: 0, textRecords: 0 };\n let result: ContentSafetyModerationResult;\n try {\n result = await this.moderate(binding, text, categories, summary);\n } catch (error) {\n result = {\n outcome: ContentSafetyModerationOutcome.NOT_MODERATED,\n providerRef: binding.providerRef,\n reason: error instanceof ContentSafetyNotScreened ? error.message : describeCaughtError(error),\n };\n }\n this.chargeScreening(admission.call, summary.textRecords);\n await this.emitTrace(binding.providerRef, ContentSafetyProvider_OperationKey.MODERATE_OUTPUT,\n result.outcome === ContentSafetyModerationOutcome.NOT_MODERATED ? { failure: result.reason } : { outcome: result.outcome }, summary, startTime);\n return result;\n }\n\n /**\n * #2294: an organization's data residency, before the text leaves. A refusal is reported as text NOT screened, the\n * one answer every caller already handles (each applies its own fail-closed or fail-open posture), with the gate's\n * audit row saying why.\n */\n private async admitUnderDataResidency(providerRef: string): Promise<void> {\n try {\n await admitProviderCallUnderDataResidency({ providerRef, account: ProviderCallAccount.APPLICATION });\n } catch (error) {\n if (error instanceof ProviderDataResidencyRefusedError) throw new ContentSafetyNotScreened(error.message);\n throw error;\n }\n }\n\n private async moderate(\n binding: ContentSafetyModerationBinding,\n text: string,\n categories: readonly ContentSafety_HarmCategory[],\n summary: { documents: number; requests: number; textRecords: number },\n ): Promise<ContentSafetyModerationResult> {\n if (text.length > CONTENT_SAFETY_ENGINE_MAX_SCREENED_CHARACTERS) {\n throw new ContentSafetyNotScreened(`The text is ${text.length} characters long, over the ${CONTENT_SAFETY_ENGINE_MAX_SCREENED_CHARACTERS} the engine moderates.`);\n }\n await this.admitUnderDataResidency(binding.providerRef);\n const apiKey = this.externalProvidersRegistry.getProviderApiKey(binding.providerRef, ExternalProvider_ExchangeProtocol_Kind.CONTENT_SAFETY_PROVIDER);\n if (!apiKey) {\n throw new ContentSafetyNotScreened(this.externalProvidersRegistry.describeMissingProviderApiKey(binding.providerRef, ExternalProvider_ExchangeProtocol_Kind.CONTENT_SAFETY_PROVIDER));\n }\n const parts = splitForScreening(text, Math.min(binding.outputModeration.limits.maxCharactersPerRequest, CONTENT_SAFETY_ENGINE_MAX_SCREENED_CHARACTERS));\n summary.documents = parts.length;\n const worst = new Map<ContentSafety_HarmCategory, ContentSafety_HarmSeverity>();\n for (const part of parts) {\n summary.requests += 1;\n const moderation = await this.moderatePart(binding, apiKey, part, categories);\n // Counted once the vendor ANSWERED (#2889, review F5): the count is a claim of what was billed, and an answer is\n // the evidence that the text was processed. A request that failed in transport or was refused is not counted.\n summary.textRecords += contentSafetyTextRecordsOf(part);\n for (const category of categories) {\n const verdict = moderation.categories.find((candidate) => candidate.category === category);\n // A category asked about and not answered was not judged: never read as SAFE.\n if (verdict === undefined) {\n throw new ContentSafetyNotScreened(`Content-safety provider \"${binding.providerRef}\" returned no verdict for the '${category}' category.`);\n }\n const previous = worst.get(category);\n if (previous === undefined || contentSafetyHarmSeverityRank(verdict.severity) > contentSafetyHarmSeverityRank(previous)) worst.set(category, verdict.severity);\n }\n }\n return {\n outcome: ContentSafetyModerationOutcome.MODERATED,\n providerRef: binding.providerRef,\n categories: categories.map((category) => ({ category, severity: worst.get(category)! })),\n };\n }\n\n /** One moderation request, retried once on any failure; a refusal or a defect after the last attempt is NOT_MODERATED. */\n private async moderatePart(\n binding: ContentSafetyModerationBinding,\n apiKey: string,\n text: string,\n categories: readonly ContentSafety_HarmCategory[],\n ): Promise<Extract<ContentSafety_ProviderModeration, { moderated: true }>> {\n let lastFailure = 'no attempt was made';\n for (let attempt = 1; attempt <= CONTENT_SAFETY_MAX_ATTEMPTS; attempt += 1) {\n try {\n const request = this.runProvider(binding, 'moderation request builder',\n () => binding.outputModeration.buildModerationRequest({ text, categories }), describeRequestDefect);\n const response = await this.send(binding, apiKey, binding.outputModeration.endpointPath, request.body, request.transportHeaders);\n const moderation = this.runProvider(binding, 'moderation response parser',\n () => binding.outputModeration.parseModerationResponse(response), describeModerationDefect);\n // `=== true`: this compiler configuration narrows the literal discriminant only on the explicit comparison.\n if (moderation.moderated === true) return moderation;\n if (moderation.moderated === false) lastFailure = `Content-safety provider \"${binding.providerRef}\" refused the moderation: ${moderation.message}`;\n } catch (error) {\n lastFailure = error instanceof ContentSafetyNotScreened ? error.message : describeCaughtError(error);\n }\n }\n throw new ContentSafetyNotScreened(lastFailure);\n }\n\n private async screen(\n binding: ContentSafetyBinding,\n text: string,\n characters: number,\n summary: { documents: number; requests: number; textRecords: number },\n ): Promise<ContentSafetyScreeningResult> {\n if (characters > CONTENT_SAFETY_ENGINE_MAX_SCREENED_CHARACTERS) {\n throw new ContentSafetyNotScreened(`The text is ${characters} characters long, over the ${CONTENT_SAFETY_ENGINE_MAX_SCREENED_CHARACTERS} the engine screens.`);\n }\n await this.admitUnderDataResidency(binding.providerRef);\n const apiKey = this.externalProvidersRegistry.getProviderApiKey(binding.providerRef, ExternalProvider_ExchangeProtocol_Kind.CONTENT_SAFETY_PROVIDER);\n if (!apiKey) {\n throw new ContentSafetyNotScreened(this.externalProvidersRegistry.describeMissingProviderApiKey(binding.providerRef, ExternalProvider_ExchangeProtocol_Kind.CONTENT_SAFETY_PROVIDER));\n }\n const { limits } = binding.promptInjection;\n // A document never exceeds what one request may carry, so every batch below holds at least one.\n const documents = splitForScreening(text, Math.min(limits.maxCharactersPerRequest, CONTENT_SAFETY_ENGINE_MAX_SCREENED_CHARACTERS));\n summary.documents = documents.length;\n for (const batch of batchForScreening(documents, limits)) {\n summary.requests += 1;\n const screening = await this.screenBatch(binding, apiKey, batch);\n // Only the batches the vendor answered are counted (#2889, review F5): screening stops at the first attack, and a\n // request that failed in transport or was refused is no evidence the text was processed.\n for (const document of batch) summary.textRecords += contentSafetyTextRecordsOf(document);\n if (screening.documents.some((verdict) => verdict.attackDetected)) {\n return { outcome: ContentSafetyScreeningOutcome.ATTACK_DETECTED, providerRef: binding.providerRef };\n }\n }\n return { outcome: ContentSafetyScreeningOutcome.CLEAN, providerRef: binding.providerRef };\n }\n\n /** One request, retried once on any failure; a refusal or a defect after the last attempt is NOT_SCREENED. */\n private async screenBatch(\n binding: ContentSafetyBinding,\n apiKey: string,\n documents: readonly string[],\n ): Promise<Extract<ContentSafety_ProviderScreening, { screened: true }>> {\n let lastFailure = 'no attempt was made';\n for (let attempt = 1; attempt <= CONTENT_SAFETY_MAX_ATTEMPTS; attempt += 1) {\n try {\n const request = this.runProvider(binding, 'request builder', () => binding.promptInjection.buildScreenRequest({ documents }), describeRequestDefect);\n const response = await this.send(binding, apiKey, binding.promptInjection.endpointPath, request.body, request.transportHeaders);\n const screening = this.runProvider(binding, 'response parser', () => binding.promptInjection.parseScreenResponse(response),\n (value) => describeScreeningDefect(value, documents.length));\n // `=== true`: this compiler configuration narrows the literal discriminant only on the explicit comparison.\n if (screening.screened === true) return screening;\n if (screening.screened === false) lastFailure = `Content-safety provider \"${binding.providerRef}\" refused the screening: ${screening.message}`;\n } catch (error) {\n lastFailure = error instanceof ContentSafetyNotScreened ? error.message : describeCaughtError(error);\n }\n }\n throw new ContentSafetyNotScreened(lastFailure);\n }\n\n private async send(\n binding: ContentSafetyEndpoint,\n apiKey: string,\n endpointPath: string,\n body: string,\n transportHeaders: Readonly<Record<string, string>> | undefined,\n ): Promise<ContentSafetyProviderScreenResponseInput> {\n const url = `${binding.baseUrl.replace(/\\/+$/, '')}/${endpointPath.replace(/^\\/+/, '')}`;\n const abortController = new AbortController();\n const timeout = setTimeout(() => abortController.abort(), CONTENT_SAFETY_REQUEST_TIMEOUT_MS);\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: withEngineOwnedHeaders(transportHeaders ?? {}, { [binding.apiKeyHeaderName]: `${binding.apiKeyPrefix}${apiKey}` }),\n body,\n signal: abortController.signal,\n redirect: 'error',\n });\n const responseText = await response.text();\n const headers: Record<string, string> = {};\n response.headers.forEach((value, key) => { headers[key.toLowerCase()] = value; });\n let parsedBody: unknown = undefined;\n if (responseText.length > 0) {\n try { parsedBody = JSON.parse(responseText); } catch { parsedBody = responseText; }\n }\n return { status: response.status, headers, body: parsedBody };\n } catch (transportError) {\n // By name and code only (#2407): fetch's own message can restate the key sent in a header.\n throw new ContentSafetyNotScreened(`Content-safety provider \"${binding.providerRef}\" was unreachable: ${describeOutboundFetchFailure(transportError)}`);\n } finally {\n clearTimeout(timeout);\n }\n }\n\n /** Run one provider function: a throw or a wrong shape is NOT_SCREENED, never a crash and never \"clean\". */\n private runProvider<T>(binding: ContentSafetyEndpoint, what: string, run: () => T, describeDefect: (value: unknown) => string | undefined): T {\n let result: T;\n try {\n result = run();\n } catch (providerError) {\n throw new ContentSafetyNotScreened(`Content-safety provider \"${binding.providerRef}\" ${what} threw: ${describeCaughtError(providerError)}`);\n }\n const defect = describeDefect(result);\n if (defect !== undefined) throw new ContentSafetyNotScreened(`Content-safety provider \"${binding.providerRef}\" ${what} ${defect}.`);\n return result;\n }\n\n /**\n * The selected provider's endpoint and contract, for one operation it must declare; `undefined` when no provider is\n * selected. Throws a named CONFIGURATION error for a selected provider that cannot serve the operation.\n */\n private resolveSelectedContract(operation: ContentSafetyProvider_OperationKey): {\n providerRef: string;\n contract: ContentSafetyContract;\n configurationError: (message: string) => unknown;\n } | undefined {\n const providerRef = this.externalProvidersRegistry.getPrimaryProviderForEngineCapability(EngineCapability.AI_CONTENT_SAFETY);\n if (!providerRef) return undefined;\n const configurationError = (message: string) => this.errorBuilder.buildError(ErrorType.CONFIGURATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.CONFIGURATION,\n context: { providerRef, message },\n });\n const contract = this.externalProvidersRegistry.getProviderRuntimeContract(providerRef, ExternalProvider_ExchangeProtocol_Kind.CONTENT_SAFETY_PROVIDER);\n if (contract?.kind !== ProviderProtocolRuntimeKind.CONTENT_SAFETY) {\n throw configurationError(`Provider \"${providerRef}\" is selected for AI_CONTENT_SAFETY but declares no CONTENT_SAFETY_PROVIDER runtime contract.`);\n }\n if (!this.externalProvidersRegistry.getContentSafetySemanticOperationKeys(providerRef).includes(operation)) {\n throw configurationError(`Provider \"${providerRef}\"'s content-safety contract does not declare the '${operation}' operation.`);\n }\n return { providerRef, contract, configurationError };\n }\n\n /**\n * The endpoint every request of the contract shares: the base URL, and the API-key header. Refuses, as a CONFIGURATION\n * error, a provider whose API key is not set, exactly as an unset host slot is refused: a binding that resolves without\n * its key would read as served (to an agent's guardrail check, the organization-policy door and the boot report) and then\n * fail every call as NOT_SCREENED, so the guarded turn would run with every result withheld instead of being refused.\n * The key itself is read again at each request (`screen`, `moderate`), which is where its value is used.\n */\n private endpointOf(providerRef: string, contract: ContentSafetyContract, configurationError: (message: string) => unknown): ContentSafetyEndpoint {\n const baseUrl = this.resolveBaseUrl(providerRef, contract, configurationError);\n if (!this.externalProvidersRegistry.getProviderApiKey(providerRef, ExternalProvider_ExchangeProtocol_Kind.CONTENT_SAFETY_PROVIDER)) {\n throw configurationError(this.externalProvidersRegistry.describeMissingProviderApiKey(providerRef, ExternalProvider_ExchangeProtocol_Kind.CONTENT_SAFETY_PROVIDER));\n }\n return {\n providerRef,\n baseUrl,\n apiKeyHeaderName: contract.apiKey.headerName,\n apiKeyPrefix: contract.apiKey.prefix ?? '',\n };\n }\n\n /**\n * The selected provider's moderation binding, `undefined` when none is selected. Throws a CONFIGURATION error when the\n * provider declares no usable `outputModeration` arm, or does not assess one of `categories`: an agent asking for a\n * category its classifier cannot judge must not run as though it were judged.\n */\n private resolveFullModerationBinding(categories: readonly ContentSafety_HarmCategory[]): ContentSafetyModerationBinding | undefined {\n const selected = this.resolveSelectedContract(ContentSafetyProvider_OperationKey.MODERATE_OUTPUT);\n if (selected === undefined) return undefined;\n const { providerRef, contract, configurationError } = selected;\n // Held to shape for the reason given in `resolveFullBinding`.\n const moderation = contract.outputModeration as Partial<NonNullable<ContentSafetyContract['outputModeration']>> | undefined;\n const limits = moderation?.limits as Partial<ContentSafety_OutputModerationLimits> | undefined;\n const knownCategories = Object.values(ContentSafety_HarmCategory) as string[];\n if (!moderation || !isNonEmptyString(moderation.endpointPath)\n || typeof moderation.buildModerationRequest !== 'function' || typeof moderation.parseModerationResponse !== 'function'\n || !limits || !Number.isInteger(limits.maxCharactersPerRequest) || (limits.maxCharactersPerRequest ?? 0) < 1\n || !Array.isArray(moderation.assessedCategories) || !moderation.assessedCategories.every((category) => knownCategories.includes(category as string))) {\n throw configurationError(\n `Provider \"${providerRef}\" declares a content-safety contract without a usable \\`outputModeration\\` (endpointPath, `\n + 'buildModerationRequest, parseModerationResponse, a positive integer limits.maxCharactersPerRequest, and '\n + 'assessedCategories drawn from ContentSafety_HarmCategory), and cannot be used.',\n );\n }\n const unassessed = categories.filter((category) => !moderation.assessedCategories!.includes(category));\n if (unassessed.length > 0) {\n throw configurationError(`Provider \"${providerRef}\" does not assess the harm categories ${unassessed.map((category) => `'${category}'`).join(', ')}, `\n + 'which an agent\\'s output moderation asks for. Select a provider that does, or narrow the agent\\'s policy.');\n }\n return { ...this.endpointOf(providerRef, contract, configurationError), outputModeration: contract.outputModeration! };\n }\n\n /** The selected provider's screening binding, `undefined` when none is selected; throws a named CONFIGURATION error otherwise. */\n private resolveFullBinding(): ContentSafetyBinding | undefined {\n const selected = this.resolveSelectedContract(ContentSafetyProvider_OperationKey.SCREEN_PROMPT_INJECTION);\n if (selected === undefined) return undefined;\n const { providerRef, contract, configurationError } = selected;\n /*\n * The contract may come from a module no compilation here checked (a provider installed from the module registry\n * reaches the application through a loosely parsed companion contribution), so its functions and limits are held\n * to their shape before anything is sent — the DOCUMENT_EXTRACTION arm's refusal, for the same reason.\n */\n const promptInjection = contract.promptInjection as Partial<NonNullable<ContentSafetyContract['promptInjection']>> | undefined;\n const limits = promptInjection?.limits as Partial<ContentSafety_PromptInjectionLimits> | undefined;\n if (!promptInjection || !isNonEmptyString(promptInjection.endpointPath)\n || typeof promptInjection.buildScreenRequest !== 'function' || typeof promptInjection.parseScreenResponse !== 'function'\n || !limits || !Number.isInteger(limits.maxDocumentsPerRequest) || (limits.maxDocumentsPerRequest ?? 0) < 1\n || !Number.isInteger(limits.maxCharactersPerRequest) || (limits.maxCharactersPerRequest ?? 0) < 1) {\n throw configurationError(\n `Provider \"${providerRef}\" declares a content-safety contract without a usable \\`promptInjection\\` (endpointPath, `\n + 'buildScreenRequest, parseScreenResponse, and positive integer limits.maxDocumentsPerRequest and '\n + 'limits.maxCharactersPerRequest), and cannot be used.',\n );\n }\n return { ...this.endpointOf(providerRef, contract, configurationError), promptInjection: contract.promptInjection! };\n }\n\n /** Exactly one of `baseUrl` and `baseUrlHostEnvVarName`, through `resolveProviderContractBaseUrl` (every non-REST arm's rule). */\n private resolveBaseUrl(\n providerRef: string,\n contract: { baseUrl?: string; baseUrlHostEnvVarName?: string; apiKey?: { secretRef?: string } },\n configurationError: (message: string) => unknown,\n ): string {\n const resolution = resolveProviderContractBaseUrl({\n providerRef,\n contractLabel: 'content-safety',\n contract,\n hostAdmission: () => ({\n declaredSlots: this.externalProvidersRegistry.getProviderSecretSlots(providerRef),\n environment: this.externalProvidersRegistry.getDeclaredApplicationEnvironment(),\n }),\n });\n if ('refusal' in resolution) throw configurationError(resolution.refusal);\n return resolution.baseUrl;\n }\n\n /**\n * One trace per screening or moderation: summaries only, recorded ungated, then the sink when tracing is on. Never\n * throws. `conclusion` is the outcome that was reached, or the failure that prevented one.\n */\n private async emitTrace(\n providerRef: string,\n operation: ContentSafetyProvider_OperationKey,\n conclusion: { readonly outcome: string } | { readonly failure: string },\n summary: { characters: number; documents: number; requests: number; textRecords: number },\n startTime: number,\n ): Promise<void> {\n const callTimestamp = new Date(startTime).toISOString();\n const failed = 'failure' in conclusion;\n const trace: AgentCallTrace = {\n agentRef: CONTENT_SAFETY_TRACE_AGENT_REF,\n // A classifier call: not a model call, billed by the text records it sent (#2889), counted apart in every cost view.\n kind: AgentCallTraceKind.CLASSIFICATION,\n provider: providerRef,\n model: operation,\n callTimestamp,\n outcome: failed ? AgentCallOutcome.FAILURE : AgentCallOutcome.SUCCESS,\n input: { characters: summary.characters, documents: summary.documents, requests: summary.requests },\n // What the vendor bills (#2889): priced by a TEXT_RECORDS authority, never by tokens.\n meteredUnits: { textRecords: summary.textRecords },\n ...('outcome' in conclusion ? { output: { outcome: conclusion.outcome } } : {}),\n context: {\n callTimestamp,\n executionTime: Date.now() - startTime,\n finishedAt: new Date().toISOString(),\n // A classifier reports no tokens and requires none, so no required dimension is missing.\n usage: { tokenUsageComplete: true },\n },\n ...('failure' in conclusion ? {\n error: {\n name: operation === ContentSafetyProvider_OperationKey.MODERATE_OUTPUT ? ContentSafetyModerationOutcome.NOT_MODERATED : ContentSafetyScreeningOutcome.NOT_SCREENED,\n message: conclusion.failure,\n },\n } : {}),\n };\n try {\n await this.providerCallRecorder?.record(trace);\n } catch (recordError) {\n this.logger.warn('A content-safety call could not be recorded', { providerRef, operation, error: describeCaughtError(recordError) });\n }\n const level = this.agentTracePolicy?.level ?? AgentTraceabilityLevel.NONE;\n if (!this.agentTraceSink || level === AgentTraceabilityLevel.NONE) return;\n try {\n await this.agentTraceSink.recordAgentCall({ trace, level });\n } catch {\n // A sink failure never turns a screening into a failed one.\n }\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embeddings.backend.service.d.ts","sourceRoot":"","sources":["../../../../src/external-providers/services/embeddings.backend.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAIH,OAAO,EAQL,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,EAC9B,KAAK,WAAW,EAIjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,wBAAwB,EAOxB,KAAK,mCAAmC,EACxC,KAAK,8BAA8B,EAEpC,MAAM,sCAAsC,CAAC;AAG9C,OAAO,KAAK,EAAE,kCAAkC,EAAE,MAAM,iFAAiF,CAAC;AAE1I,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8DAA8D,CAAC;AAClG,OAAO,EAAE,0BAA0B,EAAE,MAAM,kEAAkE,CAAC;AAC9G,OAAO,KAAK,EAAE,uCAAuC,EAAE,MAAM,4FAA4F,CAAC;AAI1J,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,0FAA0F,CAAC;AAItJ,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+EAA+E,CAAC;AAOrH;;;;;;GAMG;AACH,eAAO,MAAM,oCAAoC,MAAM,CAAC;AAExD;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,sBAAsB,CAAC;AAE9D,2GAA2G;AAC3G,MAAM,WAAW,yBAAyB;IACxC,4FAA4F;IAC5F,aAAa,EAAE,wBAAwB,CAAC;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,wFAAwF;IACxF,KAAK,EAAE,MAAM,CAAC;IACd,uGAAuG;IACvG,IAAI,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,gBAAgB,EAAE,MAAM,CAAC;IACzB,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAQD,kGAAkG;AAClG,MAAM,MAAM,2BAA2B,GACnC;IAAE,UAAU,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,yBAAyB,CAAA;CAAE,GACxD;IACE,UAAU,EAAE,KAAK,CAAC;IAClB;;;OAGG;IACH,MAAM,EAAE,4BAA4B,CAAC;CACtC,CAAC;AAEN,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,OAAO,EAAE,8BAA8B,CAAC;IACxC,aAAa,EAAE,wBAAwB,CAAC;IACxC;;;OAGG;IACH,WAAW,CAAC,EAAE,yBAAyB,CAAC;IACxC;;;;;OAKG;IACH,cAAc,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,SAAS,CAAC,EAAE,CAAC;CACvD;AAED,qBACa,wBAAwB;IAKjC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAEvB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAE7B,OAAO,CAAC,QAAQ,CAAC,yBAAyB;IAE1C,OAAO,CAAC,QAAQ,CAAC,uBAAuB;IAGxC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC;IAGhC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC;IAIlC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC;IAItC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;IAxB9B,SAAS,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;gBAI9D,MAAM,EAAE,aAAa,EAErB,YAAY,EAAE,0BAA0B,EAExC,yBAAyB,EAAE,uCAAuC,EAElE,uBAAuB,EAAE,qCAAqC,EAG9D,cAAc,CAAC,EAAE,kBAAkB,EAGnC,gBAAgB,CAAC,EAAE,uBAAuB,EAI1C,oBAAoB,CAAC,EAAE,kCAAkC,EAIzD,UAAU,CAAC,EAAE,eAAe;IAM/C;;;;;;;;OAQG;IACI,cAAc,CAAC,aAAa,EAAE,wBAAwB,GAAG,2BAA2B;IAU3F;;;;OAIG;IACH,OAAO,CAAC,yBAAyB;IA4EjC;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACU,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,mCAAmC,CAAC;IAyDjG;;;;OAIG;YACW,YAAY;
|
|
1
|
+
{"version":3,"file":"embeddings.backend.service.d.ts","sourceRoot":"","sources":["../../../../src/external-providers/services/embeddings.backend.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -340,6 +340,8 @@ let EmbeddingsBackendService = class EmbeddingsBackendService {
|
|
|
340
340
|
const client = (await contract.sdkFactory(resolvedCredential.credential, {
|
|
341
341
|
baseUrl: endpoint.baseUrl,
|
|
342
342
|
...(resolvedCredential.deploymentParameters === undefined ? {} : { deploymentParameters: resolvedCredential.deploymentParameters }),
|
|
343
|
+
// #3780: a signing arm's SDK signs each request with these; its credential argument is empty.
|
|
344
|
+
...(resolvedCredential.requestSigningCredentials === undefined ? {} : { requestSigningCredentials: resolvedCredential.requestSigningCredentials }),
|
|
343
345
|
}));
|
|
344
346
|
if (typeof client?.textEmbeddingModel !== 'function') {
|
|
345
347
|
throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, undefined, {
|