@open-mercato/ai-assistant 0.6.7 → 0.6.8-develop.6874.1.982d6097d8
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/.turbo/turbo-build.log +1 -1
- package/AGENTS.md +12 -29
- package/dist/modules/ai_assistant/__integration__/TC-AI-MODERATION-008-settings-and-audit.spec.js +80 -0
- package/dist/modules/ai_assistant/__integration__/TC-AI-MODERATION-008-settings-and-audit.spec.js.map +7 -0
- package/dist/modules/ai_assistant/__integration__/TC-AI-MODERATION-009-ui.spec.js +124 -0
- package/dist/modules/ai_assistant/__integration__/TC-AI-MODERATION-009-ui.spec.js.map +7 -0
- package/dist/modules/ai_assistant/__integration__/helpers/aiAssistantFixtures.js +30 -0
- package/dist/modules/ai_assistant/__integration__/helpers/aiAssistantFixtures.js.map +2 -2
- package/dist/modules/ai_assistant/api/ai/chat/route.js +7 -0
- package/dist/modules/ai_assistant/api/ai/chat/route.js.map +2 -2
- package/dist/modules/ai_assistant/api/moderation-flags/route.js +121 -0
- package/dist/modules/ai_assistant/api/moderation-flags/route.js.map +7 -0
- package/dist/modules/ai_assistant/api/settings/allowlist/route.js +10 -10
- package/dist/modules/ai_assistant/api/settings/allowlist/route.js.map +2 -2
- package/dist/modules/ai_assistant/api/settings/route.js +34 -13
- package/dist/modules/ai_assistant/api/settings/route.js.map +2 -2
- package/dist/modules/ai_assistant/backend/config/ai-assistant/agents/AiAgentSettingsPageClient.js +121 -15
- package/dist/modules/ai_assistant/backend/config/ai-assistant/agents/AiAgentSettingsPageClient.js.map +2 -2
- package/dist/modules/ai_assistant/backend/config/ai-assistant/allowlist/AiTenantAllowlistPageClient.js +2 -2
- package/dist/modules/ai_assistant/backend/config/ai-assistant/allowlist/AiTenantAllowlistPageClient.js.map +2 -2
- package/dist/modules/ai_assistant/backend/config/ai-assistant/moderation-flags/AiModerationFlagsPageClient.js +139 -0
- package/dist/modules/ai_assistant/backend/config/ai-assistant/moderation-flags/AiModerationFlagsPageClient.js.map +7 -0
- package/dist/modules/ai_assistant/backend/config/ai-assistant/moderation-flags/page.js +10 -0
- package/dist/modules/ai_assistant/backend/config/ai-assistant/moderation-flags/page.js.map +7 -0
- package/dist/modules/ai_assistant/backend/config/ai-assistant/moderation-flags/page.meta.js +26 -0
- package/dist/modules/ai_assistant/backend/config/ai-assistant/moderation-flags/page.meta.js.map +7 -0
- package/dist/modules/ai_assistant/backend/config/ai-assistant/playground/AiPlaygroundPageClient.js +4 -4
- package/dist/modules/ai_assistant/backend/config/ai-assistant/playground/AiPlaygroundPageClient.js.map +2 -2
- package/dist/modules/ai_assistant/data/entities.js +42 -0
- package/dist/modules/ai_assistant/data/entities.js.map +2 -2
- package/dist/modules/ai_assistant/data/repositories/AiAgentRuntimeOverrideRepository.js +3 -1
- package/dist/modules/ai_assistant/data/repositories/AiAgentRuntimeOverrideRepository.js.map +2 -2
- package/dist/modules/ai_assistant/data/repositories/AiModerationFlagRepository.js +44 -0
- package/dist/modules/ai_assistant/data/repositories/AiModerationFlagRepository.js.map +7 -0
- package/dist/modules/ai_assistant/di.js +6 -2
- package/dist/modules/ai_assistant/di.js.map +2 -2
- package/dist/modules/ai_assistant/events.js +6 -0
- package/dist/modules/ai_assistant/events.js.map +2 -2
- package/dist/modules/ai_assistant/i18n/de.json +42 -0
- package/dist/modules/ai_assistant/i18n/en.json +42 -0
- package/dist/modules/ai_assistant/i18n/es.json +42 -0
- package/dist/modules/ai_assistant/i18n/ko.json +527 -0
- package/dist/modules/ai_assistant/i18n/pl.json +42 -0
- package/dist/modules/ai_assistant/lib/agent-runtime.js +158 -5
- package/dist/modules/ai_assistant/lib/agent-runtime.js.map +2 -2
- package/dist/modules/ai_assistant/lib/ai-agent-definition.js.map +2 -2
- package/dist/modules/ai_assistant/lib/auth.js +6 -7
- package/dist/modules/ai_assistant/lib/auth.js.map +2 -2
- package/dist/modules/ai_assistant/lib/entity-graph.js +3 -3
- package/dist/modules/ai_assistant/lib/entity-graph.js.map +2 -2
- package/dist/modules/ai_assistant/lib/llm-adapters/anthropic.js +3 -0
- package/dist/modules/ai_assistant/lib/llm-adapters/anthropic.js.map +2 -2
- package/dist/modules/ai_assistant/lib/llm-adapters/openai.js +8 -1
- package/dist/modules/ai_assistant/lib/llm-adapters/openai.js.map +2 -2
- package/dist/modules/ai_assistant/lib/model-factory.js +6 -1
- package/dist/modules/ai_assistant/lib/model-factory.js.map +2 -2
- package/dist/modules/ai_assistant/lib/moderation-flag-recorder.js +43 -0
- package/dist/modules/ai_assistant/lib/moderation-flag-recorder.js.map +7 -0
- package/dist/modules/ai_assistant/lib/moderation-policy.js +24 -0
- package/dist/modules/ai_assistant/lib/moderation-policy.js.map +7 -0
- package/dist/modules/ai_assistant/lib/moderation.js +109 -0
- package/dist/modules/ai_assistant/lib/moderation.js.map +7 -0
- package/dist/modules/ai_assistant/lib/openai-compatible-presets.js +2 -0
- package/dist/modules/ai_assistant/lib/openai-compatible-presets.js.map +2 -2
- package/dist/modules/ai_assistant/lib/tool-search.js +4 -12
- package/dist/modules/ai_assistant/lib/tool-search.js.map +2 -2
- package/dist/modules/ai_assistant/migrations/Migration20260610134045_ai_assistant.js +19 -0
- package/dist/modules/ai_assistant/migrations/Migration20260610134045_ai_assistant.js.map +7 -0
- package/generated/entities/ai_agent_runtime_override/index.ts +1 -0
- package/generated/entities/ai_moderation_flag/index.ts +9 -0
- package/generated/entities.ids.generated.ts +2 -1
- package/generated/entity-fields-registry.ts +13 -1
- package/package.json +13 -12
- package/src/modules/ai_assistant/__integration__/TC-AI-MODERATION-008-settings-and-audit.spec.ts +126 -0
- package/src/modules/ai_assistant/__integration__/TC-AI-MODERATION-009-ui.spec.ts +161 -0
- package/src/modules/ai_assistant/__integration__/helpers/aiAssistantFixtures.ts +48 -0
- package/src/modules/ai_assistant/api/ai/chat/route.ts +10 -0
- package/src/modules/ai_assistant/api/moderation-flags/__tests__/route.test.ts +122 -0
- package/src/modules/ai_assistant/api/moderation-flags/route.ts +137 -0
- package/src/modules/ai_assistant/api/settings/__tests__/route.test.ts +58 -8
- package/src/modules/ai_assistant/api/settings/allowlist/route.ts +10 -12
- package/src/modules/ai_assistant/api/settings/route.ts +33 -10
- package/src/modules/ai_assistant/backend/config/ai-assistant/agents/AiAgentSettingsPageClient.tsx +161 -15
- package/src/modules/ai_assistant/backend/config/ai-assistant/allowlist/AiTenantAllowlistPageClient.tsx +2 -2
- package/src/modules/ai_assistant/backend/config/ai-assistant/moderation-flags/AiModerationFlagsPageClient.tsx +186 -0
- package/src/modules/ai_assistant/backend/config/ai-assistant/moderation-flags/page.meta.ts +24 -0
- package/src/modules/ai_assistant/backend/config/ai-assistant/moderation-flags/page.tsx +12 -0
- package/src/modules/ai_assistant/backend/config/ai-assistant/playground/AiPlaygroundPageClient.tsx +4 -4
- package/src/modules/ai_assistant/data/entities.ts +56 -0
- package/src/modules/ai_assistant/data/repositories/AiAgentRuntimeOverrideRepository.ts +4 -0
- package/src/modules/ai_assistant/data/repositories/AiModerationFlagRepository.ts +79 -0
- package/src/modules/ai_assistant/di.ts +5 -1
- package/src/modules/ai_assistant/events.ts +21 -0
- package/src/modules/ai_assistant/i18n/de.json +42 -0
- package/src/modules/ai_assistant/i18n/en.json +42 -0
- package/src/modules/ai_assistant/i18n/es.json +42 -0
- package/src/modules/ai_assistant/i18n/ko.json +527 -0
- package/src/modules/ai_assistant/i18n/pl.json +42 -0
- package/src/modules/ai_assistant/lib/__tests__/auth.test.ts +2 -5
- package/src/modules/ai_assistant/lib/__tests__/input-moderation-gate.test.ts +121 -0
- package/src/modules/ai_assistant/lib/__tests__/llm-adapters-anthropic.test.ts +13 -0
- package/src/modules/ai_assistant/lib/__tests__/llm-adapters-openai.test.ts +41 -0
- package/src/modules/ai_assistant/lib/__tests__/model-factory.test.ts +60 -0
- package/src/modules/ai_assistant/lib/__tests__/moderation-flag-recorder.test.ts +76 -0
- package/src/modules/ai_assistant/lib/__tests__/moderation-policy.test.ts +86 -0
- package/src/modules/ai_assistant/lib/__tests__/moderation.test.ts +114 -0
- package/src/modules/ai_assistant/lib/agent-runtime.ts +259 -0
- package/src/modules/ai_assistant/lib/ai-agent-definition.ts +10 -0
- package/src/modules/ai_assistant/lib/auth.ts +6 -15
- package/src/modules/ai_assistant/lib/entity-graph.ts +3 -3
- package/src/modules/ai_assistant/lib/llm-adapters/anthropic.ts +10 -0
- package/src/modules/ai_assistant/lib/llm-adapters/openai.ts +32 -1
- package/src/modules/ai_assistant/lib/model-factory.ts +33 -0
- package/src/modules/ai_assistant/lib/moderation-flag-recorder.ts +75 -0
- package/src/modules/ai_assistant/lib/moderation-policy.ts +77 -0
- package/src/modules/ai_assistant/lib/moderation.ts +179 -0
- package/src/modules/ai_assistant/lib/openai-compatible-presets.ts +2 -0
- package/src/modules/ai_assistant/lib/tool-search.ts +4 -17
- package/src/modules/ai_assistant/migrations/.snapshot-open-mercato.json +388 -16
- package/src/modules/ai_assistant/migrations/Migration20260610134045_ai_assistant.ts +21 -0
|
@@ -36,21 +36,44 @@
|
|
|
36
36
|
"ai_assistant.agents.meta.readOnlyYes": "Tak",
|
|
37
37
|
"ai_assistant.agents.meta.unlimited": "Bez limitu",
|
|
38
38
|
"ai_assistant.agents.model_override.allowlistCustom": "niestandardowe",
|
|
39
|
+
"ai_assistant.agents.model_override.allowlistEmpty": "Brak skonfigurowanych dostawców dostępnych do nadpisań w czacie.",
|
|
40
|
+
"ai_assistant.agents.model_override.allowlistHelp": "Ogranicz, które nadpisania dostawcy i modelu użytkownicy mogą wybrać w stopce czatu dla tego agenta.",
|
|
39
41
|
"ai_assistant.agents.model_override.allowlistInherited": "dziedziczone",
|
|
40
42
|
"ai_assistant.agents.model_override.allowlistReset": "Dziedzicz",
|
|
41
43
|
"ai_assistant.agents.model_override.allowlistSave": "Zapisz wybór",
|
|
44
|
+
"ai_assistant.agents.model_override.allowlistSaved": "Zapisano dozwolone opcje nadpisań w czacie.",
|
|
45
|
+
"ai_assistant.agents.model_override.allowlistTitle": "Dozwolone opcje nadpisań w czacie",
|
|
42
46
|
"ai_assistant.agents.model_override.anyProvider": "pierwszy skonfigurowany",
|
|
43
47
|
"ai_assistant.agents.model_override.clear": "Wyczyść nadpisanie",
|
|
48
|
+
"ai_assistant.agents.model_override.cleared": "Nadpisanie modelu zostało wyczyszczone; agent korzysta ze standardowego łańcucha rozwiązywania.",
|
|
44
49
|
"ai_assistant.agents.model_override.codeDefault": "Domyślne z kodu",
|
|
45
50
|
"ai_assistant.agents.model_override.defaultBadge": "domyślne",
|
|
51
|
+
"ai_assistant.agents.model_override.envAlsoNarrows": "dodatkowo zawęża tę listę na podstawie zmiennych środowiskowych.",
|
|
52
|
+
"ai_assistant.agents.model_override.loadErrorTitle": "Nie udało się wczytać katalogu dostawców",
|
|
53
|
+
"ai_assistant.agents.model_override.loading": "Wczytywanie katalogu dostawców…",
|
|
46
54
|
"ai_assistant.agents.model_override.model": "Model",
|
|
47
55
|
"ai_assistant.agents.model_override.noOverride": "Brak nadpisania dla agenta",
|
|
48
56
|
"ai_assistant.agents.model_override.provider": "Dostawca",
|
|
49
57
|
"ai_assistant.agents.model_override.providerDefault": "domyślne dostawcy",
|
|
50
58
|
"ai_assistant.agents.model_override.save": "Zapisz nadpisanie",
|
|
51
59
|
"ai_assistant.agents.model_override.saved": "Nadpisanie modelu zapisane.",
|
|
60
|
+
"ai_assistant.agents.model_override.selectModel": "Wybierz model",
|
|
61
|
+
"ai_assistant.agents.model_override.selectProvider": "Wybierz dostawcę",
|
|
62
|
+
"ai_assistant.agents.model_override.subtitle": "Nadpisz domyślnego dostawcę i model dla tego najemcy i agenta.",
|
|
52
63
|
"ai_assistant.agents.model_override.tenantOverride": "Nadpisanie tenant",
|
|
53
64
|
"ai_assistant.agents.model_override.title": "Dostawca i model",
|
|
65
|
+
"ai_assistant.agents.moderation.controlLabel": "Moderacja",
|
|
66
|
+
"ai_assistant.agents.moderation.effectiveEnforced": "Wymuszona",
|
|
67
|
+
"ai_assistant.agents.moderation.effectiveOff": "Wyłączona",
|
|
68
|
+
"ai_assistant.agents.moderation.effectiveOn": "Włączona",
|
|
69
|
+
"ai_assistant.agents.moderation.enforcedBadge": "Wymuszona",
|
|
70
|
+
"ai_assistant.agents.moderation.enforcedHint": "Ten agent przyjmuje niezaufane dane wejściowe, więc moderacja jest zawsze włączona i nie można jej tutaj wyłączyć.",
|
|
71
|
+
"ai_assistant.agents.moderation.inheritLabel": "Dziedzicz",
|
|
72
|
+
"ai_assistant.agents.moderation.offLabel": "Wyłączona",
|
|
73
|
+
"ai_assistant.agents.moderation.onLabel": "Włączona",
|
|
74
|
+
"ai_assistant.agents.moderation.saved": "Zapisano ustawienie moderacji danych wejściowych.",
|
|
75
|
+
"ai_assistant.agents.moderation.subtitle": "Filtruj dane wejściowe użytkownika pod kątem niebezpiecznych treści przed uruchomieniem modelu. Działa tylko, gdy wybrany dostawca obsługuje moderację.",
|
|
76
|
+
"ai_assistant.agents.moderation.title": "Moderacja danych wejściowych",
|
|
54
77
|
"ai_assistant.agents.mutation_policy.clear": "Wyczyść nadpisanie",
|
|
55
78
|
"ai_assistant.agents.mutation_policy.clearedMessage": "Nadpisanie polityki mutacji usunięte; agent korzysta z polityki zadeklarowanej w kodzie.",
|
|
56
79
|
"ai_assistant.agents.mutation_policy.codeDeclared": "Zadeklarowane w kodzie",
|
|
@@ -275,7 +298,9 @@
|
|
|
275
298
|
"ai_assistant.chat.toolRunning": "w toku…",
|
|
276
299
|
"ai_assistant.chat.transcriptLabel": "Transkrypcja czatu",
|
|
277
300
|
"ai_assistant.chat.uiPartPending": "Oczekująca część UI:",
|
|
301
|
+
"ai_assistant.chat.uploadingHint": "Trwa przesyłanie załączników… Wysyłanie jest zablokowane do zakończenia.",
|
|
278
302
|
"ai_assistant.chat.userRoleLabel": "Ty",
|
|
303
|
+
"ai_assistant.chat.welcomeDescription": "Zapytaj mnie o cokolwiek z Twoich danych. Oto kilka rzeczy, które potrafię:",
|
|
279
304
|
"ai_assistant.chat.welcomeTitle": "W czym mogę pomóc?",
|
|
280
305
|
"ai_assistant.chat.zoomImage": "Otwórz podgląd {name}",
|
|
281
306
|
"ai_assistant.dock.bottom": "Dokuj na dole",
|
|
@@ -284,13 +309,17 @@
|
|
|
284
309
|
"ai_assistant.dock.left": "Dokuj po lewej",
|
|
285
310
|
"ai_assistant.dock.minimize": "Minimalizuj",
|
|
286
311
|
"ai_assistant.dock.right": "Dokuj po prawej",
|
|
312
|
+
"ai_assistant.errors.moderationBlocked": "Twoja wiadomość została zablokowana przez filtr bezpieczeństwa treści. Przeformułuj ją i spróbuj ponownie.",
|
|
313
|
+
"ai_assistant.errors.moderationUnavailable": "Sprawdzanie bezpieczeństwa treści jest chwilowo niedostępne. Spróbuj ponownie za chwilę.",
|
|
287
314
|
"ai_assistant.launcher.composerPlaceholder": "Zapytaj o cokolwiek…",
|
|
315
|
+
"ai_assistant.launcher.dialogDescription": "Wybierz asystenta. Nawiguj klawiszami ↑/↓, Enter uruchamia, Esc zamyka.",
|
|
288
316
|
"ai_assistant.launcher.dialogTitle": "Asystenci AI",
|
|
289
317
|
"ai_assistant.launcher.dock.subtitle": "Asystent AI",
|
|
290
318
|
"ai_assistant.launcher.empty": "Żaden asystent nie pasuje do wyszukiwania.",
|
|
291
319
|
"ai_assistant.launcher.hint.close": "Zamknij",
|
|
292
320
|
"ai_assistant.launcher.hint.launch": "Uruchom",
|
|
293
321
|
"ai_assistant.launcher.hint.navigate": "Nawigacja",
|
|
322
|
+
"ai_assistant.launcher.none": "Dla Twojego konta nie są dostępni żadni asystenci.",
|
|
294
323
|
"ai_assistant.launcher.searchPlaceholder": "Szukaj asystentów...",
|
|
295
324
|
"ai_assistant.launcher.setup.body": "Asystenci AI są zainstalowani, ale nie skonfigurowano klucza dostawcy. Ustaw OM_AI_PROVIDER oraz pasujący klucz API w pliku .env, a następnie uruchom aplikację ponownie.",
|
|
296
325
|
"ai_assistant.launcher.setup.docs": "Dokumentacja asystenta AI",
|
|
@@ -299,6 +328,7 @@
|
|
|
299
328
|
"ai_assistant.launcher.sheet.dock": "Przypnij z boku",
|
|
300
329
|
"ai_assistant.launcher.triggerAriaLabel": "Otwórz asystenta AI",
|
|
301
330
|
"ai_assistant.launcher.triggerLabel": "AI",
|
|
331
|
+
"ai_assistant.launcher.welcome.fallback": "W czym mogę pomóc?",
|
|
302
332
|
"ai_assistant.launcher.welcome.suggestion1": "W czym możesz mi pomóc?",
|
|
303
333
|
"ai_assistant.launcher.welcome.suggestion2": "Pokaż, do jakich danych masz dostęp",
|
|
304
334
|
"ai_assistant.launcher.welcome.suggestion3": "Zaproponuj, co mogę wypróbować",
|
|
@@ -326,6 +356,18 @@
|
|
|
326
356
|
"ai_assistant.modelPicker.triggerAriaLabel": "Wybierz model AI",
|
|
327
357
|
"ai_assistant.modelPicker.useDefault": "Użyj domyślnego agenta",
|
|
328
358
|
"ai_assistant.modelPicker.useDefaultWithModel": "Użyj domyślnego agenta: {{model}}",
|
|
359
|
+
"ai_assistant.moderationFlags.columns.agent": "Agent",
|
|
360
|
+
"ai_assistant.moderationFlags.columns.categories": "Kategorie",
|
|
361
|
+
"ai_assistant.moderationFlags.columns.createdAt": "Oznaczono",
|
|
362
|
+
"ai_assistant.moderationFlags.columns.user": "Użytkownik",
|
|
363
|
+
"ai_assistant.moderationFlags.empty": "Brak oznaczonych wiadomości.",
|
|
364
|
+
"ai_assistant.moderationFlags.filters.agentPlaceholder": "moduł.agent",
|
|
365
|
+
"ai_assistant.moderationFlags.filters.apply": "Zastosuj",
|
|
366
|
+
"ai_assistant.moderationFlags.filters.from": "Od",
|
|
367
|
+
"ai_assistant.moderationFlags.filters.to": "Do",
|
|
368
|
+
"ai_assistant.moderationFlags.navTitle": "Flagi moderacji",
|
|
369
|
+
"ai_assistant.moderationFlags.subtitle": "Dane wejściowe zablokowane przez filtr bezpieczeństwa treści. Tylko flagi kategorii i wyniki — treść promptu nie jest przechowywana.",
|
|
370
|
+
"ai_assistant.moderationFlags.title": "Flagi moderacji",
|
|
329
371
|
"ai_assistant.notifications.conversation_shared.body": "Udostępniono Ci konwersację z asystentem AI.",
|
|
330
372
|
"ai_assistant.notifications.conversation_shared.title": "Udostępniono Ci konwersację",
|
|
331
373
|
"ai_assistant.notifications.conversation_shared.view_button": "Otwórz konwersację",
|
|
@@ -11,6 +11,18 @@ import {
|
|
|
11
11
|
Experimental_Agent as ToolLoopAgent
|
|
12
12
|
} from "ai";
|
|
13
13
|
import { createModelFactory, resolveAllowRuntimeOverride } from "./model-factory.js";
|
|
14
|
+
import { computeEndUserIdentifier } from "@open-mercato/shared/lib/ai/safety-identifier";
|
|
15
|
+
import { llmProviderRegistry } from "@open-mercato/shared/lib/ai/llm-provider-registry";
|
|
16
|
+
import {
|
|
17
|
+
AiModerationBlockedError,
|
|
18
|
+
AiModerationUnavailableError
|
|
19
|
+
} from "./moderation.js";
|
|
20
|
+
import {
|
|
21
|
+
isModerationActive,
|
|
22
|
+
resolveModerationPolicy,
|
|
23
|
+
shouldFailClosed
|
|
24
|
+
} from "./moderation-policy.js";
|
|
25
|
+
import { recordModerationFlag } from "./moderation-flag-recorder.js";
|
|
14
26
|
import {
|
|
15
27
|
resolveAiAgentTools,
|
|
16
28
|
AgentPolicyError,
|
|
@@ -397,7 +409,7 @@ function assertLoopObjectModeCompatible(loopConfig) {
|
|
|
397
409
|
);
|
|
398
410
|
}
|
|
399
411
|
}
|
|
400
|
-
function resolveAgentModel(agent, modelOverride, providerOverride, container, baseUrlOverride, tenantOverride, requestOverride, tenantAllowlist) {
|
|
412
|
+
function resolveAgentModel(agent, modelOverride, providerOverride, container, baseUrlOverride, tenantOverride, requestOverride, tenantAllowlist, endUserIdentifier) {
|
|
401
413
|
const effectiveContainer = container ?? createContainer();
|
|
402
414
|
const resolution = createModelFactory(effectiveContainer).resolveModel({
|
|
403
415
|
moduleId: agent.moduleId,
|
|
@@ -410,14 +422,88 @@ function resolveAgentModel(agent, modelOverride, providerOverride, container, ba
|
|
|
410
422
|
allowRuntimeOverride: resolveAllowRuntimeOverride(agent),
|
|
411
423
|
tenantOverride: tenantOverride ?? void 0,
|
|
412
424
|
requestOverride: requestOverride ?? void 0,
|
|
413
|
-
tenantAllowlist: tenantAllowlist ?? null
|
|
425
|
+
tenantAllowlist: tenantAllowlist ?? null,
|
|
426
|
+
endUserIdentifier
|
|
414
427
|
});
|
|
415
428
|
return {
|
|
416
429
|
model: resolution.model,
|
|
417
430
|
modelId: resolution.modelId,
|
|
418
|
-
providerId: resolution.providerId
|
|
431
|
+
providerId: resolution.providerId,
|
|
432
|
+
providerOptions: resolution.providerOptions,
|
|
433
|
+
supportsInputModeration: resolution.supportsInputModeration === true,
|
|
434
|
+
baseURL: resolution.baseURL
|
|
419
435
|
};
|
|
420
436
|
}
|
|
437
|
+
function extractLatestUserText(messages) {
|
|
438
|
+
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
439
|
+
const raw = messages[index];
|
|
440
|
+
if (raw.role !== "user") continue;
|
|
441
|
+
if (Array.isArray(raw.parts)) {
|
|
442
|
+
return raw.parts.filter((part) => part?.type === "text" && typeof part.text === "string").map((part) => part.text).join("\n");
|
|
443
|
+
}
|
|
444
|
+
return typeof raw.content === "string" ? raw.content : "";
|
|
445
|
+
}
|
|
446
|
+
return "";
|
|
447
|
+
}
|
|
448
|
+
async function runInputModerationGate(params) {
|
|
449
|
+
const policy = resolveModerationPolicy({
|
|
450
|
+
untrustedInput: params.untrustedInput,
|
|
451
|
+
perAgentOverride: params.perAgentOverride,
|
|
452
|
+
tenantWideOverride: params.tenantWideOverride,
|
|
453
|
+
env: params.env
|
|
454
|
+
});
|
|
455
|
+
if (!isModerationActive(policy)) return;
|
|
456
|
+
if (!params.supportsInputModeration) return;
|
|
457
|
+
const text = params.userText.trim();
|
|
458
|
+
if (!text) return;
|
|
459
|
+
const failClosed = shouldFailClosed(policy);
|
|
460
|
+
const failOpenOrThrow = (reason, error) => {
|
|
461
|
+
if (failClosed) {
|
|
462
|
+
if (error instanceof AiModerationUnavailableError) throw error;
|
|
463
|
+
throw new AiModerationUnavailableError(reason, error);
|
|
464
|
+
}
|
|
465
|
+
logger.warn("Input moderation unavailable; failing open for opt-in surface", { reason });
|
|
466
|
+
};
|
|
467
|
+
if (!params.service) {
|
|
468
|
+
return failOpenOrThrow("moderation service is not available in the container");
|
|
469
|
+
}
|
|
470
|
+
const apiKey = params.resolveApiKey();
|
|
471
|
+
if (!apiKey) {
|
|
472
|
+
return failOpenOrThrow("no API key available for the moderation provider");
|
|
473
|
+
}
|
|
474
|
+
let result;
|
|
475
|
+
try {
|
|
476
|
+
result = await params.service.checkInput({
|
|
477
|
+
text,
|
|
478
|
+
apiKey,
|
|
479
|
+
baseURL: params.baseURL,
|
|
480
|
+
model: params.moderationModel
|
|
481
|
+
});
|
|
482
|
+
} catch (error) {
|
|
483
|
+
if (error instanceof AiModerationUnavailableError) {
|
|
484
|
+
return failOpenOrThrow(error.message, error);
|
|
485
|
+
}
|
|
486
|
+
throw error;
|
|
487
|
+
}
|
|
488
|
+
if (result.flagged) {
|
|
489
|
+
if (params.onFlagged) {
|
|
490
|
+
try {
|
|
491
|
+
await params.onFlagged(result.categories);
|
|
492
|
+
} catch (error) {
|
|
493
|
+
logger.error("Moderation flag side effect failed (rejection still applies)", { err: error });
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
throw new AiModerationBlockedError(result.categories);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
function resolveEndUserIdentifier(authContext) {
|
|
500
|
+
try {
|
|
501
|
+
return computeEndUserIdentifier(authContext.tenantId, authContext.userId);
|
|
502
|
+
} catch (error) {
|
|
503
|
+
logger.warn("Failed to derive end-user safety identifier", { err: error });
|
|
504
|
+
return void 0;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
421
507
|
async function resolveTenantAllowlistSnapshot(container, tenantId, organizationId) {
|
|
422
508
|
if (!tenantId || !container) return null;
|
|
423
509
|
let em = null;
|
|
@@ -550,6 +636,31 @@ async function resolveRuntimeModelOverride(agentId, container, tenantId, organiz
|
|
|
550
636
|
return null;
|
|
551
637
|
}
|
|
552
638
|
}
|
|
639
|
+
async function resolveModerationOverrideValues(container, tenantId, organizationId, agentId) {
|
|
640
|
+
const empty = { perAgentOverride: null, tenantWideOverride: null };
|
|
641
|
+
if (!tenantId || !container) return empty;
|
|
642
|
+
let em = null;
|
|
643
|
+
try {
|
|
644
|
+
em = container.resolve("em");
|
|
645
|
+
} catch {
|
|
646
|
+
em = null;
|
|
647
|
+
}
|
|
648
|
+
if (!em) return empty;
|
|
649
|
+
try {
|
|
650
|
+
const repo = new AiAgentRuntimeOverrideRepository(em);
|
|
651
|
+
const [agentRow, tenantRow] = await Promise.all([
|
|
652
|
+
repo.getExact({ tenantId, organizationId: organizationId ?? null, agentId }),
|
|
653
|
+
repo.getDefault({ tenantId, organizationId: organizationId ?? null, agentId: null })
|
|
654
|
+
]);
|
|
655
|
+
return {
|
|
656
|
+
perAgentOverride: agentRow?.inputModeration ?? null,
|
|
657
|
+
tenantWideOverride: tenantRow?.inputModeration ?? null
|
|
658
|
+
};
|
|
659
|
+
} catch (error) {
|
|
660
|
+
logger.warn("Moderation override lookup failed; falling back to env default", { agentId, err: error });
|
|
661
|
+
return empty;
|
|
662
|
+
}
|
|
663
|
+
}
|
|
553
664
|
function ensureUiMessageShape(messages) {
|
|
554
665
|
return messages.map((message, index) => {
|
|
555
666
|
const raw = message;
|
|
@@ -750,10 +861,47 @@ async function runAiAgentText(input) {
|
|
|
750
861
|
input.baseUrlOverride,
|
|
751
862
|
tenantRuntimeOverride,
|
|
752
863
|
input.requestOverride,
|
|
753
|
-
tenantAllowlistSnapshot
|
|
864
|
+
tenantAllowlistSnapshot,
|
|
865
|
+
resolveEndUserIdentifier(input.authContext)
|
|
754
866
|
);
|
|
755
867
|
const { model } = resolvedModel;
|
|
868
|
+
const modelProviderOptions = resolvedModel.providerOptions;
|
|
756
869
|
const normalizedMessages = ensureUiMessageShape(input.messages);
|
|
870
|
+
let moderationService = null;
|
|
871
|
+
try {
|
|
872
|
+
moderationService = input.container?.resolve("moderationService") ?? null;
|
|
873
|
+
} catch {
|
|
874
|
+
moderationService = null;
|
|
875
|
+
}
|
|
876
|
+
const moderationOverrides = resolvedModel.supportsInputModeration && agent.untrustedInput !== true ? await resolveModerationOverrideValues(
|
|
877
|
+
input.container,
|
|
878
|
+
input.authContext.tenantId,
|
|
879
|
+
input.authContext.organizationId,
|
|
880
|
+
agent.id
|
|
881
|
+
) : { perAgentOverride: null, tenantWideOverride: null };
|
|
882
|
+
await runInputModerationGate({
|
|
883
|
+
untrustedInput: agent.untrustedInput,
|
|
884
|
+
supportsInputModeration: resolvedModel.supportsInputModeration,
|
|
885
|
+
perAgentOverride: moderationOverrides.perAgentOverride,
|
|
886
|
+
tenantWideOverride: moderationOverrides.tenantWideOverride,
|
|
887
|
+
userText: extractLatestUserText(normalizedMessages),
|
|
888
|
+
service: moderationService,
|
|
889
|
+
resolveApiKey: () => llmProviderRegistry.get(resolvedModel.providerId)?.resolveApiKey() ?? null,
|
|
890
|
+
baseURL: resolvedModel.baseURL,
|
|
891
|
+
moderationModel: process.env.OM_AI_MODERATION_MODEL,
|
|
892
|
+
onFlagged: (categories) => recordModerationFlag(
|
|
893
|
+
{
|
|
894
|
+
tenantId: input.authContext.tenantId,
|
|
895
|
+
organizationId: input.authContext.organizationId,
|
|
896
|
+
agentId: agent.id,
|
|
897
|
+
userId: input.authContext.userId,
|
|
898
|
+
providerId: resolvedModel.providerId,
|
|
899
|
+
modelId: resolvedModel.modelId,
|
|
900
|
+
categories
|
|
901
|
+
},
|
|
902
|
+
input.container
|
|
903
|
+
)
|
|
904
|
+
});
|
|
757
905
|
const hydratedMessages = attachAttachmentsToMessages(normalizedMessages, resolvedAttachments);
|
|
758
906
|
const modelMessages = await convertToModelMessages(hydratedMessages);
|
|
759
907
|
const effectiveLoop = resolveEffectiveLoopConfig(agent, input.loop, WRAPPER_DEFAULT_LOOP_CHAT);
|
|
@@ -814,7 +962,8 @@ async function runAiAgentText(input) {
|
|
|
814
962
|
onStepFinish: wiredOnStepFinish,
|
|
815
963
|
...effectiveLoop.repairToolCall !== void 0 ? { experimental_repairToolCall: effectiveLoop.repairToolCall } : {},
|
|
816
964
|
...sdkActiveTools !== void 0 ? { activeTools: sdkActiveTools } : {},
|
|
817
|
-
...sdkToolChoice !== void 0 ? { toolChoice: sdkToolChoice } : {}
|
|
965
|
+
...sdkToolChoice !== void 0 ? { toolChoice: sdkToolChoice } : {},
|
|
966
|
+
...modelProviderOptions !== void 0 ? { providerOptions: modelProviderOptions } : {}
|
|
818
967
|
};
|
|
819
968
|
builtToolLoopAgent = new ToolLoopAgent(agentSettings);
|
|
820
969
|
}
|
|
@@ -835,6 +984,7 @@ async function runAiAgentText(input) {
|
|
|
835
984
|
toolChoice: sdkToolChoice,
|
|
836
985
|
abortSignal: abortController.signal,
|
|
837
986
|
finalizeLoopTrace: () => loopTraceCollector.finalize(budgetEnforcer.abortReason),
|
|
987
|
+
...modelProviderOptions !== void 0 ? { providerOptions: modelProviderOptions } : {},
|
|
838
988
|
...builtToolLoopAgent !== void 0 ? { toolLoopAgent: builtToolLoopAgent } : {}
|
|
839
989
|
};
|
|
840
990
|
const taskPlanId = `turn_${turnId}`;
|
|
@@ -894,6 +1044,7 @@ async function runAiAgentText(input) {
|
|
|
894
1044
|
experimental_repairToolCall: effectiveLoop.repairToolCall,
|
|
895
1045
|
...sdkActiveTools !== void 0 ? { activeTools: sdkActiveTools } : {},
|
|
896
1046
|
...sdkToolChoice !== void 0 ? { toolChoice: sdkToolChoice } : {},
|
|
1047
|
+
...modelProviderOptions !== void 0 ? { providerOptions: modelProviderOptions } : {},
|
|
897
1048
|
abortSignal: abortController.signal
|
|
898
1049
|
});
|
|
899
1050
|
if (wallClockTimer !== void 0) {
|
|
@@ -1101,11 +1252,13 @@ export {
|
|
|
1101
1252
|
buildLoopTraceCollector,
|
|
1102
1253
|
buildWrapperPrepareStep,
|
|
1103
1254
|
composeSystemPrompt,
|
|
1255
|
+
extractLatestUserText,
|
|
1104
1256
|
mergeStepOverrides,
|
|
1105
1257
|
resolveEffectiveLoopConfig,
|
|
1106
1258
|
resolveLoopBudgetPreset,
|
|
1107
1259
|
runAiAgentObject,
|
|
1108
1260
|
runAiAgentText,
|
|
1261
|
+
runInputModerationGate,
|
|
1109
1262
|
translateStopConditions
|
|
1110
1263
|
};
|
|
1111
1264
|
//# sourceMappingURL=agent-runtime.js.map
|