@cat-factory/app 0.102.0 → 0.103.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -129,7 +129,11 @@ async function saveStorage() {
129
129
  ...(cs.forcePathStyle ? { forcePathStyle: true } : {}),
130
130
  }
131
131
  }
132
- const input: Parameters<typeof store.save>[1] = { config: { contentStorage: config } }
132
+ // `config` fully REPLACES the stored non-secret config, so carry the rest forward
133
+ // (e.g. the model-family policy) — only `contentStorage` is edited here.
134
+ const input: Parameters<typeof store.save>[1] = {
135
+ config: { ...store.view?.config, contentStorage: config },
136
+ }
133
137
  if (backend === 's3') {
134
138
  const id = cs.accessKeyId.trim()
135
139
  const key = cs.secretAccessKey.trim()
@@ -0,0 +1,247 @@
1
+ <script setup lang="ts">
2
+ import { computed, onMounted, ref, watch } from 'vue'
3
+ import { MODEL_FAMILY_POLICY_PRESETS } from '@cat-factory/contracts'
4
+ import type {
5
+ AccountRegion,
6
+ ModelFamily,
7
+ ModelFamilyPolicy,
8
+ ModelPolicyMode,
9
+ } from '~/types/accountSettings'
10
+
11
+ // Account-wide model-family allow/block policy (admin only). Constrains which LLM families
12
+ // the account's teams may run; a residency-guaranteed route (`trustedProviders`) can exempt
13
+ // an otherwise-blocked family. Region-grouped built-in presets are one-click templates the
14
+ // admin applies into the editable policy. Mounted only where the deployment supports it
15
+ // (hosted / mothership — never plain local mode), gated by the parent on the infra flag.
16
+ const props = defineProps<{ accountId: string }>()
17
+
18
+ const store = useAccountSettingsStore()
19
+ const toast = useToast()
20
+ const { t } = useI18n()
21
+
22
+ // The family / region / mode / trusted-provider domains, pinned to the contract unions so a
23
+ // new enum member fails the typecheck here (via the exhaustive label maps below).
24
+ const FAMILIES = [
25
+ 'claude',
26
+ 'openai',
27
+ 'gemini',
28
+ 'llama',
29
+ 'qwen',
30
+ 'kimi',
31
+ 'deepseek',
32
+ 'glm',
33
+ ] as const satisfies readonly ModelFamily[]
34
+ const REGIONS = ['usa', 'europe', 'china', 'other'] as const satisfies readonly AccountRegion[]
35
+ const MODES = ['off', 'blocklist', 'allowlist'] as const satisfies readonly ModelPolicyMode[]
36
+ const TRUSTED_PROVIDERS = ['bedrock'] as const
37
+
38
+ // Exhaustive enum→key maps (drift guard): every member resolves to a static literal `t()`
39
+ // key, so adding a family/region/mode without a label fails the typecheck on the Record.
40
+ const familyLabels = computed<Record<ModelFamily, string>>(() => ({
41
+ claude: t('settings.modelPolicy.families.claude'),
42
+ openai: t('settings.modelPolicy.families.openai'),
43
+ gemini: t('settings.modelPolicy.families.gemini'),
44
+ llama: t('settings.modelPolicy.families.llama'),
45
+ qwen: t('settings.modelPolicy.families.qwen'),
46
+ kimi: t('settings.modelPolicy.families.kimi'),
47
+ deepseek: t('settings.modelPolicy.families.deepseek'),
48
+ glm: t('settings.modelPolicy.families.glm'),
49
+ }))
50
+ const regionLabels = computed<Record<AccountRegion, string>>(() => ({
51
+ usa: t('settings.modelPolicy.regions.usa'),
52
+ europe: t('settings.modelPolicy.regions.europe'),
53
+ china: t('settings.modelPolicy.regions.china'),
54
+ other: t('settings.modelPolicy.regions.other'),
55
+ }))
56
+ const modeLabels = computed<Record<ModelPolicyMode, string>>(() => ({
57
+ off: t('settings.modelPolicy.modes.off'),
58
+ blocklist: t('settings.modelPolicy.modes.blocklist'),
59
+ allowlist: t('settings.modelPolicy.modes.allowlist'),
60
+ }))
61
+ const providerLabels = computed<Record<(typeof TRUSTED_PROVIDERS)[number], string>>(() => ({
62
+ bedrock: t('settings.modelPolicy.providers.bedrock'),
63
+ }))
64
+
65
+ const modeItems = computed(() => MODES.map((m) => ({ label: modeLabels.value[m], value: m })))
66
+ const regionItems = computed(() => REGIONS.map((r) => ({ label: regionLabels.value[r], value: r })))
67
+
68
+ // Editable local state (hydrated from the stored policy).
69
+ const mode = ref<ModelPolicyMode>('off')
70
+ const region = ref<AccountRegion>('other')
71
+ const families = ref<ModelFamily[]>([])
72
+ const trusted = ref<string[]>([])
73
+ const saving = ref(false)
74
+
75
+ function hydrate() {
76
+ const p = store.view?.config?.modelPolicy
77
+ mode.value = p?.mode ?? 'off'
78
+ region.value = p?.region ?? 'other'
79
+ families.value = [...(p?.families ?? [])]
80
+ trusted.value = [...(p?.trustedProviders ?? [])]
81
+ }
82
+
83
+ // The presets offered for the currently-selected region.
84
+ const regionPresets = computed(() =>
85
+ MODEL_FAMILY_POLICY_PRESETS.filter((preset) => preset.region === region.value),
86
+ )
87
+
88
+ function toggleFamily(fam: ModelFamily) {
89
+ families.value = families.value.includes(fam)
90
+ ? families.value.filter((x) => x !== fam)
91
+ : [...families.value, fam]
92
+ }
93
+ function toggleTrusted(provider: string) {
94
+ trusted.value = trusted.value.includes(provider)
95
+ ? trusted.value.filter((x) => x !== provider)
96
+ : [...trusted.value, provider]
97
+ }
98
+
99
+ function applyPreset(policy: ModelFamilyPolicy) {
100
+ mode.value = policy.mode
101
+ families.value = [...policy.families]
102
+ trusted.value = [...policy.trustedProviders]
103
+ }
104
+
105
+ onMounted(async () => {
106
+ // The sibling deployment-settings panel loads the store on mount too; guard against a
107
+ // double-load being unnecessary by only loading when the view isn't present yet.
108
+ if (!store.view && store.available !== false) {
109
+ try {
110
+ await store.load(props.accountId)
111
+ } catch {
112
+ // The deployment-settings panel surfaces the load error; stay quiet here.
113
+ }
114
+ }
115
+ hydrate()
116
+ })
117
+ watch(() => store.view, hydrate)
118
+
119
+ async function save() {
120
+ const policy: ModelFamilyPolicy = {
121
+ mode: mode.value,
122
+ // Families are irrelevant when the policy is off; keep them so a later re-enable
123
+ // restores the admin's selection rather than silently emptying it.
124
+ families: families.value,
125
+ trustedProviders: trusted.value,
126
+ region: region.value,
127
+ }
128
+ saving.value = true
129
+ try {
130
+ // `config` fully replaces the stored non-secret config, so carry the rest forward.
131
+ await store.save(props.accountId, { config: { ...store.view?.config, modelPolicy: policy } })
132
+ toast.add({
133
+ title: t('settings.modelPolicy.saved'),
134
+ icon: 'i-lucide-check',
135
+ color: 'success',
136
+ })
137
+ } catch (e) {
138
+ toast.add({
139
+ title: t('settings.modelPolicy.saveFailed'),
140
+ description: e instanceof Error ? e.message : String(e),
141
+ color: 'error',
142
+ })
143
+ } finally {
144
+ saving.value = false
145
+ }
146
+ }
147
+ </script>
148
+
149
+ <template>
150
+ <section
151
+ v-if="store.available !== false"
152
+ data-testid="account-model-policy"
153
+ class="space-y-3 border-t border-slate-800 pt-6"
154
+ >
155
+ <div>
156
+ <h4 class="text-sm font-semibold text-slate-200">{{ t('settings.modelPolicy.title') }}</h4>
157
+ <p class="text-[11px] text-slate-400">{{ t('settings.modelPolicy.description') }}</p>
158
+ </div>
159
+
160
+ <!-- Region + apply-preset templates -->
161
+ <div class="space-y-2">
162
+ <label class="text-[11px] font-medium text-slate-300">
163
+ {{ t('settings.modelPolicy.regionLabel') }}
164
+ </label>
165
+ <div class="grid grid-cols-1 gap-2 sm:grid-cols-2">
166
+ <USelect v-model="region" :items="regionItems" value-key="value" size="sm" />
167
+ </div>
168
+ <div v-if="regionPresets.length" class="flex flex-wrap items-center gap-2">
169
+ <span class="text-[11px] text-slate-400">{{ t('settings.modelPolicy.applyPreset') }}</span>
170
+ <UButton
171
+ v-for="preset in regionPresets"
172
+ :key="preset.id"
173
+ color="neutral"
174
+ variant="subtle"
175
+ size="xs"
176
+ icon="i-lucide-wand-2"
177
+ :title="t(`settings.modelPolicy.presets.${preset.id}.description`)"
178
+ @click="applyPreset(preset.policy)"
179
+ >
180
+ {{ t(`settings.modelPolicy.presets.${preset.id}.label`) }}
181
+ </UButton>
182
+ </div>
183
+ </div>
184
+
185
+ <!-- Mode -->
186
+ <div class="space-y-2">
187
+ <label class="text-[11px] font-medium text-slate-300">
188
+ {{ t('settings.modelPolicy.modeLabel') }}
189
+ </label>
190
+ <div class="grid grid-cols-1 gap-2 sm:grid-cols-2">
191
+ <USelect v-model="mode" :items="modeItems" value-key="value" size="sm" />
192
+ </div>
193
+ </div>
194
+
195
+ <!-- Families -->
196
+ <div v-if="mode !== 'off'" class="space-y-2">
197
+ <label class="text-[11px] font-medium text-slate-300">
198
+ {{
199
+ mode === 'blocklist'
200
+ ? t('settings.modelPolicy.familiesBlockLabel')
201
+ : t('settings.modelPolicy.familiesAllowLabel')
202
+ }}
203
+ </label>
204
+ <div class="grid grid-cols-2 gap-1 sm:grid-cols-4">
205
+ <UCheckbox
206
+ v-for="fam in FAMILIES"
207
+ :key="fam"
208
+ :model-value="families.includes(fam)"
209
+ :label="familyLabels[fam]"
210
+ size="sm"
211
+ @update:model-value="toggleFamily(fam)"
212
+ />
213
+ </div>
214
+ </div>
215
+
216
+ <!-- Trusted (residency-guaranteed) routes -->
217
+ <div v-if="mode !== 'off'" class="space-y-2">
218
+ <label class="text-[11px] font-medium text-slate-300">
219
+ {{ t('settings.modelPolicy.trustedLabel') }}
220
+ </label>
221
+ <p class="text-[11px] text-slate-400">{{ t('settings.modelPolicy.trustedHint') }}</p>
222
+ <div class="grid grid-cols-2 gap-1 sm:grid-cols-4">
223
+ <UCheckbox
224
+ v-for="provider in TRUSTED_PROVIDERS"
225
+ :key="provider"
226
+ :model-value="trusted.includes(provider)"
227
+ :label="providerLabels[provider]"
228
+ size="sm"
229
+ @update:model-value="toggleTrusted(provider)"
230
+ />
231
+ </div>
232
+ </div>
233
+
234
+ <div class="flex gap-2">
235
+ <UButton
236
+ color="primary"
237
+ size="xs"
238
+ icon="i-lucide-save"
239
+ :loading="saving"
240
+ data-testid="account-model-policy-save"
241
+ @click="save"
242
+ >
243
+ {{ t('common.save') }}
244
+ </UButton>
245
+ </div>
246
+ </section>
247
+ </template>
@@ -4,6 +4,7 @@ import { apiErrorEnvelope } from '~/composables/api/errors'
4
4
  import type { AccountRole } from '~/types/domain'
5
5
  import type { InvitationStatus } from '@cat-factory/contracts'
6
6
  import AccountDeploymentSettings from '~/components/layout/AccountDeploymentSettings.vue'
7
+ import AccountModelPolicySettings from '~/components/layout/AccountModelPolicySettings.vue'
7
8
  import SecretInput from '~/components/common/SecretInput.vue'
8
9
 
9
10
  // Team settings for an org account: the member roster (with combinable admin /
@@ -13,11 +14,16 @@ import SecretInput from '~/components/common/SecretInput.vue'
13
14
  const props = defineProps<{ accountId: string }>()
14
15
 
15
16
  const accounts = useAccountsStore()
17
+ const auth = useAuthStore()
16
18
  const toast = useToast()
17
19
  const { t, te } = useI18n()
18
20
  const { confirmAction, toastDone } = useConfirmAction()
19
21
  const busy = ref(false)
20
22
 
23
+ // The account-wide model-family policy is a hosted / mothership-only control (the backend
24
+ // reports `false` in plain local mode, where there is no account admin to govern).
25
+ const modelPolicySupported = computed(() => auth.infrastructure?.modelPolicy?.supported ?? false)
26
+
21
27
  const ROLE_ITEMS = computed<{ label: string; value: AccountRole }[]>(() => [
22
28
  { label: t('layout.accountTeam.roles.admin'), value: 'admin' },
23
29
  { label: t('layout.accountTeam.roles.developer'), value: 'developer' },
@@ -326,5 +332,10 @@ async function disconnectEmail() {
326
332
  <section v-if="isAdmin">
327
333
  <AccountDeploymentSettings :account-id="accountId" />
328
334
  </section>
335
+
336
+ <!-- account-wide model-family allow/block policy (admin-only; hosted/mothership only) -->
337
+ <section v-if="isAdmin && modelPolicySupported">
338
+ <AccountModelPolicySettings :account-id="accountId" />
339
+ </section>
329
340
  </div>
330
341
  </template>
@@ -48,6 +48,8 @@ const CONFLICT_TITLE_KEYS: Record<
48
48
  provision_type_unhandled: 'errors.conflict.title.provision_type_unhandled',
49
49
  preset_unsatisfiable: 'errors.conflict.title.preset_unsatisfiable',
50
50
  visual_pipeline_no_frontend: 'errors.conflict.title.visual_pipeline_no_frontend',
51
+ model_policy_blocked: 'errors.conflict.title.model_policy_blocked',
52
+ model_policy_unsupported: 'errors.conflict.title.model_policy_unsupported',
51
53
  deployer_required_before_tester: 'errors.conflict.title.deployer_required_before_tester',
52
54
  }
53
55
 
@@ -15,4 +15,9 @@ export type {
15
15
  ContentStorageConfig,
16
16
  ContentStorageSummary,
17
17
  ContentStorageCapability,
18
+ // Account-wide model-family allow/block policy.
19
+ ModelFamily,
20
+ ModelFamilyPolicy,
21
+ ModelPolicyMode,
22
+ AccountRegion,
18
23
  } from '@cat-factory/contracts'
@@ -745,6 +745,65 @@
745
745
  "title": "Diesen Runner entfernen?",
746
746
  "body": "\"{name}\" wird entfernt. Dies kann nicht rückgängig gemacht werden."
747
747
  }
748
+ },
749
+ "modelPolicy": {
750
+ "title": "Modellzugriffsrichtlinie",
751
+ "description": "Beschränkt, welche Modellfamilien die Teams dieses Kontos ausführen dürfen. Das Datenresidenz-Risiko hängt von der Bereitstellungsroute ab, daher kann eine vertrauenswürdige (residenzgarantierte) Route eine andernfalls blockierte Familie freigeben.",
752
+ "regionLabel": "Betriebsregion",
753
+ "applyPreset": "Vorlage anwenden:",
754
+ "modeLabel": "Richtlinienmodus",
755
+ "modes": {
756
+ "off": "Keine Einschränkung",
757
+ "blocklist": "Aufgeführte Familien blockieren",
758
+ "allowlist": "Nur aufgeführte Familien zulassen"
759
+ },
760
+ "familiesBlockLabel": "Blockierte Familien",
761
+ "familiesAllowLabel": "Zugelassene Familien",
762
+ "trustedLabel": "Vertrauenswürdige (residenzgarantierte) Routen",
763
+ "trustedHint": "Eine blockierte Familie bleibt verfügbar, wenn sie über eine dieser Routen bereitgestellt wird.",
764
+ "families": {
765
+ "claude": "Claude (Anthropic)",
766
+ "openai": "OpenAI / ChatGPT",
767
+ "gemini": "Gemini (Google)",
768
+ "llama": "Llama (Meta)",
769
+ "qwen": "Qwen (Alibaba)",
770
+ "kimi": "Kimi (Moonshot)",
771
+ "deepseek": "DeepSeek",
772
+ "glm": "GLM (Z.ai)"
773
+ },
774
+ "regions": {
775
+ "usa": "Vereinigte Staaten",
776
+ "europe": "Europa",
777
+ "china": "China",
778
+ "other": "Andere"
779
+ },
780
+ "providers": {
781
+ "bedrock": "AWS Bedrock"
782
+ },
783
+ "presets": {
784
+ "us-block-cn": {
785
+ "label": "In China gehostete Familien blockieren",
786
+ "description": "Blockiert DeepSeek, Qwen, Kimi und GLM; erlaubt sie nur über eine residenzgarantierte Route (z. B. Bedrock)."
787
+ },
788
+ "eu-block-cn": {
789
+ "label": "EU: in China gehostete Familien blockieren",
790
+ "description": "Blockiert DeepSeek, Qwen, Kimi und GLM; eine residenzgarantierte EU-Route (z. B. Bedrock) bleibt zulässig."
791
+ },
792
+ "eu-guaranteed-only": {
793
+ "label": "EU: nur residenzgarantierte Routen",
794
+ "description": "Erlaubt ein Modell nur, wenn es über eine residenzgarantierte Route bereitgestellt wird."
795
+ },
796
+ "cn-prefer-domestic": {
797
+ "label": "In China gehostete Familien bevorzugen",
798
+ "description": "Erlaubt in China gehostete Familien (plus Llama) und jede residenzgarantierte Route."
799
+ },
800
+ "other-block-cn": {
801
+ "label": "In China gehostete Familien blockieren",
802
+ "description": "Blockiert DeepSeek, Qwen, Kimi und GLM; erlaubt sie nur über eine residenzgarantierte Route."
803
+ }
804
+ },
805
+ "saved": "Modellzugriffsrichtlinie gespeichert",
806
+ "saveFailed": "Modellzugriffsrichtlinie konnte nicht gespeichert werden"
748
807
  }
749
808
  },
750
809
  "inspector": {
@@ -3591,6 +3650,8 @@
3591
3650
  "provision_type_unhandled": "Kein Handler für diesen Bereitstellungstyp",
3592
3651
  "preset_unsatisfiable": "Modell-Preset kann diese Pipeline nicht ausführen",
3593
3652
  "visual_pipeline_no_frontend": "Kein Frontend zum Testen",
3653
+ "model_policy_blocked": "Modell durch Kontorichtlinie blockiert",
3654
+ "model_policy_unsupported": "Modellrichtlinie hier nicht verfügbar",
3594
3655
  "deployer_required_before_tester": "Füge einen Deployer vor dem Tester hinzu"
3595
3656
  },
3596
3657
  "fallbackMessage": "Diese Aktion steht im Konflikt mit dem aktuellen Zustand.",
@@ -439,6 +439,8 @@
439
439
  "provision_type_unhandled": "No handler for this provision type",
440
440
  "preset_unsatisfiable": "Model preset can't run this pipeline",
441
441
  "visual_pipeline_no_frontend": "No frontend to test",
442
+ "model_policy_blocked": "Model blocked by account policy",
443
+ "model_policy_unsupported": "Model policy not available here",
442
444
  "deployer_required_before_tester": "Add a Deployer before the Tester"
443
445
  },
444
446
  "fallbackMessage": "This action conflicts with the current state.",
@@ -2442,6 +2444,65 @@
2442
2444
  "title": "Remove this runner?",
2443
2445
  "body": "\"{name}\" will be removed. This can't be undone."
2444
2446
  }
2447
+ },
2448
+ "modelPolicy": {
2449
+ "title": "Model access policy",
2450
+ "description": "Restrict which model families this account’s teams can run. Data-residency risk depends on the serving route, so a trusted (residency-guaranteed) route can exempt an otherwise-blocked family.",
2451
+ "regionLabel": "Operating region",
2452
+ "applyPreset": "Apply preset:",
2453
+ "modeLabel": "Policy mode",
2454
+ "modes": {
2455
+ "off": "No restriction",
2456
+ "blocklist": "Block listed families",
2457
+ "allowlist": "Allow only listed families"
2458
+ },
2459
+ "familiesBlockLabel": "Blocked families",
2460
+ "familiesAllowLabel": "Allowed families",
2461
+ "trustedLabel": "Trusted (residency-guaranteed) routes",
2462
+ "trustedHint": "A blocked family stays available when it is served over one of these routes.",
2463
+ "families": {
2464
+ "claude": "Claude (Anthropic)",
2465
+ "openai": "OpenAI / ChatGPT",
2466
+ "gemini": "Gemini (Google)",
2467
+ "llama": "Llama (Meta)",
2468
+ "qwen": "Qwen (Alibaba)",
2469
+ "kimi": "Kimi (Moonshot)",
2470
+ "deepseek": "DeepSeek",
2471
+ "glm": "GLM (Z.ai)"
2472
+ },
2473
+ "regions": {
2474
+ "usa": "United States",
2475
+ "europe": "Europe",
2476
+ "china": "China",
2477
+ "other": "Other"
2478
+ },
2479
+ "providers": {
2480
+ "bedrock": "AWS Bedrock"
2481
+ },
2482
+ "presets": {
2483
+ "us-block-cn": {
2484
+ "label": "Block China-hosted families",
2485
+ "description": "Block DeepSeek, Qwen, Kimi and GLM; allow them only over a residency-guaranteed route (e.g. Bedrock)."
2486
+ },
2487
+ "eu-block-cn": {
2488
+ "label": "EU: block China-hosted families",
2489
+ "description": "Block DeepSeek, Qwen, Kimi and GLM; a residency-guaranteed EU route (e.g. Bedrock) stays allowed."
2490
+ },
2491
+ "eu-guaranteed-only": {
2492
+ "label": "EU: residency-guaranteed routes only",
2493
+ "description": "Allow a model only when it is served over a residency-guaranteed route."
2494
+ },
2495
+ "cn-prefer-domestic": {
2496
+ "label": "Prefer China-hosted families",
2497
+ "description": "Allow China-hosted families (plus Llama) and any residency-guaranteed route."
2498
+ },
2499
+ "other-block-cn": {
2500
+ "label": "Block China-hosted families",
2501
+ "description": "Block DeepSeek, Qwen, Kimi and GLM; allow them only over a residency-guaranteed route."
2502
+ }
2503
+ },
2504
+ "saved": "Model access policy saved",
2505
+ "saveFailed": "Could not save the model access policy"
2445
2506
  }
2446
2507
  },
2447
2508
  "providers": {
@@ -399,6 +399,8 @@
399
399
  "bootstrap_reference_missing": "La arquitectura de referencia ha desaparecido",
400
400
  "preset_unsatisfiable": "El preajuste de modelo no puede ejecutar esta canalización",
401
401
  "visual_pipeline_no_frontend": "No hay frontend que probar",
402
+ "model_policy_blocked": "Modelo bloqueado por la política de la cuenta",
403
+ "model_policy_unsupported": "La política de modelos no está disponible aquí",
402
404
  "deployer_required_before_tester": "Añade un Deployer antes del Tester"
403
405
  },
404
406
  "fallbackMessage": "Esta acción entra en conflicto con el estado actual.",
@@ -2375,6 +2377,65 @@
2375
2377
  "kubeOverrideNoun": "la anulación de Kubernetes",
2376
2378
  "customNoun": "este controlador"
2377
2379
  }
2380
+ },
2381
+ "modelPolicy": {
2382
+ "title": "Política de acceso a modelos",
2383
+ "description": "Restringe qué familias de modelos pueden usar los equipos de esta cuenta. El riesgo de residencia de datos depende de la ruta de servicio, por lo que una ruta de confianza (con residencia garantizada) puede eximir a una familia que de otro modo estaría bloqueada.",
2384
+ "regionLabel": "Región de operación",
2385
+ "applyPreset": "Aplicar preajuste:",
2386
+ "modeLabel": "Modo de la política",
2387
+ "modes": {
2388
+ "off": "Sin restricción",
2389
+ "blocklist": "Bloquear las familias listadas",
2390
+ "allowlist": "Permitir solo las familias listadas"
2391
+ },
2392
+ "familiesBlockLabel": "Familias bloqueadas",
2393
+ "familiesAllowLabel": "Familias permitidas",
2394
+ "trustedLabel": "Rutas de confianza (con residencia garantizada)",
2395
+ "trustedHint": "Una familia bloqueada sigue disponible cuando se sirve a través de una de estas rutas.",
2396
+ "families": {
2397
+ "claude": "Claude (Anthropic)",
2398
+ "openai": "OpenAI / ChatGPT",
2399
+ "gemini": "Gemini (Google)",
2400
+ "llama": "Llama (Meta)",
2401
+ "qwen": "Qwen (Alibaba)",
2402
+ "kimi": "Kimi (Moonshot)",
2403
+ "deepseek": "DeepSeek",
2404
+ "glm": "GLM (Z.ai)"
2405
+ },
2406
+ "regions": {
2407
+ "usa": "Estados Unidos",
2408
+ "europe": "Europa",
2409
+ "china": "China",
2410
+ "other": "Otra"
2411
+ },
2412
+ "providers": {
2413
+ "bedrock": "AWS Bedrock"
2414
+ },
2415
+ "presets": {
2416
+ "us-block-cn": {
2417
+ "label": "Bloquear familias alojadas en China",
2418
+ "description": "Bloquea DeepSeek, Qwen, Kimi y GLM; permítelas solo a través de una ruta con residencia garantizada (p. ej. Bedrock)."
2419
+ },
2420
+ "eu-block-cn": {
2421
+ "label": "UE: bloquear familias alojadas en China",
2422
+ "description": "Bloquea DeepSeek, Qwen, Kimi y GLM; una ruta de la UE con residencia garantizada (p. ej. Bedrock) sigue permitida."
2423
+ },
2424
+ "eu-guaranteed-only": {
2425
+ "label": "UE: solo rutas con residencia garantizada",
2426
+ "description": "Permite un modelo solo cuando se sirve a través de una ruta con residencia garantizada."
2427
+ },
2428
+ "cn-prefer-domestic": {
2429
+ "label": "Preferir familias alojadas en China",
2430
+ "description": "Permite las familias alojadas en China (más Llama) y cualquier ruta con residencia garantizada."
2431
+ },
2432
+ "other-block-cn": {
2433
+ "label": "Bloquear familias alojadas en China",
2434
+ "description": "Bloquea DeepSeek, Qwen, Kimi y GLM; permítelas solo a través de una ruta con residencia garantizada."
2435
+ }
2436
+ },
2437
+ "saved": "Política de acceso a modelos guardada",
2438
+ "saveFailed": "No se pudo guardar la política de acceso a modelos"
2378
2439
  }
2379
2440
  },
2380
2441
  "providers": {
@@ -399,6 +399,8 @@
399
399
  "bootstrap_reference_missing": "L’architecture de référence a disparu",
400
400
  "preset_unsatisfiable": "Le préréglage de modèle ne peut pas exécuter ce pipeline",
401
401
  "visual_pipeline_no_frontend": "Aucun frontend à tester",
402
+ "model_policy_blocked": "Modèle bloqué par la politique du compte",
403
+ "model_policy_unsupported": "La politique de modèles n'est pas disponible ici",
402
404
  "deployer_required_before_tester": "Ajoutez un Deployer avant le Testeur"
403
405
  },
404
406
  "fallbackMessage": "Cette action est en conflit avec l’état actuel.",
@@ -2375,6 +2377,65 @@
2375
2377
  "kubeOverrideNoun": "le remplacement Kubernetes",
2376
2378
  "customNoun": "ce gestionnaire"
2377
2379
  }
2380
+ },
2381
+ "modelPolicy": {
2382
+ "title": "Politique d'accès aux modèles",
2383
+ "description": "Restreint les familles de modèles que les équipes de ce compte peuvent utiliser. Le risque lié à la résidence des données dépend de la route de service : une route de confiance (à résidence garantie) peut donc exempter une famille autrement bloquée.",
2384
+ "regionLabel": "Région d'exploitation",
2385
+ "applyPreset": "Appliquer un préréglage :",
2386
+ "modeLabel": "Mode de la politique",
2387
+ "modes": {
2388
+ "off": "Aucune restriction",
2389
+ "blocklist": "Bloquer les familles listées",
2390
+ "allowlist": "Autoriser uniquement les familles listées"
2391
+ },
2392
+ "familiesBlockLabel": "Familles bloquées",
2393
+ "familiesAllowLabel": "Familles autorisées",
2394
+ "trustedLabel": "Routes de confiance (à résidence garantie)",
2395
+ "trustedHint": "Une famille bloquée reste disponible lorsqu'elle est servie via l'une de ces routes.",
2396
+ "families": {
2397
+ "claude": "Claude (Anthropic)",
2398
+ "openai": "OpenAI / ChatGPT",
2399
+ "gemini": "Gemini (Google)",
2400
+ "llama": "Llama (Meta)",
2401
+ "qwen": "Qwen (Alibaba)",
2402
+ "kimi": "Kimi (Moonshot)",
2403
+ "deepseek": "DeepSeek",
2404
+ "glm": "GLM (Z.ai)"
2405
+ },
2406
+ "regions": {
2407
+ "usa": "États-Unis",
2408
+ "europe": "Europe",
2409
+ "china": "Chine",
2410
+ "other": "Autre"
2411
+ },
2412
+ "providers": {
2413
+ "bedrock": "AWS Bedrock"
2414
+ },
2415
+ "presets": {
2416
+ "us-block-cn": {
2417
+ "label": "Bloquer les familles hébergées en Chine",
2418
+ "description": "Bloque DeepSeek, Qwen, Kimi et GLM ; ne les autorise que via une route à résidence garantie (p. ex. Bedrock)."
2419
+ },
2420
+ "eu-block-cn": {
2421
+ "label": "UE : bloquer les familles hébergées en Chine",
2422
+ "description": "Bloque DeepSeek, Qwen, Kimi et GLM ; une route UE à résidence garantie (p. ex. Bedrock) reste autorisée."
2423
+ },
2424
+ "eu-guaranteed-only": {
2425
+ "label": "UE : routes à résidence garantie uniquement",
2426
+ "description": "N'autorise un modèle que lorsqu'il est servi via une route à résidence garantie."
2427
+ },
2428
+ "cn-prefer-domestic": {
2429
+ "label": "Préférer les familles hébergées en Chine",
2430
+ "description": "Autorise les familles hébergées en Chine (plus Llama) et toute route à résidence garantie."
2431
+ },
2432
+ "other-block-cn": {
2433
+ "label": "Bloquer les familles hébergées en Chine",
2434
+ "description": "Bloque DeepSeek, Qwen, Kimi et GLM ; ne les autorise que via une route à résidence garantie."
2435
+ }
2436
+ },
2437
+ "saved": "Politique d'accès aux modèles enregistrée",
2438
+ "saveFailed": "Impossible d'enregistrer la politique d'accès aux modèles"
2378
2439
  }
2379
2440
  },
2380
2441
  "providers": {
@@ -399,6 +399,8 @@
399
399
  "bootstrap_reference_missing": "ארכיטקטורת ההפניה נעלמה",
400
400
  "preset_unsatisfiable": "קדם‑הגדרת המודל אינה יכולה להריץ צנרת זו",
401
401
  "visual_pipeline_no_frontend": "אין frontend לבדיקה",
402
+ "model_policy_blocked": "המודל נחסם על ידי מדיניות החשבון",
403
+ "model_policy_unsupported": "מדיניות המודלים אינה זמינה כאן",
402
404
  "deployer_required_before_tester": "הוסף Deployer לפני ה-Tester"
403
405
  },
404
406
  "fallbackMessage": "פעולה זו מתנגשת עם המצב הנוכחי.",
@@ -2386,6 +2388,65 @@
2386
2388
  "title": "להסיר את ה־runner הזה?",
2387
2389
  "body": "\"{name}\" יימחק. לא ניתן לבטל פעולה זו."
2388
2390
  }
2391
+ },
2392
+ "modelPolicy": {
2393
+ "title": "מדיניות גישה למודלים",
2394
+ "description": "מגבילה אילו משפחות מודלים הצוותים של חשבון זה יכולים להריץ. סיכון תושבוּת הנתונים תלוי בנתיב השירות, ולכן נתיב מהימן (עם תושבוּת מובטחת) יכול לפטור משפחה שאחרת הייתה חסומה.",
2395
+ "regionLabel": "אזור הפעילות",
2396
+ "applyPreset": "החל תבנית:",
2397
+ "modeLabel": "מצב המדיניות",
2398
+ "modes": {
2399
+ "off": "ללא הגבלה",
2400
+ "blocklist": "חסום את המשפחות ברשימה",
2401
+ "allowlist": "אפשר רק את המשפחות ברשימה"
2402
+ },
2403
+ "familiesBlockLabel": "משפחות חסומות",
2404
+ "familiesAllowLabel": "משפחות מותרות",
2405
+ "trustedLabel": "נתיבים מהימנים (עם תושבוּת מובטחת)",
2406
+ "trustedHint": "משפחה חסומה נשארת זמינה כאשר היא מוגשת דרך אחד מהנתיבים האלה.",
2407
+ "families": {
2408
+ "claude": "Claude (Anthropic)",
2409
+ "openai": "OpenAI / ChatGPT",
2410
+ "gemini": "Gemini (Google)",
2411
+ "llama": "Llama (Meta)",
2412
+ "qwen": "Qwen (Alibaba)",
2413
+ "kimi": "Kimi (Moonshot)",
2414
+ "deepseek": "DeepSeek",
2415
+ "glm": "GLM (Z.ai)"
2416
+ },
2417
+ "regions": {
2418
+ "usa": "ארצות הברית",
2419
+ "europe": "אירופה",
2420
+ "china": "סין",
2421
+ "other": "אחר"
2422
+ },
2423
+ "providers": {
2424
+ "bedrock": "AWS Bedrock"
2425
+ },
2426
+ "presets": {
2427
+ "us-block-cn": {
2428
+ "label": "חסום משפחות המתארחות בסין",
2429
+ "description": "חוסם את DeepSeek, Qwen, Kimi ו-GLM; מתיר אותן רק דרך נתיב עם תושבוּת מובטחת (למשל Bedrock)."
2430
+ },
2431
+ "eu-block-cn": {
2432
+ "label": "האיחוד האירופי: חסום משפחות המתארחות בסין",
2433
+ "description": "חוסם את DeepSeek, Qwen, Kimi ו-GLM; נתיב של האיחוד האירופי עם תושבוּת מובטחת (למשל Bedrock) נשאר מותר."
2434
+ },
2435
+ "eu-guaranteed-only": {
2436
+ "label": "האיחוד האירופי: רק נתיבים עם תושבוּת מובטחת",
2437
+ "description": "מתיר מודל רק כאשר הוא מוגש דרך נתיב עם תושבוּת מובטחת."
2438
+ },
2439
+ "cn-prefer-domestic": {
2440
+ "label": "העדף משפחות המתארחות בסין",
2441
+ "description": "מתיר משפחות המתארחות בסין (וגם Llama) וכל נתיב עם תושבוּת מובטחת."
2442
+ },
2443
+ "other-block-cn": {
2444
+ "label": "חסום משפחות המתארחות בסין",
2445
+ "description": "חוסם את DeepSeek, Qwen, Kimi ו-GLM; מתיר אותן רק דרך נתיב עם תושבוּת מובטחת."
2446
+ }
2447
+ },
2448
+ "saved": "מדיניות הגישה למודלים נשמרה",
2449
+ "saveFailed": "לא ניתן היה לשמור את מדיניות הגישה למודלים"
2389
2450
  }
2390
2451
  },
2391
2452
  "providers": {
@@ -745,6 +745,65 @@
745
745
  "title": "Rimuovere questo runner?",
746
746
  "body": "\"{name}\" verra rimosso. Questa operazione non puo essere annullata."
747
747
  }
748
+ },
749
+ "modelPolicy": {
750
+ "title": "Policy di accesso ai modelli",
751
+ "description": "Limita quali famiglie di modelli possono usare i team di questo account. Il rischio di residenza dei dati dipende dalla rotta di servizio, quindi una rotta attendibile (con residenza garantita) può esentare una famiglia altrimenti bloccata.",
752
+ "regionLabel": "Regione operativa",
753
+ "applyPreset": "Applica preset:",
754
+ "modeLabel": "Modalità della policy",
755
+ "modes": {
756
+ "off": "Nessuna restrizione",
757
+ "blocklist": "Blocca le famiglie elencate",
758
+ "allowlist": "Consenti solo le famiglie elencate"
759
+ },
760
+ "familiesBlockLabel": "Famiglie bloccate",
761
+ "familiesAllowLabel": "Famiglie consentite",
762
+ "trustedLabel": "Rotte attendibili (con residenza garantita)",
763
+ "trustedHint": "Una famiglia bloccata resta disponibile quando viene servita tramite una di queste rotte.",
764
+ "families": {
765
+ "claude": "Claude (Anthropic)",
766
+ "openai": "OpenAI / ChatGPT",
767
+ "gemini": "Gemini (Google)",
768
+ "llama": "Llama (Meta)",
769
+ "qwen": "Qwen (Alibaba)",
770
+ "kimi": "Kimi (Moonshot)",
771
+ "deepseek": "DeepSeek",
772
+ "glm": "GLM (Z.ai)"
773
+ },
774
+ "regions": {
775
+ "usa": "Stati Uniti",
776
+ "europe": "Europa",
777
+ "china": "Cina",
778
+ "other": "Altro"
779
+ },
780
+ "providers": {
781
+ "bedrock": "AWS Bedrock"
782
+ },
783
+ "presets": {
784
+ "us-block-cn": {
785
+ "label": "Blocca le famiglie ospitate in Cina",
786
+ "description": "Blocca DeepSeek, Qwen, Kimi e GLM; consentile solo tramite una rotta con residenza garantita (es. Bedrock)."
787
+ },
788
+ "eu-block-cn": {
789
+ "label": "UE: blocca le famiglie ospitate in Cina",
790
+ "description": "Blocca DeepSeek, Qwen, Kimi e GLM; una rotta UE con residenza garantita (es. Bedrock) resta consentita."
791
+ },
792
+ "eu-guaranteed-only": {
793
+ "label": "UE: solo rotte con residenza garantita",
794
+ "description": "Consente un modello solo quando è servito tramite una rotta con residenza garantita."
795
+ },
796
+ "cn-prefer-domestic": {
797
+ "label": "Preferisci le famiglie ospitate in Cina",
798
+ "description": "Consente le famiglie ospitate in Cina (più Llama) e qualsiasi rotta con residenza garantita."
799
+ },
800
+ "other-block-cn": {
801
+ "label": "Blocca le famiglie ospitate in Cina",
802
+ "description": "Blocca DeepSeek, Qwen, Kimi e GLM; consentile solo tramite una rotta con residenza garantita."
803
+ }
804
+ },
805
+ "saved": "Policy di accesso ai modelli salvata",
806
+ "saveFailed": "Impossibile salvare la policy di accesso ai modelli"
748
807
  }
749
808
  },
750
809
  "inspector": {
@@ -3591,6 +3650,8 @@
3591
3650
  "provision_type_unhandled": "Nessun gestore per questo tipo di provisioning",
3592
3651
  "preset_unsatisfiable": "Il preset del modello non può eseguire questa pipeline",
3593
3652
  "visual_pipeline_no_frontend": "Nessun frontend da testare",
3653
+ "model_policy_blocked": "Modello bloccato dalla policy dell'account",
3654
+ "model_policy_unsupported": "Policy dei modelli non disponibile qui",
3594
3655
  "deployer_required_before_tester": "Aggiungi un Deployer prima del Tester"
3595
3656
  },
3596
3657
  "fallbackMessage": "Questa azione è in conflitto con lo stato attuale.",
@@ -399,6 +399,8 @@
399
399
  "bootstrap_reference_missing": "リファレンスアーキテクチャが見つかりません",
400
400
  "preset_unsatisfiable": "モデルプリセットではこのパイプラインを実行できません",
401
401
  "visual_pipeline_no_frontend": "テスト対象のフロントエンドがありません",
402
+ "model_policy_blocked": "アカウントのポリシーによりモデルがブロックされています",
403
+ "model_policy_unsupported": "モデルポリシーはここでは利用できません",
402
404
  "deployer_required_before_tester": "テスターの前にDeployerを追加してください"
403
405
  },
404
406
  "fallbackMessage": "この操作は現在の状態と競合します。",
@@ -2387,6 +2389,65 @@
2387
2389
  "title": "このランナーを削除しますか?",
2388
2390
  "body": "「{name}」が削除されます。 この操作は取り消せません。"
2389
2391
  }
2392
+ },
2393
+ "modelPolicy": {
2394
+ "title": "モデルアクセスポリシー",
2395
+ "description": "このアカウントのチームが実行できるモデルファミリーを制限します。データレジデンシーのリスクは提供経路に依存するため、信頼された(レジデンシー保証済みの)経路であれば、通常はブロックされるファミリーを除外できます。",
2396
+ "regionLabel": "運用リージョン",
2397
+ "applyPreset": "プリセットを適用:",
2398
+ "modeLabel": "ポリシーモード",
2399
+ "modes": {
2400
+ "off": "制限なし",
2401
+ "blocklist": "リストされたファミリーをブロック",
2402
+ "allowlist": "リストされたファミリーのみ許可"
2403
+ },
2404
+ "familiesBlockLabel": "ブロックするファミリー",
2405
+ "familiesAllowLabel": "許可するファミリー",
2406
+ "trustedLabel": "信頼された(レジデンシー保証済みの)経路",
2407
+ "trustedHint": "ブロックされたファミリーでも、これらの経路のいずれかで提供される場合は利用可能なままです。",
2408
+ "families": {
2409
+ "claude": "Claude (Anthropic)",
2410
+ "openai": "OpenAI / ChatGPT",
2411
+ "gemini": "Gemini (Google)",
2412
+ "llama": "Llama (Meta)",
2413
+ "qwen": "Qwen (Alibaba)",
2414
+ "kimi": "Kimi (Moonshot)",
2415
+ "deepseek": "DeepSeek",
2416
+ "glm": "GLM (Z.ai)"
2417
+ },
2418
+ "regions": {
2419
+ "usa": "アメリカ合衆国",
2420
+ "europe": "ヨーロッパ",
2421
+ "china": "中国",
2422
+ "other": "その他"
2423
+ },
2424
+ "providers": {
2425
+ "bedrock": "AWS Bedrock"
2426
+ },
2427
+ "presets": {
2428
+ "us-block-cn": {
2429
+ "label": "中国でホストされるファミリーをブロック",
2430
+ "description": "DeepSeek、Qwen、Kimi、GLM をブロックし、レジデンシー保証済みの経路(例: Bedrock)経由でのみ許可します。"
2431
+ },
2432
+ "eu-block-cn": {
2433
+ "label": "EU: 中国でホストされるファミリーをブロック",
2434
+ "description": "DeepSeek、Qwen、Kimi、GLM をブロックしますが、レジデンシー保証済みの EU 経路(例: Bedrock)は許可されたままです。"
2435
+ },
2436
+ "eu-guaranteed-only": {
2437
+ "label": "EU: レジデンシー保証済みの経路のみ",
2438
+ "description": "レジデンシー保証済みの経路で提供される場合にのみモデルを許可します。"
2439
+ },
2440
+ "cn-prefer-domestic": {
2441
+ "label": "中国でホストされるファミリーを優先",
2442
+ "description": "中国でホストされるファミリー(および Llama)と、レジデンシー保証済みの任意の経路を許可します。"
2443
+ },
2444
+ "other-block-cn": {
2445
+ "label": "中国でホストされるファミリーをブロック",
2446
+ "description": "DeepSeek、Qwen、Kimi、GLM をブロックし、レジデンシー保証済みの経路経由でのみ許可します。"
2447
+ }
2448
+ },
2449
+ "saved": "モデルアクセスポリシーを保存しました",
2450
+ "saveFailed": "モデルアクセスポリシーを保存できませんでした"
2390
2451
  }
2391
2452
  },
2392
2453
  "providers": {
@@ -399,6 +399,8 @@
399
399
  "bootstrap_reference_missing": "Architektura referencyjna zniknęła",
400
400
  "preset_unsatisfiable": "Ten zestaw modeli nie może uruchomić tego potoku",
401
401
  "visual_pipeline_no_frontend": "Brak frontendu do przetestowania",
402
+ "model_policy_blocked": "Model zablokowany przez politykę konta",
403
+ "model_policy_unsupported": "Polityka modeli jest tu niedostępna",
402
404
  "deployer_required_before_tester": "Dodaj Deployer przed Testerem"
403
405
  },
404
406
  "fallbackMessage": "Ta akcja jest sprzeczna z bieżącym stanem.",
@@ -2375,6 +2377,65 @@
2375
2377
  "kubeOverrideNoun": "nadpisanie Kubernetes",
2376
2378
  "customNoun": "tę obsługę"
2377
2379
  }
2380
+ },
2381
+ "modelPolicy": {
2382
+ "title": "Polityka dostępu do modeli",
2383
+ "description": "Ogranicza, które rodziny modeli mogą uruchamiać zespoły tego konta. Ryzyko rezydencji danych zależy od trasy obsługi, więc zaufana trasa (z gwarantowaną rezydencją) może zwolnić rodzinę, która w innym przypadku byłaby zablokowana.",
2384
+ "regionLabel": "Region działania",
2385
+ "applyPreset": "Zastosuj szablon:",
2386
+ "modeLabel": "Tryb polityki",
2387
+ "modes": {
2388
+ "off": "Bez ograniczeń",
2389
+ "blocklist": "Blokuj wymienione rodziny",
2390
+ "allowlist": "Zezwól tylko na wymienione rodziny"
2391
+ },
2392
+ "familiesBlockLabel": "Zablokowane rodziny",
2393
+ "familiesAllowLabel": "Dozwolone rodziny",
2394
+ "trustedLabel": "Zaufane trasy (z gwarantowaną rezydencją)",
2395
+ "trustedHint": "Zablokowana rodzina pozostaje dostępna, gdy jest obsługiwana przez jedną z tych tras.",
2396
+ "families": {
2397
+ "claude": "Claude (Anthropic)",
2398
+ "openai": "OpenAI / ChatGPT",
2399
+ "gemini": "Gemini (Google)",
2400
+ "llama": "Llama (Meta)",
2401
+ "qwen": "Qwen (Alibaba)",
2402
+ "kimi": "Kimi (Moonshot)",
2403
+ "deepseek": "DeepSeek",
2404
+ "glm": "GLM (Z.ai)"
2405
+ },
2406
+ "regions": {
2407
+ "usa": "Stany Zjednoczone",
2408
+ "europe": "Europa",
2409
+ "china": "Chiny",
2410
+ "other": "Inny"
2411
+ },
2412
+ "providers": {
2413
+ "bedrock": "AWS Bedrock"
2414
+ },
2415
+ "presets": {
2416
+ "us-block-cn": {
2417
+ "label": "Blokuj rodziny hostowane w Chinach",
2418
+ "description": "Blokuje DeepSeek, Qwen, Kimi i GLM; zezwala na nie tylko przez trasę z gwarantowaną rezydencją (np. Bedrock)."
2419
+ },
2420
+ "eu-block-cn": {
2421
+ "label": "UE: blokuj rodziny hostowane w Chinach",
2422
+ "description": "Blokuje DeepSeek, Qwen, Kimi i GLM; trasa UE z gwarantowaną rezydencją (np. Bedrock) pozostaje dozwolona."
2423
+ },
2424
+ "eu-guaranteed-only": {
2425
+ "label": "UE: tylko trasy z gwarantowaną rezydencją",
2426
+ "description": "Zezwala na model tylko wtedy, gdy jest obsługiwany przez trasę z gwarantowaną rezydencją."
2427
+ },
2428
+ "cn-prefer-domestic": {
2429
+ "label": "Preferuj rodziny hostowane w Chinach",
2430
+ "description": "Zezwala na rodziny hostowane w Chinach (oraz Llama) i dowolną trasę z gwarantowaną rezydencją."
2431
+ },
2432
+ "other-block-cn": {
2433
+ "label": "Blokuj rodziny hostowane w Chinach",
2434
+ "description": "Blokuje DeepSeek, Qwen, Kimi i GLM; zezwala na nie tylko przez trasę z gwarantowaną rezydencją."
2435
+ }
2436
+ },
2437
+ "saved": "Zapisano politykę dostępu do modeli",
2438
+ "saveFailed": "Nie udało się zapisać polityki dostępu do modeli"
2378
2439
  }
2379
2440
  },
2380
2441
  "providers": {
@@ -399,6 +399,8 @@
399
399
  "bootstrap_reference_missing": "Referans mimari kayıp",
400
400
  "preset_unsatisfiable": "Model ön ayarı bu ardışık düzeni çalıştıramıyor",
401
401
  "visual_pipeline_no_frontend": "Test edilecek bir frontend yok",
402
+ "model_policy_blocked": "Model, hesap politikası tarafından engellendi",
403
+ "model_policy_unsupported": "Model politikası burada kullanılamıyor",
402
404
  "deployer_required_before_tester": "Tester’dan önce bir Deployer ekleyin"
403
405
  },
404
406
  "fallbackMessage": "Bu eylem mevcut durumla çelişiyor.",
@@ -2387,6 +2389,65 @@
2387
2389
  "title": "Bu runner kaldırılsın mı?",
2388
2390
  "body": "\"{name}\" kaldırılacak. Bu işlem geri alınamaz."
2389
2391
  }
2392
+ },
2393
+ "modelPolicy": {
2394
+ "title": "Model erişim politikası",
2395
+ "description": "Bu hesabın ekiplerinin hangi model ailelerini çalıştırabileceğini kısıtlar. Veri yerleşimi riski hizmet rotasına bağlıdır; bu nedenle güvenilir (yerleşimi garantili) bir rota, aksi takdirde engellenmiş bir aileyi muaf tutabilir.",
2396
+ "regionLabel": "Çalışma bölgesi",
2397
+ "applyPreset": "Ön ayarı uygula:",
2398
+ "modeLabel": "Politika modu",
2399
+ "modes": {
2400
+ "off": "Kısıtlama yok",
2401
+ "blocklist": "Listelenen aileleri engelle",
2402
+ "allowlist": "Yalnızca listelenen ailelere izin ver"
2403
+ },
2404
+ "familiesBlockLabel": "Engellenen aileler",
2405
+ "familiesAllowLabel": "İzin verilen aileler",
2406
+ "trustedLabel": "Güvenilir (yerleşimi garantili) rotalar",
2407
+ "trustedHint": "Engellenen bir aile, bu rotalardan biri üzerinden sunulduğunda kullanılabilir kalır.",
2408
+ "families": {
2409
+ "claude": "Claude (Anthropic)",
2410
+ "openai": "OpenAI / ChatGPT",
2411
+ "gemini": "Gemini (Google)",
2412
+ "llama": "Llama (Meta)",
2413
+ "qwen": "Qwen (Alibaba)",
2414
+ "kimi": "Kimi (Moonshot)",
2415
+ "deepseek": "DeepSeek",
2416
+ "glm": "GLM (Z.ai)"
2417
+ },
2418
+ "regions": {
2419
+ "usa": "Amerika Birleşik Devletleri",
2420
+ "europe": "Avrupa",
2421
+ "china": "Çin",
2422
+ "other": "Diğer"
2423
+ },
2424
+ "providers": {
2425
+ "bedrock": "AWS Bedrock"
2426
+ },
2427
+ "presets": {
2428
+ "us-block-cn": {
2429
+ "label": "Çin'de barındırılan aileleri engelle",
2430
+ "description": "DeepSeek, Qwen, Kimi ve GLM'yi engeller; bunlara yalnızca yerleşimi garantili bir rota üzerinden izin verir (ör. Bedrock)."
2431
+ },
2432
+ "eu-block-cn": {
2433
+ "label": "AB: Çin'de barındırılan aileleri engelle",
2434
+ "description": "DeepSeek, Qwen, Kimi ve GLM'yi engeller; yerleşimi garantili bir AB rotası (ör. Bedrock) izinli kalır."
2435
+ },
2436
+ "eu-guaranteed-only": {
2437
+ "label": "AB: yalnızca yerleşimi garantili rotalar",
2438
+ "description": "Bir modele yalnızca yerleşimi garantili bir rota üzerinden sunulduğunda izin verir."
2439
+ },
2440
+ "cn-prefer-domestic": {
2441
+ "label": "Çin'de barındırılan aileleri tercih et",
2442
+ "description": "Çin'de barındırılan ailelere (ve Llama'ya) ve yerleşimi garantili herhangi bir rotaya izin verir."
2443
+ },
2444
+ "other-block-cn": {
2445
+ "label": "Çin'de barındırılan aileleri engelle",
2446
+ "description": "DeepSeek, Qwen, Kimi ve GLM'yi engeller; bunlara yalnızca yerleşimi garantili bir rota üzerinden izin verir."
2447
+ }
2448
+ },
2449
+ "saved": "Model erişim politikası kaydedildi",
2450
+ "saveFailed": "Model erişim politikası kaydedilemedi"
2390
2451
  }
2391
2452
  },
2392
2453
  "providers": {
@@ -399,6 +399,8 @@
399
399
  "bootstrap_reference_missing": "Еталонна архітектура зникла",
400
400
  "preset_unsatisfiable": "Пресет моделі не може запустити цей конвеєр",
401
401
  "visual_pipeline_no_frontend": "Немає фронтенду для тестування",
402
+ "model_policy_blocked": "Модель заблоковано політикою облікового запису",
403
+ "model_policy_unsupported": "Політика моделей тут недоступна",
402
404
  "deployer_required_before_tester": "Додайте Deployer перед Tester"
403
405
  },
404
406
  "fallbackMessage": "Ця дія суперечить поточному стану.",
@@ -2375,6 +2377,65 @@
2375
2377
  "kubeOverrideNoun": "перевизначення Kubernetes",
2376
2378
  "customNoun": "цей обробник"
2377
2379
  }
2380
+ },
2381
+ "modelPolicy": {
2382
+ "title": "Політика доступу до моделей",
2383
+ "description": "Обмежує, які родини моделей можуть запускати команди цього облікового запису. Ризик резидентності даних залежить від маршруту обслуговування, тож довірений маршрут (із гарантованою резидентністю) може звільнити родину, яку інакше було б заблоковано.",
2384
+ "regionLabel": "Регіон роботи",
2385
+ "applyPreset": "Застосувати шаблон:",
2386
+ "modeLabel": "Режим політики",
2387
+ "modes": {
2388
+ "off": "Без обмежень",
2389
+ "blocklist": "Блокувати перелічені родини",
2390
+ "allowlist": "Дозволити лише перелічені родини"
2391
+ },
2392
+ "familiesBlockLabel": "Заблоковані родини",
2393
+ "familiesAllowLabel": "Дозволені родини",
2394
+ "trustedLabel": "Довірені маршрути (із гарантованою резидентністю)",
2395
+ "trustedHint": "Заблокована родина залишається доступною, коли обслуговується через один із цих маршрутів.",
2396
+ "families": {
2397
+ "claude": "Claude (Anthropic)",
2398
+ "openai": "OpenAI / ChatGPT",
2399
+ "gemini": "Gemini (Google)",
2400
+ "llama": "Llama (Meta)",
2401
+ "qwen": "Qwen (Alibaba)",
2402
+ "kimi": "Kimi (Moonshot)",
2403
+ "deepseek": "DeepSeek",
2404
+ "glm": "GLM (Z.ai)"
2405
+ },
2406
+ "regions": {
2407
+ "usa": "Сполучені Штати",
2408
+ "europe": "Європа",
2409
+ "china": "Китай",
2410
+ "other": "Інше"
2411
+ },
2412
+ "providers": {
2413
+ "bedrock": "AWS Bedrock"
2414
+ },
2415
+ "presets": {
2416
+ "us-block-cn": {
2417
+ "label": "Блокувати родини, розміщені в Китаї",
2418
+ "description": "Блокує DeepSeek, Qwen, Kimi та GLM; дозволяє їх лише через маршрут із гарантованою резидентністю (напр. Bedrock)."
2419
+ },
2420
+ "eu-block-cn": {
2421
+ "label": "ЄС: блокувати родини, розміщені в Китаї",
2422
+ "description": "Блокує DeepSeek, Qwen, Kimi та GLM; маршрут ЄС із гарантованою резидентністю (напр. Bedrock) залишається дозволеним."
2423
+ },
2424
+ "eu-guaranteed-only": {
2425
+ "label": "ЄС: лише маршрути з гарантованою резидентністю",
2426
+ "description": "Дозволяє модель лише тоді, коли вона обслуговується через маршрут із гарантованою резидентністю."
2427
+ },
2428
+ "cn-prefer-domestic": {
2429
+ "label": "Надавати перевагу родинам, розміщеним у Китаї",
2430
+ "description": "Дозволяє родини, розміщені в Китаї (а також Llama), і будь-який маршрут із гарантованою резидентністю."
2431
+ },
2432
+ "other-block-cn": {
2433
+ "label": "Блокувати родини, розміщені в Китаї",
2434
+ "description": "Блокує DeepSeek, Qwen, Kimi та GLM; дозволяє їх лише через маршрут із гарантованою резидентністю."
2435
+ }
2436
+ },
2437
+ "saved": "Політику доступу до моделей збережено",
2438
+ "saveFailed": "Не вдалося зберегти політику доступу до моделей"
2378
2439
  }
2379
2440
  },
2380
2441
  "providers": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cat-factory/app",
3
- "version": "0.102.0",
3
+ "version": "0.103.0",
4
4
  "description": "Reusable Nuxt layer for the Agent Architecture Board SPA (components, stores, composables, pages). Consume it from a thin deployment app via `extends: ['@cat-factory/app']` and point it at your backend with NUXT_PUBLIC_API_BASE. See deploy/frontend for an example.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -34,7 +34,7 @@
34
34
  "valibot": "^1.4.2",
35
35
  "vue": "3.5.39",
36
36
  "wretch": "^3.0.9",
37
- "@cat-factory/contracts": "0.112.0"
37
+ "@cat-factory/contracts": "0.113.0"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@toad-contracts/testing": "0.3.2",