@cat-factory/app 0.212.0 → 0.213.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/components/settings/ModelConfigurationPanel.vue +37 -0
- package/app/components/settings/ProviderPreferenceEditor.logic.spec.ts +104 -0
- package/app/components/settings/ProviderPreferenceEditor.logic.ts +81 -0
- package/app/components/settings/ProviderPreferenceEditor.vue +180 -0
- package/i18n/locales/de.json +27 -2
- package/i18n/locales/en.json +27 -2
- package/i18n/locales/es.json +27 -2
- package/i18n/locales/fr.json +27 -2
- package/i18n/locales/he.json +27 -2
- package/i18n/locales/it.json +27 -2
- package/i18n/locales/ja.json +27 -2
- package/i18n/locales/pl.json +27 -2
- package/i18n/locales/tr.json +27 -2
- package/i18n/locales/uk.json +27 -2
- package/package.json +2 -2
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
// base-model picker plus a filterable per-agent override list.
|
|
13
13
|
import { computed, ref, watch } from 'vue'
|
|
14
14
|
import { onKeyStroke } from '@vueuse/core'
|
|
15
|
+
import type { ModelFlavor } from '@cat-factory/contracts'
|
|
15
16
|
import type { AgentKind } from '~/types/domain'
|
|
16
17
|
import type { ModelPreset } from '~/types/model-presets'
|
|
17
18
|
import AgentTierSelect from '~/components/palettes/AgentTierSelect.vue'
|
|
@@ -19,9 +20,12 @@ import { filterByAgentTierKeeping } from '~/utils/agentTier'
|
|
|
19
20
|
import { MODEL_CONFIGURABLE_SYSTEM_KINDS } from '~/utils/catalog'
|
|
20
21
|
import { cachingLabel, contextLabel, costLabel, displayFlavor, isSelectable } from '~/stores/models'
|
|
21
22
|
import ConsensusGroupsSection from '~/components/settings/ConsensusGroupsSection.vue'
|
|
23
|
+
import ProviderPreferenceEditor from '~/components/settings/ProviderPreferenceEditor.vue'
|
|
24
|
+
import { showOverrideField } from '~/utils/uiMode'
|
|
22
25
|
|
|
23
26
|
const { t } = useI18n()
|
|
24
27
|
const ui = useUiStore()
|
|
28
|
+
const uiMode = useUiModeStore()
|
|
25
29
|
const models = useModelsStore()
|
|
26
30
|
const presets = useModelPresetsStore()
|
|
27
31
|
const agents = useAgentsStore()
|
|
@@ -43,6 +47,8 @@ interface EditorState {
|
|
|
43
47
|
baseModelId: string
|
|
44
48
|
overrides: Record<string, string>
|
|
45
49
|
isDefault: boolean
|
|
50
|
+
/** The preset's route order; undefined ⇒ it inherits the deployment's default order. */
|
|
51
|
+
providerPreference: ModelFlavor[] | undefined
|
|
46
52
|
}
|
|
47
53
|
const editor = ref<EditorState | null>(null)
|
|
48
54
|
const busy = ref(false)
|
|
@@ -144,6 +150,7 @@ function startCreate() {
|
|
|
144
150
|
baseModelId: selectableModels.value[0]?.id ?? 'kimi-k2.7',
|
|
145
151
|
overrides: {},
|
|
146
152
|
isDefault: false,
|
|
153
|
+
providerPreference: undefined,
|
|
147
154
|
}
|
|
148
155
|
filter.value = ''
|
|
149
156
|
}
|
|
@@ -154,10 +161,19 @@ function startEdit(p: ModelPreset) {
|
|
|
154
161
|
baseModelId: p.baseModelId,
|
|
155
162
|
overrides: { ...p.overrides },
|
|
156
163
|
isDefault: p.isDefault,
|
|
164
|
+
providerPreference: p.providerPreference ? [...p.providerPreference] : undefined,
|
|
157
165
|
}
|
|
158
166
|
filter.value = ''
|
|
159
167
|
}
|
|
160
168
|
|
|
169
|
+
// The route order is an OVERRIDE of the deployment's default, so basic mode hides it — but only
|
|
170
|
+
// while this preset states none. A preset that already carries one (written by a teammate, by the
|
|
171
|
+
// API, or here at the advanced tier) keeps the control, or a basic-mode user would be looking at a
|
|
172
|
+
// preset whose routes they can neither read nor reset.
|
|
173
|
+
const showRouteOrder = computed(() =>
|
|
174
|
+
showOverrideField(uiMode.isAdvanced, editor.value?.providerPreference),
|
|
175
|
+
)
|
|
176
|
+
|
|
161
177
|
async function setDefault(p: ModelPreset) {
|
|
162
178
|
if (p.isDefault) return
|
|
163
179
|
busy.value = true
|
|
@@ -249,6 +265,9 @@ async function save() {
|
|
|
249
265
|
baseModelId: e.baseModelId,
|
|
250
266
|
overrides: e.overrides,
|
|
251
267
|
isDefault: e.isDefault,
|
|
268
|
+
// Always sent on a patch, `[]` included: an absent field means "leave the stored order
|
|
269
|
+
// alone", so a reset has to arrive as the empty list that clears it.
|
|
270
|
+
providerPreference: e.providerPreference ?? [],
|
|
252
271
|
})
|
|
253
272
|
} else {
|
|
254
273
|
await presets.create({
|
|
@@ -256,6 +275,7 @@ async function save() {
|
|
|
256
275
|
baseModelId: e.baseModelId,
|
|
257
276
|
overrides: e.overrides,
|
|
258
277
|
isDefault: e.isDefault,
|
|
278
|
+
...(e.providerPreference ? { providerPreference: e.providerPreference } : {}),
|
|
259
279
|
})
|
|
260
280
|
}
|
|
261
281
|
editor.value = null
|
|
@@ -422,6 +442,12 @@ function fail(title: string, e: unknown) {
|
|
|
422
442
|
)
|
|
423
443
|
}}
|
|
424
444
|
</span>
|
|
445
|
+
<!-- A custom route order changes which provider the same model runs on, so the
|
|
446
|
+
list says so rather than leaving it visible only inside the editor (which
|
|
447
|
+
basic mode hides). -->
|
|
448
|
+
<span v-if="p.providerPreference?.length" class="text-slate-300">
|
|
449
|
+
· {{ t('settings.modelConfiguration.list.customRouteOrder') }}
|
|
450
|
+
</span>
|
|
425
451
|
</div>
|
|
426
452
|
</div>
|
|
427
453
|
<p
|
|
@@ -483,6 +509,17 @@ function fail(title: string, e: unknown) {
|
|
|
483
509
|
</label>
|
|
484
510
|
</div>
|
|
485
511
|
|
|
512
|
+
<!-- Which of a model's ROUTES this preset's runs prefer: a compliance preset can put
|
|
513
|
+
AWS Bedrock ahead of a model's own provider API, an everyday preset a flat-rate
|
|
514
|
+
subscription first. An override of the deployment default, so basic mode hides it
|
|
515
|
+
until the preset actually carries one. -->
|
|
516
|
+
<ProviderPreferenceEditor
|
|
517
|
+
v-if="showRouteOrder"
|
|
518
|
+
v-model="editor.providerPreference"
|
|
519
|
+
:has-subscription="creds.configuredVendors.size > 0"
|
|
520
|
+
:is-default-preset="editor.isDefault"
|
|
521
|
+
/>
|
|
522
|
+
|
|
486
523
|
<div>
|
|
487
524
|
<div class="mb-1 flex items-start justify-between gap-3">
|
|
488
525
|
<span class="text-[11px] font-semibold uppercase tracking-wide text-slate-400">
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { DEFAULT_MODEL_FLAVOR_ORDER, type ModelFlavor } from '@cat-factory/contracts'
|
|
3
|
+
import {
|
|
4
|
+
commitFlavorOrder,
|
|
5
|
+
isDefaultFlavorOrder,
|
|
6
|
+
moveFlavor,
|
|
7
|
+
subscriptionOverridesOrder,
|
|
8
|
+
} from '~/components/settings/ProviderPreferenceEditor.logic'
|
|
9
|
+
|
|
10
|
+
const DEFAULT = [...DEFAULT_MODEL_FLAVOR_ORDER]
|
|
11
|
+
|
|
12
|
+
describe('isDefaultFlavorOrder', () => {
|
|
13
|
+
it('is true only for the full shipped order, position for position', () => {
|
|
14
|
+
expect(isDefaultFlavorOrder(DEFAULT)).toBe(true)
|
|
15
|
+
expect(isDefaultFlavorOrder([...DEFAULT].reverse())).toBe(false)
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
it('rejects a PREFIX of the default rather than reading it as "no preference"', () => {
|
|
19
|
+
// `every` is vacuously true for a prefix, so without the length check a partial order that
|
|
20
|
+
// happens to start like the default would be silently cleared — the preset would lose an
|
|
21
|
+
// order the caller meant to store.
|
|
22
|
+
expect(isDefaultFlavorOrder(DEFAULT.slice(0, 2))).toBe(false)
|
|
23
|
+
expect(isDefaultFlavorOrder([])).toBe(false)
|
|
24
|
+
})
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
describe('commitFlavorOrder', () => {
|
|
28
|
+
it('stores an order that equals the default as ABSENT, not as a copy of it', () => {
|
|
29
|
+
// The whole "a preset keeps tracking the shipped order as the product changes it" property
|
|
30
|
+
// rests on this, and the SPA is the only place it happens.
|
|
31
|
+
expect(commitFlavorOrder(DEFAULT)).toBeUndefined()
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it('stores a genuinely reordered list', () => {
|
|
35
|
+
const reordered: ModelFlavor[] = [
|
|
36
|
+
'bedrock',
|
|
37
|
+
'direct',
|
|
38
|
+
'openrouter',
|
|
39
|
+
'cloudflare',
|
|
40
|
+
'subscription',
|
|
41
|
+
]
|
|
42
|
+
expect(commitFlavorOrder(reordered)).toEqual(reordered)
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it('copies rather than aliasing the array it was given', () => {
|
|
46
|
+
const next: ModelFlavor[] = ['bedrock', 'direct', 'openrouter', 'cloudflare', 'subscription']
|
|
47
|
+
const stored = commitFlavorOrder(next)
|
|
48
|
+
next[0] = 'cloudflare'
|
|
49
|
+
expect(stored?.[0]).toBe('bedrock')
|
|
50
|
+
})
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
describe('moveFlavor', () => {
|
|
54
|
+
it('swaps with the neighbour in the given direction', () => {
|
|
55
|
+
expect(moveFlavor(DEFAULT, 1, -1)).toEqual([DEFAULT[1], DEFAULT[0], ...DEFAULT.slice(2)])
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
it('is a no-op past either end', () => {
|
|
59
|
+
expect(moveFlavor(DEFAULT, 0, -1)).toBeUndefined()
|
|
60
|
+
expect(moveFlavor(DEFAULT, DEFAULT.length - 1, 1)).toBeUndefined()
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
it('never drops or duplicates a route (a preference reorders, it never filters)', () => {
|
|
64
|
+
const moved = moveFlavor(DEFAULT, 2, 1)!
|
|
65
|
+
expect([...moved].sort()).toEqual([...DEFAULT].sort())
|
|
66
|
+
})
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
describe('subscriptionOverridesOrder', () => {
|
|
70
|
+
const compliance: ModelFlavor[] = ['bedrock', 'direct']
|
|
71
|
+
const subscriptionFirst: ModelFlavor[] = ['subscription', 'direct']
|
|
72
|
+
|
|
73
|
+
it('warns whenever a connected plan can overrule the order (the compliance-preset case)', () => {
|
|
74
|
+
// "Subscriptions always win" is applied by the engine ON TOP of the route this order resolves,
|
|
75
|
+
// so a preset promoting AWS Bedrock is silently overruled for a dual-mode model on a workspace
|
|
76
|
+
// holding a token. The control has to say so rather than promise the route.
|
|
77
|
+
expect(subscriptionOverridesOrder({ preference: compliance, hasSubscription: true })).toBe(true)
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
it('stays quiet when the order already puts the subscription first (override agrees with it)', () => {
|
|
81
|
+
expect(
|
|
82
|
+
subscriptionOverridesOrder({ preference: subscriptionFirst, hasSubscription: true }),
|
|
83
|
+
).toBe(false)
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it('stays quiet with no connected subscription — no token, no override', () => {
|
|
87
|
+
expect(subscriptionOverridesOrder({ preference: compliance, hasSubscription: false })).toBe(
|
|
88
|
+
false,
|
|
89
|
+
)
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
it('stays quiet when the preset states no order at all (nothing was promised)', () => {
|
|
93
|
+
expect(subscriptionOverridesOrder({ preference: undefined, hasSubscription: true })).toBe(false)
|
|
94
|
+
expect(subscriptionOverridesOrder({ preference: [], hasSubscription: true })).toBe(false)
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
it('judges the RESOLVED total order, not the caller’s partial list', () => {
|
|
98
|
+
// A one-entry list still resolves to a full order, so "is subscription first" is answerable
|
|
99
|
+
// for it — and `['subscription']` promotes the route even though it names nothing else.
|
|
100
|
+
expect(
|
|
101
|
+
subscriptionOverridesOrder({ preference: ['subscription'], hasSubscription: true }),
|
|
102
|
+
).toBe(false)
|
|
103
|
+
})
|
|
104
|
+
})
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// The pure half of `ProviderPreferenceEditor.vue`: what a reordering COMMITS, and what the
|
|
2
|
+
// control has to say about a route order the run path may still override. Extracted so both can
|
|
3
|
+
// be pinned without mounting Vue — the "equals the default is stored as absent" normalisation in
|
|
4
|
+
// particular, which the backend's whole "a preset keeps tracking the shipped order" property rests
|
|
5
|
+
// on and which no backend test can see (the SPA is the only thing that performs it).
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
DEFAULT_MODEL_FLAVOR_ORDER,
|
|
9
|
+
type ModelFlavor,
|
|
10
|
+
orderedModelFlavorPreference,
|
|
11
|
+
} from '@cat-factory/contracts'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Whether an order is today's shipped default, position for position.
|
|
15
|
+
*
|
|
16
|
+
* The length check is not redundant: `every` is vacuously true for a PREFIX, so without it a
|
|
17
|
+
* partial order that happens to start like the default would be read as "no preference" and
|
|
18
|
+
* silently cleared. The editor only ever produces full permutations, which is exactly why the
|
|
19
|
+
* guard belongs here rather than in the caller — it is what keeps that a property of this
|
|
20
|
+
* function instead of a property of its one current caller.
|
|
21
|
+
*/
|
|
22
|
+
export function isDefaultFlavorOrder(next: readonly ModelFlavor[]): boolean {
|
|
23
|
+
return (
|
|
24
|
+
next.length === DEFAULT_MODEL_FLAVOR_ORDER.length &&
|
|
25
|
+
next.every((flavor, i) => DEFAULT_MODEL_FLAVOR_ORDER[i] === flavor)
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* What a reordering stores: the new order, or UNSET when it lands back on the shipped default.
|
|
31
|
+
*
|
|
32
|
+
* "No preference" and "an order that happens to match today's default" are different states, and
|
|
33
|
+
* only the first keeps following the shipped order as the product changes it. Storing a copy would
|
|
34
|
+
* silently pin today's wording of a list that is itself scheduled to be reordered.
|
|
35
|
+
*/
|
|
36
|
+
export function commitFlavorOrder(next: readonly ModelFlavor[]): ModelFlavor[] | undefined {
|
|
37
|
+
return isDefaultFlavorOrder(next) ? undefined : [...next]
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Swap the entry at `index` with its neighbour `delta` away; undefined when the move is a no-op. */
|
|
41
|
+
export function moveFlavor(
|
|
42
|
+
order: readonly ModelFlavor[],
|
|
43
|
+
index: number,
|
|
44
|
+
delta: number,
|
|
45
|
+
): ModelFlavor[] | undefined {
|
|
46
|
+
const next = [...order]
|
|
47
|
+
const target = index + delta
|
|
48
|
+
const moved = next[index]
|
|
49
|
+
const displaced = next[target]
|
|
50
|
+
if (!moved || !displaced) return undefined
|
|
51
|
+
next[index] = displaced
|
|
52
|
+
next[target] = moved
|
|
53
|
+
return next
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Whether to warn that a connected subscription will still win over this order.
|
|
58
|
+
*
|
|
59
|
+
* "Subscriptions always win" is applied by the ENGINE on top of the route this order resolves: a
|
|
60
|
+
* dual-mode model (Kimi/DeepSeek/GLM) switches to its subscription flavour whenever the workspace
|
|
61
|
+
* or the run initiator holds a token, whatever the preset asked for. So the override does not
|
|
62
|
+
* merely re-rank the subscription route within this list — it sits OUTSIDE the list — and the only
|
|
63
|
+
* order it cannot contradict is one that already puts `subscription` first.
|
|
64
|
+
*
|
|
65
|
+
* That is why the test is "is subscription first", not "was subscription demoted": `subscription`
|
|
66
|
+
* is last in today's shipped order, so a demotion test could never fire, and the case that actually
|
|
67
|
+
* bites is the opposite one — a compliance preset promoting `bedrock` and being silently overruled.
|
|
68
|
+
* Until the override moves into this order, the control has to say so, because copy promising a
|
|
69
|
+
* residency-guaranteed route that a connected plan quietly overrules is the one thing a compliance
|
|
70
|
+
* preset must never do.
|
|
71
|
+
*
|
|
72
|
+
* Only when the preset actually states an order (nothing is promised otherwise) AND the workspace
|
|
73
|
+
* has a connected subscription (no token, no override).
|
|
74
|
+
*/
|
|
75
|
+
export function subscriptionOverridesOrder(input: {
|
|
76
|
+
preference: readonly ModelFlavor[] | undefined
|
|
77
|
+
hasSubscription: boolean
|
|
78
|
+
}): boolean {
|
|
79
|
+
if (!input.preference?.length || !input.hasSubscription) return false
|
|
80
|
+
return orderedModelFlavorPreference(input.preference)[0] !== 'subscription'
|
|
81
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// The ROUTE-ORDER editor for one model preset: which of a model's routes (its own provider API,
|
|
3
|
+
// AWS Bedrock, the OpenRouter gateway, Cloudflare Workers AI, a subscription harness) the preset's
|
|
4
|
+
// runs prefer, most preferred first.
|
|
5
|
+
//
|
|
6
|
+
// Two properties of the backend model decide the whole shape of this control:
|
|
7
|
+
//
|
|
8
|
+
// - A preference REORDERS, never filters. So the list always shows EVERY route and the only
|
|
9
|
+
// affordance is moving one. There is deliberately no way to remove a route: a preset that
|
|
10
|
+
// could drop one would make a model whose only route is that one unstartable, which is not
|
|
11
|
+
// what anybody choosing an order means.
|
|
12
|
+
// - "No preference" is a real, distinct state from "an order that happens to match today's
|
|
13
|
+
// default". Only the first keeps tracking the shipped order as the product changes it, so
|
|
14
|
+
// reordering back to the default clears the preference rather than storing a copy of it, and
|
|
15
|
+
// the header says which of the two the preset is in.
|
|
16
|
+
//
|
|
17
|
+
// A third property is the engine's rather than this order's, and it is why the control can warn:
|
|
18
|
+
// "subscriptions always win" is applied on TOP of the resolved route, so on a workspace with a
|
|
19
|
+
// connected plan a dual-mode model ignores an order that ranks `subscription` lower than the
|
|
20
|
+
// shipped default does. The logic module says when; the copy says so plainly.
|
|
21
|
+
import { computed } from 'vue'
|
|
22
|
+
import type { ModelFlavor } from '@cat-factory/contracts'
|
|
23
|
+
import { orderedModelFlavorPreference } from '@cat-factory/contracts'
|
|
24
|
+
import {
|
|
25
|
+
commitFlavorOrder,
|
|
26
|
+
moveFlavor,
|
|
27
|
+
subscriptionOverridesOrder,
|
|
28
|
+
} from '~/components/settings/ProviderPreferenceEditor.logic'
|
|
29
|
+
|
|
30
|
+
const props = defineProps<{
|
|
31
|
+
/** The preset's stored order; empty/absent ⇒ the deployment's default order. */
|
|
32
|
+
modelValue: ModelFlavor[] | undefined
|
|
33
|
+
/**
|
|
34
|
+
* Whether this workspace has ANY subscription vendor connected. Drives the caveat only: the
|
|
35
|
+
* override it warns about is the engine's, so the control cannot prevent it, only name it.
|
|
36
|
+
*/
|
|
37
|
+
hasSubscription?: boolean
|
|
38
|
+
/**
|
|
39
|
+
* Whether the preset being edited is the workspace DEFAULT. `GET /models` resolves its flavour
|
|
40
|
+
* badges under the default preset's order, so on any OTHER preset the model list beside this
|
|
41
|
+
* control is showing routes this order does not govern, and the control says so.
|
|
42
|
+
*/
|
|
43
|
+
isDefaultPreset?: boolean
|
|
44
|
+
}>()
|
|
45
|
+
const emit = defineEmits<{ 'update:modelValue': [ModelFlavor[] | undefined] }>()
|
|
46
|
+
|
|
47
|
+
const { t } = useI18n()
|
|
48
|
+
|
|
49
|
+
/** Static literal keys, one per route, so the typed-message-key check sees them all. */
|
|
50
|
+
const ROUTE_LABELS: Record<ModelFlavor, string> = {
|
|
51
|
+
direct: 'settings.modelConfiguration.routes.direct',
|
|
52
|
+
bedrock: 'settings.modelConfiguration.routes.bedrock',
|
|
53
|
+
openrouter: 'settings.modelConfiguration.routes.openrouter',
|
|
54
|
+
cloudflare: 'settings.modelConfiguration.routes.cloudflare',
|
|
55
|
+
subscription: 'settings.modelConfiguration.routes.subscription',
|
|
56
|
+
}
|
|
57
|
+
const ROUTE_HINTS: Record<ModelFlavor, string> = {
|
|
58
|
+
direct: 'settings.modelConfiguration.routeHints.direct',
|
|
59
|
+
bedrock: 'settings.modelConfiguration.routeHints.bedrock',
|
|
60
|
+
openrouter: 'settings.modelConfiguration.routeHints.openrouter',
|
|
61
|
+
cloudflare: 'settings.modelConfiguration.routeHints.cloudflare',
|
|
62
|
+
subscription: 'settings.modelConfiguration.routeHints.subscription',
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** The order actually in force: the preset's own, else the default. Always all five routes. */
|
|
66
|
+
const order = computed(() => orderedModelFlavorPreference(props.modelValue))
|
|
67
|
+
const isCustom = computed(() => (props.modelValue?.length ?? 0) > 0)
|
|
68
|
+
|
|
69
|
+
/** A connected plan overrules a deprioritised subscription route — see the logic module. */
|
|
70
|
+
const subscriptionWins = computed(() =>
|
|
71
|
+
subscriptionOverridesOrder({
|
|
72
|
+
preference: props.modelValue,
|
|
73
|
+
hasSubscription: props.hasSubscription ?? false,
|
|
74
|
+
}),
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
/** The badges beside this control render under the DEFAULT preset's order, not this one's. */
|
|
78
|
+
const badgesShowAnotherOrder = computed(() => isCustom.value && props.isDefaultPreset === false)
|
|
79
|
+
|
|
80
|
+
function move(index: number, delta: number) {
|
|
81
|
+
const next = moveFlavor(order.value, index, delta)
|
|
82
|
+
if (next) emit('update:modelValue', commitFlavorOrder(next))
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function reset() {
|
|
86
|
+
emit('update:modelValue', undefined)
|
|
87
|
+
}
|
|
88
|
+
</script>
|
|
89
|
+
|
|
90
|
+
<template>
|
|
91
|
+
<div>
|
|
92
|
+
<div class="mb-1 flex items-start justify-between gap-3">
|
|
93
|
+
<span class="text-[11px] font-semibold uppercase tracking-wide text-slate-400">
|
|
94
|
+
{{ t('settings.modelConfiguration.routeOrder.label') }}
|
|
95
|
+
</span>
|
|
96
|
+
<UButton
|
|
97
|
+
v-if="isCustom"
|
|
98
|
+
size="xs"
|
|
99
|
+
variant="ghost"
|
|
100
|
+
color="neutral"
|
|
101
|
+
icon="i-lucide-rotate-ccw"
|
|
102
|
+
data-testid="preset-route-order-reset"
|
|
103
|
+
@click="reset"
|
|
104
|
+
>
|
|
105
|
+
{{ t('settings.modelConfiguration.routeOrder.reset') }}
|
|
106
|
+
</UButton>
|
|
107
|
+
</div>
|
|
108
|
+
<p class="mb-2 text-[11px] leading-relaxed text-slate-500">
|
|
109
|
+
{{
|
|
110
|
+
isCustom
|
|
111
|
+
? t('settings.modelConfiguration.routeOrder.customHint')
|
|
112
|
+
: t('settings.modelConfiguration.routeOrder.defaultHint')
|
|
113
|
+
}}
|
|
114
|
+
</p>
|
|
115
|
+
<!-- The engine applies "subscriptions always win" ON TOP of this order, so on a workspace with
|
|
116
|
+
a connected plan a dual-mode model ignores a deprioritised subscription route. Said here
|
|
117
|
+
rather than left to be discovered in a run: copy that promises a residency-guaranteed
|
|
118
|
+
route a connected plan quietly overrules is the one thing this control must not do. -->
|
|
119
|
+
<p
|
|
120
|
+
v-if="subscriptionWins"
|
|
121
|
+
class="mb-2 text-[11px] leading-relaxed text-amber-400/90"
|
|
122
|
+
data-testid="preset-route-order-subscription-warning"
|
|
123
|
+
>
|
|
124
|
+
{{ t('settings.modelConfiguration.routeOrder.subscriptionOverrideHint') }}
|
|
125
|
+
</p>
|
|
126
|
+
<!-- The model list beside this control shows each model's route under the WORKSPACE DEFAULT
|
|
127
|
+
preset (that is what `GET /models` resolves), so on any other preset those badges are
|
|
128
|
+
answering a different question than this order asks. -->
|
|
129
|
+
<p
|
|
130
|
+
v-if="badgesShowAnotherOrder"
|
|
131
|
+
class="mb-2 text-[11px] leading-relaxed text-slate-500"
|
|
132
|
+
data-testid="preset-route-order-badge-hint"
|
|
133
|
+
>
|
|
134
|
+
{{ t('settings.modelConfiguration.routeOrder.badgesUseDefaultPresetHint') }}
|
|
135
|
+
</p>
|
|
136
|
+
<ol
|
|
137
|
+
class="divide-y divide-slate-800 rounded-xl border border-slate-800 bg-slate-900/50"
|
|
138
|
+
data-testid="preset-route-order"
|
|
139
|
+
>
|
|
140
|
+
<li
|
|
141
|
+
v-for="(flavor, index) in order"
|
|
142
|
+
:key="flavor"
|
|
143
|
+
class="flex items-center gap-3 px-4 py-2.5"
|
|
144
|
+
:data-testid="`preset-route-${flavor}`"
|
|
145
|
+
>
|
|
146
|
+
<span
|
|
147
|
+
class="flex h-5 w-5 shrink-0 items-center justify-center rounded bg-slate-800 text-[10px] font-semibold text-slate-400"
|
|
148
|
+
>
|
|
149
|
+
{{ index + 1 }}
|
|
150
|
+
</span>
|
|
151
|
+
<div class="min-w-0 flex-1">
|
|
152
|
+
<p class="truncate text-sm text-slate-200">{{ t(ROUTE_LABELS[flavor]) }}</p>
|
|
153
|
+
<p class="truncate text-[11px] text-slate-500">{{ t(ROUTE_HINTS[flavor]) }}</p>
|
|
154
|
+
</div>
|
|
155
|
+
<div class="flex shrink-0 items-center gap-1">
|
|
156
|
+
<UButton
|
|
157
|
+
size="xs"
|
|
158
|
+
variant="ghost"
|
|
159
|
+
color="neutral"
|
|
160
|
+
icon="i-lucide-chevron-up"
|
|
161
|
+
:disabled="index === 0"
|
|
162
|
+
:title="t('settings.modelConfiguration.routeOrder.moveUp')"
|
|
163
|
+
:aria-label="t('settings.modelConfiguration.routeOrder.moveUp')"
|
|
164
|
+
@click="move(index, -1)"
|
|
165
|
+
/>
|
|
166
|
+
<UButton
|
|
167
|
+
size="xs"
|
|
168
|
+
variant="ghost"
|
|
169
|
+
color="neutral"
|
|
170
|
+
icon="i-lucide-chevron-down"
|
|
171
|
+
:disabled="index === order.length - 1"
|
|
172
|
+
:title="t('settings.modelConfiguration.routeOrder.moveDown')"
|
|
173
|
+
:aria-label="t('settings.modelConfiguration.routeOrder.moveDown')"
|
|
174
|
+
@click="move(index, 1)"
|
|
175
|
+
/>
|
|
176
|
+
</div>
|
|
177
|
+
</li>
|
|
178
|
+
</ol>
|
|
179
|
+
</div>
|
|
180
|
+
</template>
|
package/i18n/locales/de.json
CHANGED
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
"deleteTitle": "Preset löschen",
|
|
23
23
|
"basePrefix": "Basis:",
|
|
24
24
|
"overrideCount": "{count} Override | {count} Overrides",
|
|
25
|
-
"empty": "Noch keine Presets. Erstelle eines, um Modelle deinen Agenten zuzuordnen."
|
|
25
|
+
"empty": "Noch keine Presets. Erstelle eines, um Modelle deinen Agenten zuzuordnen.",
|
|
26
|
+
"customRouteOrder": "eigene Routen-Reihenfolge"
|
|
26
27
|
},
|
|
27
28
|
"editor": {
|
|
28
29
|
"useBaseModel": "Basismodell verwenden",
|
|
@@ -43,6 +44,30 @@
|
|
|
43
44
|
"nameRequiredTitle": "Name erforderlich",
|
|
44
45
|
"nameRequiredBody": "Gib dem Preset einen Namen.",
|
|
45
46
|
"saveFailed": "Preset konnte nicht gespeichert werden"
|
|
47
|
+
},
|
|
48
|
+
"routes": {
|
|
49
|
+
"direct": "Die eigene Provider-API des Modells",
|
|
50
|
+
"bedrock": "AWS Bedrock",
|
|
51
|
+
"openrouter": "OpenRouter-Gateway",
|
|
52
|
+
"cloudflare": "Cloudflare Workers AI",
|
|
53
|
+
"subscription": "Abo (Claude Code / Codex)"
|
|
54
|
+
},
|
|
55
|
+
"routeHints": {
|
|
56
|
+
"direct": "Benötigt einen API-Schlüssel für diesen Provider.",
|
|
57
|
+
"bedrock": "Läuft in deiner AWS-Region, mit den für dein Konto freigegebenen Modellen.",
|
|
58
|
+
"openrouter": "Ein Schlüssel, viele Anbieter, mit Aufschlag weiterverkauft.",
|
|
59
|
+
"cloudflare": "Immer verfügbar, ohne Prompt-Caching.",
|
|
60
|
+
"subscription": "Pauschales Kontingent eines verbundenen Tarifs."
|
|
61
|
+
},
|
|
62
|
+
"routeOrder": {
|
|
63
|
+
"label": "Routen-Reihenfolge",
|
|
64
|
+
"defaultHint": "Dieses Preset folgt dem Standard des Deployments. Verschiebe eine Route nach oben, um sie zu bevorzugen.",
|
|
65
|
+
"customHint": "Dieses Preset bevorzugt Routen in dieser Reihenfolge. Ein Modell, das nur über eine niedrigere Route erreichbar ist, läuft weiterhin und wird nur später versucht.",
|
|
66
|
+
"reset": "Standardreihenfolge verwenden",
|
|
67
|
+
"moveUp": "Diese Route stärker bevorzugen",
|
|
68
|
+
"moveDown": "Diese Route weniger bevorzugen",
|
|
69
|
+
"subscriptionOverrideHint": "Ein verbundenes Abo gewinnt weiterhin bei Modellen, die eines anbieten: Die Engine leitet diese unabhängig von dieser Reihenfolge auf den Tarif. Routen unterhalb des Abo-Eintrags gelten für alle anderen Modelle.",
|
|
70
|
+
"badgesUseDefaultPresetHint": "Die Route neben jedem Modell oben ist die des Standard-Presets des Workspace, nicht die dieses Presets."
|
|
46
71
|
}
|
|
47
72
|
},
|
|
48
73
|
"account": {
|
|
@@ -5948,7 +5973,7 @@
|
|
|
5948
5973
|
"newDescription": "Neue integrierte Modell-Presets sind verfügbar. Füge sie zur Bibliothek dieses Boards hinzu.",
|
|
5949
5974
|
"add": "Hinzufügen",
|
|
5950
5975
|
"updatesHeading": "Updates verfügbar",
|
|
5951
|
-
"updatesDescription": "Eine neuere Version dieser integrierten Modell-Presets ist verfügbar. Führe ein erneutes Seeding durch, um sie zu übernehmen
|
|
5976
|
+
"updatesDescription": "Eine neuere Version dieser integrierten Modell-Presets ist verfügbar. Führe ein erneutes Seeding durch, um sie zu übernehmen: Standard und Reihenfolge bleiben erhalten, eine eigene Routen-Reihenfolge auf dem Preset wird jedoch zurückgesetzt.",
|
|
5952
5977
|
"versionAvailable": "Version {from} → {to} verfügbar.",
|
|
5953
5978
|
"reseed": "Erneut seeden",
|
|
5954
5979
|
"reseedAll": "Alle aktualisieren ({count})",
|
package/i18n/locales/en.json
CHANGED
|
@@ -2416,7 +2416,8 @@
|
|
|
2416
2416
|
"deleteTitle": "Delete preset",
|
|
2417
2417
|
"basePrefix": "Base:",
|
|
2418
2418
|
"overrideCount": "{count} override | {count} overrides",
|
|
2419
|
-
"empty": "No presets yet. Create one to map models to your agents."
|
|
2419
|
+
"empty": "No presets yet. Create one to map models to your agents.",
|
|
2420
|
+
"customRouteOrder": "custom route order"
|
|
2420
2421
|
},
|
|
2421
2422
|
"editor": {
|
|
2422
2423
|
"useBaseModel": "Use base model",
|
|
@@ -2437,6 +2438,30 @@
|
|
|
2437
2438
|
"nameRequiredTitle": "Name required",
|
|
2438
2439
|
"nameRequiredBody": "Give the preset a name.",
|
|
2439
2440
|
"saveFailed": "Could not save the preset"
|
|
2441
|
+
},
|
|
2442
|
+
"routes": {
|
|
2443
|
+
"direct": "The model's own provider API",
|
|
2444
|
+
"bedrock": "AWS Bedrock",
|
|
2445
|
+
"openrouter": "OpenRouter gateway",
|
|
2446
|
+
"cloudflare": "Cloudflare Workers AI",
|
|
2447
|
+
"subscription": "Subscription (Claude Code / Codex)"
|
|
2448
|
+
},
|
|
2449
|
+
"routeHints": {
|
|
2450
|
+
"direct": "Needs an API key for that provider.",
|
|
2451
|
+
"bedrock": "Runs in your AWS Region, on the models your account allows.",
|
|
2452
|
+
"openrouter": "One key, many vendors, resold at a margin.",
|
|
2453
|
+
"cloudflare": "Always available, no prompt caching.",
|
|
2454
|
+
"subscription": "Flat-rate quota on a connected plan."
|
|
2455
|
+
},
|
|
2456
|
+
"routeOrder": {
|
|
2457
|
+
"label": "Route order",
|
|
2458
|
+
"defaultHint": "This preset follows the deployment default. Move a route up to prefer it instead.",
|
|
2459
|
+
"customHint": "This preset prefers routes in this order. A model reachable only on a lower route still runs, it is just tried later.",
|
|
2460
|
+
"reset": "Use default order",
|
|
2461
|
+
"moveUp": "Prefer this route more",
|
|
2462
|
+
"moveDown": "Prefer this route less",
|
|
2463
|
+
"subscriptionOverrideHint": "A connected subscription still wins for models that offer one: the engine routes those to the plan regardless of this order. Routes below the subscription entry apply to every other model.",
|
|
2464
|
+
"badgesUseDefaultPresetHint": "The route shown next to each model above is the one the workspace default preset takes, not this preset's."
|
|
2440
2465
|
}
|
|
2441
2466
|
},
|
|
2442
2467
|
"account": {
|
|
@@ -4562,7 +4587,7 @@
|
|
|
4562
4587
|
"newDescription": "New built-in model presets have shipped. Add them to this board's library.",
|
|
4563
4588
|
"add": "Add",
|
|
4564
4589
|
"updatesHeading": "Updates available",
|
|
4565
|
-
"updatesDescription": "A newer version of these built-in model presets has shipped. Reseed to adopt it
|
|
4590
|
+
"updatesDescription": "A newer version of these built-in model presets has shipped. Reseed to adopt it: the default and ordering are kept, but a custom route order on the preset is cleared.",
|
|
4566
4591
|
"versionAvailable": "Version {from} → {to} available.",
|
|
4567
4592
|
"reseed": "Reseed",
|
|
4568
4593
|
"reseedAll": "Update all ({count})",
|
package/i18n/locales/es.json
CHANGED
|
@@ -2330,7 +2330,8 @@
|
|
|
2330
2330
|
"deleteTitle": "Eliminar ajuste",
|
|
2331
2331
|
"basePrefix": "Base:",
|
|
2332
2332
|
"overrideCount": "{count} anulación | {count} anulaciones",
|
|
2333
|
-
"empty": "Aún no hay ajustes. Crea uno para asignar modelos a tus agentes."
|
|
2333
|
+
"empty": "Aún no hay ajustes. Crea uno para asignar modelos a tus agentes.",
|
|
2334
|
+
"customRouteOrder": "orden de rutas personalizado"
|
|
2334
2335
|
},
|
|
2335
2336
|
"editor": {
|
|
2336
2337
|
"useBaseModel": "Usar el modelo base",
|
|
@@ -2355,6 +2356,30 @@
|
|
|
2355
2356
|
"confirmDelete": {
|
|
2356
2357
|
"title": "¿Eliminar este preset de modelo?",
|
|
2357
2358
|
"body": "Se eliminará \"{name}\". Las tareas que lo usan volverán al valor predeterminado del espacio de trabajo."
|
|
2359
|
+
},
|
|
2360
|
+
"routes": {
|
|
2361
|
+
"direct": "La API propia del proveedor del modelo",
|
|
2362
|
+
"bedrock": "AWS Bedrock",
|
|
2363
|
+
"openrouter": "Pasarela OpenRouter",
|
|
2364
|
+
"cloudflare": "Cloudflare Workers AI",
|
|
2365
|
+
"subscription": "Suscripción (Claude Code / Codex)"
|
|
2366
|
+
},
|
|
2367
|
+
"routeHints": {
|
|
2368
|
+
"direct": "Requiere una clave de API para ese proveedor.",
|
|
2369
|
+
"bedrock": "Se ejecuta en tu región de AWS, con los modelos que tu cuenta permite.",
|
|
2370
|
+
"openrouter": "Una clave, muchos proveedores, revendidos con margen.",
|
|
2371
|
+
"cloudflare": "Siempre disponible, sin caché de prompts.",
|
|
2372
|
+
"subscription": "Cuota de tarifa plana en un plan conectado."
|
|
2373
|
+
},
|
|
2374
|
+
"routeOrder": {
|
|
2375
|
+
"label": "Orden de rutas",
|
|
2376
|
+
"defaultHint": "Este preajuste sigue el valor predeterminado del despliegue. Sube una ruta para preferirla.",
|
|
2377
|
+
"customHint": "Este preajuste prefiere las rutas en este orden. Un modelo accesible solo por una ruta inferior sigue funcionando, solo se intenta más tarde.",
|
|
2378
|
+
"reset": "Usar el orden predeterminado",
|
|
2379
|
+
"moveUp": "Preferir más esta ruta",
|
|
2380
|
+
"moveDown": "Preferir menos esta ruta",
|
|
2381
|
+
"subscriptionOverrideHint": "Una suscripción conectada sigue ganando en los modelos que ofrecen una: el motor los enruta al plan sin importar este orden. Las rutas por debajo de la entrada de suscripción se aplican a todos los demás modelos.",
|
|
2382
|
+
"badgesUseDefaultPresetHint": "La ruta que aparece junto a cada modelo arriba es la del preset predeterminado del espacio de trabajo, no la de este preset."
|
|
2358
2383
|
}
|
|
2359
2384
|
},
|
|
2360
2385
|
"account": {
|
|
@@ -5802,7 +5827,7 @@
|
|
|
5802
5827
|
"newDescription": "Hay nuevos presets de modelo integrados. Añádelos a la biblioteca de este tablero.",
|
|
5803
5828
|
"add": "Añadir",
|
|
5804
5829
|
"updatesHeading": "Actualizaciones disponibles",
|
|
5805
|
-
"updatesDescription": "Hay una versión más reciente de estos presets de modelo integrados. Regenera para adoptarla
|
|
5830
|
+
"updatesDescription": "Hay una versión más reciente de estos presets de modelo integrados. Regenera para adoptarla: se conservan el predeterminado y el orden, pero se borra un orden de rutas personalizado del preset.",
|
|
5806
5831
|
"versionAvailable": "Versión {from} → {to} disponible.",
|
|
5807
5832
|
"reseed": "Regenerar",
|
|
5808
5833
|
"reseedAll": "Actualizar todos ({count})",
|
package/i18n/locales/fr.json
CHANGED
|
@@ -2330,7 +2330,8 @@
|
|
|
2330
2330
|
"deleteTitle": "Supprimer le préréglage",
|
|
2331
2331
|
"basePrefix": "Base :",
|
|
2332
2332
|
"overrideCount": "{count} remplacement | {count} remplacements",
|
|
2333
|
-
"empty": "Aucun préréglage pour l'instant. Créez-en un pour associer des modèles à vos agents."
|
|
2333
|
+
"empty": "Aucun préréglage pour l'instant. Créez-en un pour associer des modèles à vos agents.",
|
|
2334
|
+
"customRouteOrder": "ordre de routes personnalisé"
|
|
2334
2335
|
},
|
|
2335
2336
|
"editor": {
|
|
2336
2337
|
"useBaseModel": "Utiliser le modèle de base",
|
|
@@ -2355,6 +2356,30 @@
|
|
|
2355
2356
|
"confirmDelete": {
|
|
2356
2357
|
"title": "Supprimer ce préréglage de modèle ?",
|
|
2357
2358
|
"body": "\"{name}\" sera supprimé. Les tâches qui l'utilisent reviendront au préréglage par défaut de l'espace de travail."
|
|
2359
|
+
},
|
|
2360
|
+
"routes": {
|
|
2361
|
+
"direct": "L'API propre du fournisseur du modèle",
|
|
2362
|
+
"bedrock": "AWS Bedrock",
|
|
2363
|
+
"openrouter": "Passerelle OpenRouter",
|
|
2364
|
+
"cloudflare": "Cloudflare Workers AI",
|
|
2365
|
+
"subscription": "Abonnement (Claude Code / Codex)"
|
|
2366
|
+
},
|
|
2367
|
+
"routeHints": {
|
|
2368
|
+
"direct": "Nécessite une clé API pour ce fournisseur.",
|
|
2369
|
+
"bedrock": "Exécuté dans votre région AWS, sur les modèles autorisés par votre compte.",
|
|
2370
|
+
"openrouter": "Une clé, plusieurs fournisseurs, revendus avec une marge.",
|
|
2371
|
+
"cloudflare": "Toujours disponible, sans mise en cache des prompts.",
|
|
2372
|
+
"subscription": "Quota forfaitaire d'un forfait connecté."
|
|
2373
|
+
},
|
|
2374
|
+
"routeOrder": {
|
|
2375
|
+
"label": "Ordre des routes",
|
|
2376
|
+
"defaultHint": "Ce préréglage suit la valeur par défaut du déploiement. Remontez une route pour la préférer.",
|
|
2377
|
+
"customHint": "Ce préréglage préfère les routes dans cet ordre. Un modèle accessible uniquement par une route inférieure fonctionne toujours, il est simplement essayé plus tard.",
|
|
2378
|
+
"reset": "Utiliser l'ordre par défaut",
|
|
2379
|
+
"moveUp": "Préférer davantage cette route",
|
|
2380
|
+
"moveDown": "Préférer moins cette route",
|
|
2381
|
+
"subscriptionOverrideHint": "Un abonnement connecté l'emporte toujours pour les modèles qui en proposent un : le moteur les achemine vers le forfait quel que soit cet ordre. Les routes situées sous l'entrée abonnement s'appliquent à tous les autres modèles.",
|
|
2382
|
+
"badgesUseDefaultPresetHint": "La route affichée à côté de chaque modèle ci-dessus est celle du preset par défaut de l'espace de travail, pas celle de ce preset."
|
|
2358
2383
|
}
|
|
2359
2384
|
},
|
|
2360
2385
|
"account": {
|
|
@@ -5802,7 +5827,7 @@
|
|
|
5802
5827
|
"newDescription": "De nouveaux presets de modèle intégrés sont arrivés. Ajoutez-les à la bibliothèque de ce tableau.",
|
|
5803
5828
|
"add": "Ajouter",
|
|
5804
5829
|
"updatesHeading": "Mises à jour disponibles",
|
|
5805
|
-
"updatesDescription": "Une version plus récente de ces presets de modèle intégrés est arrivée. Régénérez pour l'adopter
|
|
5830
|
+
"updatesDescription": "Une version plus récente de ces presets de modèle intégrés est arrivée. Régénérez pour l'adopter : le preset par défaut et l'ordre sont conservés, mais un ordre de routes personnalisé sur le preset est effacé.",
|
|
5806
5831
|
"versionAvailable": "Version {from} → {to} disponible.",
|
|
5807
5832
|
"reseed": "Régénérer",
|
|
5808
5833
|
"reseedAll": "Tout mettre à jour ({count})",
|
package/i18n/locales/he.json
CHANGED
|
@@ -2330,7 +2330,8 @@
|
|
|
2330
2330
|
"deleteTitle": "מחיקת תצורה",
|
|
2331
2331
|
"basePrefix": "בסיס:",
|
|
2332
2332
|
"overrideCount": "עקיפה אחת | {count} עקיפות",
|
|
2333
|
-
"empty": "אין עדיין תצורות. צור אחת כדי למפות מודלים לסוכנים שלך."
|
|
2333
|
+
"empty": "אין עדיין תצורות. צור אחת כדי למפות מודלים לסוכנים שלך.",
|
|
2334
|
+
"customRouteOrder": "סדר מסלולים מותאם"
|
|
2334
2335
|
},
|
|
2335
2336
|
"editor": {
|
|
2336
2337
|
"useBaseModel": "השתמש במודל הבסיס",
|
|
@@ -2355,6 +2356,30 @@
|
|
|
2355
2356
|
"confirmDelete": {
|
|
2356
2357
|
"title": "למחוק את קדם־הגדרת המודל הזו?",
|
|
2357
2358
|
"body": "\"{name}\" יימחק. משימות המשתמשות בו יחזרו לברירת המחדל של סביבת העבודה."
|
|
2359
|
+
},
|
|
2360
|
+
"routes": {
|
|
2361
|
+
"direct": "ה-API של ספק המודל עצמו",
|
|
2362
|
+
"bedrock": "AWS Bedrock",
|
|
2363
|
+
"openrouter": "שער OpenRouter",
|
|
2364
|
+
"cloudflare": "Cloudflare Workers AI",
|
|
2365
|
+
"subscription": "מנוי (Claude Code / Codex)"
|
|
2366
|
+
},
|
|
2367
|
+
"routeHints": {
|
|
2368
|
+
"direct": "נדרש מפתח API לספק הזה.",
|
|
2369
|
+
"bedrock": "פועל באזור ה-AWS שלך, על המודלים שהחשבון שלך מתיר.",
|
|
2370
|
+
"openrouter": "מפתח אחד, ספקים רבים, נמכרים מחדש בתוספת רווח.",
|
|
2371
|
+
"cloudflare": "זמין תמיד, בלי מטמון הנחיות.",
|
|
2372
|
+
"subscription": "מכסה בתעריף אחיד בתוכנית מחוברת."
|
|
2373
|
+
},
|
|
2374
|
+
"routeOrder": {
|
|
2375
|
+
"label": "סדר המסלולים",
|
|
2376
|
+
"defaultHint": "התצורה הזו פועלת לפי ברירת המחדל של הפריסה. העלה מסלול כדי להעדיף אותו.",
|
|
2377
|
+
"customHint": "התצורה הזו מעדיפה את המסלולים בסדר הזה. מודל שנגיש רק במסלול נמוך יותר עדיין ירוץ, פשוט ינוסה מאוחר יותר.",
|
|
2378
|
+
"reset": "השתמש בסדר ברירת המחדל",
|
|
2379
|
+
"moveUp": "העדף את המסלול הזה יותר",
|
|
2380
|
+
"moveDown": "העדף את המסלול הזה פחות",
|
|
2381
|
+
"subscriptionOverrideHint": "מנוי מחובר עדיין גובר עבור מודלים שמציעים אחד: המנוע מנתב אותם לתוכנית ללא קשר לסדר הזה. המסלולים שמתחת לרשומת המנוי חלים על כל שאר המודלים.",
|
|
2382
|
+
"badgesUseDefaultPresetHint": "המסלול שמוצג ליד כל מודל למעלה הוא זה של תצורת ברירת המחדל של סביבת העבודה, לא של התצורה הזו."
|
|
2358
2383
|
}
|
|
2359
2384
|
},
|
|
2360
2385
|
"account": {
|
|
@@ -5813,7 +5838,7 @@
|
|
|
5813
5838
|
"newDescription": "הגיעו קביעות מודל מובנות חדשות. הוסף אותן לספריית הלוח הזה.",
|
|
5814
5839
|
"add": "הוסף",
|
|
5815
5840
|
"updatesHeading": "עדכונים זמינים",
|
|
5816
|
-
"updatesDescription": "גרסה חדשה יותר של קביעות המודל המובנות האלה הגיעה. זרע מחדש כדי לאמץ
|
|
5841
|
+
"updatesDescription": "גרסה חדשה יותר של קביעות המודל המובנות האלה הגיעה. זרע מחדש כדי לאמץ אותה: ברירת המחדל והסדר נשמרים, אך סדר מסלולים מותאם שנשמר בתצורה יימחק.",
|
|
5817
5842
|
"versionAvailable": "גרסה {from} → {to} זמינה.",
|
|
5818
5843
|
"reseed": "זרע מחדש",
|
|
5819
5844
|
"reseedAll": "עדכן הכל ({count})",
|
package/i18n/locales/it.json
CHANGED
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
"deleteTitle": "Elimina preset",
|
|
23
23
|
"basePrefix": "Base:",
|
|
24
24
|
"overrideCount": "{count} override | {count} override",
|
|
25
|
-
"empty": "Ancora nessun preset. Creane uno per associare i modelli ai tuoi agenti."
|
|
25
|
+
"empty": "Ancora nessun preset. Creane uno per associare i modelli ai tuoi agenti.",
|
|
26
|
+
"customRouteOrder": "ordine rotte personalizzato"
|
|
26
27
|
},
|
|
27
28
|
"editor": {
|
|
28
29
|
"useBaseModel": "Usa il modello di base",
|
|
@@ -43,6 +44,30 @@
|
|
|
43
44
|
"nameRequiredTitle": "Nome obbligatorio",
|
|
44
45
|
"nameRequiredBody": "Assegna un nome al preset.",
|
|
45
46
|
"saveFailed": "Impossibile salvare il preset"
|
|
47
|
+
},
|
|
48
|
+
"routes": {
|
|
49
|
+
"direct": "L'API propria del fornitore del modello",
|
|
50
|
+
"bedrock": "AWS Bedrock",
|
|
51
|
+
"openrouter": "Gateway OpenRouter",
|
|
52
|
+
"cloudflare": "Cloudflare Workers AI",
|
|
53
|
+
"subscription": "Abbonamento (Claude Code / Codex)"
|
|
54
|
+
},
|
|
55
|
+
"routeHints": {
|
|
56
|
+
"direct": "Richiede una chiave API per quel fornitore.",
|
|
57
|
+
"bedrock": "Viene eseguito nella tua region AWS, sui modelli consentiti dal tuo account.",
|
|
58
|
+
"openrouter": "Una chiave, molti fornitori, rivenduti con un margine.",
|
|
59
|
+
"cloudflare": "Sempre disponibile, senza cache dei prompt.",
|
|
60
|
+
"subscription": "Quota forfettaria su un piano collegato."
|
|
61
|
+
},
|
|
62
|
+
"routeOrder": {
|
|
63
|
+
"label": "Ordine delle rotte",
|
|
64
|
+
"defaultHint": "Questo preset segue il valore predefinito del deployment. Sposta una rotta in alto per preferirla.",
|
|
65
|
+
"customHint": "Questo preset preferisce le rotte in questo ordine. Un modello raggiungibile solo su una rotta inferiore funziona comunque, viene solo provato dopo.",
|
|
66
|
+
"reset": "Usa l'ordine predefinito",
|
|
67
|
+
"moveUp": "Preferisci di più questa rotta",
|
|
68
|
+
"moveDown": "Preferisci di meno questa rotta",
|
|
69
|
+
"subscriptionOverrideHint": "Un abbonamento collegato prevale comunque sui modelli che ne offrono uno: il motore li instrada al piano indipendentemente da questo ordine. Le rotte sotto la voce abbonamento si applicano a tutti gli altri modelli.",
|
|
70
|
+
"badgesUseDefaultPresetHint": "La rotta mostrata accanto a ogni modello qui sopra è quella del preset predefinito dello spazio di lavoro, non di questo preset."
|
|
46
71
|
}
|
|
47
72
|
},
|
|
48
73
|
"account": {
|
|
@@ -5948,7 +5973,7 @@
|
|
|
5948
5973
|
"newDescription": "Sono stati rilasciati nuovi preset di modello integrati. Aggiungili alla libreria di questa board.",
|
|
5949
5974
|
"add": "Aggiungi",
|
|
5950
5975
|
"updatesHeading": "Aggiornamenti disponibili",
|
|
5951
|
-
"updatesDescription": "È stata rilasciata una versione più recente di questi preset di modello integrati. Ripristina i valori iniziali per adottarla
|
|
5976
|
+
"updatesDescription": "È stata rilasciata una versione più recente di questi preset di modello integrati. Ripristina i valori iniziali per adottarla: il predefinito e l'ordinamento vengono mantenuti, ma un ordine delle rotte personalizzato sul preset viene azzerato.",
|
|
5952
5977
|
"versionAvailable": "Versione {from} → {to} disponibile.",
|
|
5953
5978
|
"reseed": "Ripristina",
|
|
5954
5979
|
"reseedAll": "Aggiorna tutti ({count})",
|
package/i18n/locales/ja.json
CHANGED
|
@@ -2330,7 +2330,8 @@
|
|
|
2330
2330
|
"deleteTitle": "プリセットを削除",
|
|
2331
2331
|
"basePrefix": "ベース:",
|
|
2332
2332
|
"overrideCount": "{count} 件の上書き | {count} 件の上書き",
|
|
2333
|
-
"empty": "プリセットはまだありません。1 つ作成してモデルをエージェントに割り当てましょう。"
|
|
2333
|
+
"empty": "プリセットはまだありません。1 つ作成してモデルをエージェントに割り当てましょう。",
|
|
2334
|
+
"customRouteOrder": "ルート順をカスタム設定"
|
|
2334
2335
|
},
|
|
2335
2336
|
"editor": {
|
|
2336
2337
|
"useBaseModel": "ベースモデルを使用",
|
|
@@ -2355,6 +2356,30 @@
|
|
|
2355
2356
|
"confirmDelete": {
|
|
2356
2357
|
"title": "このモデルプリセットを削除しますか?",
|
|
2357
2358
|
"body": "「{name}」が削除されます。使用中のタスクはワークスペースの既定に戻ります。"
|
|
2359
|
+
},
|
|
2360
|
+
"routes": {
|
|
2361
|
+
"direct": "モデル自身のプロバイダー API",
|
|
2362
|
+
"bedrock": "AWS Bedrock",
|
|
2363
|
+
"openrouter": "OpenRouter ゲートウェイ",
|
|
2364
|
+
"cloudflare": "Cloudflare Workers AI",
|
|
2365
|
+
"subscription": "サブスクリプション(Claude Code / Codex)"
|
|
2366
|
+
},
|
|
2367
|
+
"routeHints": {
|
|
2368
|
+
"direct": "そのプロバイダーの API キーが必要です。",
|
|
2369
|
+
"bedrock": "お使いの AWS リージョンで、アカウントが許可したモデルのみ実行します。",
|
|
2370
|
+
"openrouter": "1 つのキーで多数のベンダーに接続でき、手数料が上乗せされます。",
|
|
2371
|
+
"cloudflare": "常に利用できますが、プロンプトキャッシュはありません。",
|
|
2372
|
+
"subscription": "接続済みプランの定額枠を使用します。"
|
|
2373
|
+
},
|
|
2374
|
+
"routeOrder": {
|
|
2375
|
+
"label": "ルートの優先順",
|
|
2376
|
+
"defaultHint": "このプリセットはデプロイの既定順に従います。優先したいルートを上に移動してください。",
|
|
2377
|
+
"customHint": "このプリセットはこの順でルートを優先します。下位のルートしか使えないモデルも実行されますが、試されるのが後になります。",
|
|
2378
|
+
"reset": "既定の順序を使う",
|
|
2379
|
+
"moveUp": "このルートの優先度を上げる",
|
|
2380
|
+
"moveDown": "このルートの優先度を下げる",
|
|
2381
|
+
"subscriptionOverrideHint": "サブスクリプションを持つモデルでは、接続済みのプランが引き続き優先されます。この順序に関わらず、エンジンはそれらをプランに振り分けます。サブスクリプションより下のルートは、それ以外のすべてのモデルに適用されます。",
|
|
2382
|
+
"badgesUseDefaultPresetHint": "上の各モデルの横に表示されているルートは、ワークスペース既定のプリセットのものであり、このプリセットのものではありません。"
|
|
2358
2383
|
}
|
|
2359
2384
|
},
|
|
2360
2385
|
"account": {
|
|
@@ -5814,7 +5839,7 @@
|
|
|
5814
5839
|
"newDescription": "新しい組み込みモデルプリセットが追加されました。このボードのライブラリに追加してください。",
|
|
5815
5840
|
"add": "追加",
|
|
5816
5841
|
"updatesHeading": "更新あり",
|
|
5817
|
-
"updatesDescription": "
|
|
5842
|
+
"updatesDescription": "これらの組み込みモデルプリセットの新しいバージョンがあります。再シードして取り込みます。既定と並び順は保持されますが、プリセットに設定したカスタムのルート順はクリアされます。",
|
|
5818
5843
|
"versionAvailable": "バージョン {from} → {to} が利用可能です。",
|
|
5819
5844
|
"reseed": "再シード",
|
|
5820
5845
|
"reseedAll": "すべて更新 ({count})",
|
package/i18n/locales/pl.json
CHANGED
|
@@ -2330,7 +2330,8 @@
|
|
|
2330
2330
|
"deleteTitle": "Usuń ustawienie",
|
|
2331
2331
|
"basePrefix": "Bazowy:",
|
|
2332
2332
|
"overrideCount": "{count} nadpisanie | {count} nadpisania | {count} nadpisań",
|
|
2333
|
-
"empty": "Brak ustawień. Utwórz jedno, aby przypisać modele do swoich agentów."
|
|
2333
|
+
"empty": "Brak ustawień. Utwórz jedno, aby przypisać modele do swoich agentów.",
|
|
2334
|
+
"customRouteOrder": "własna kolejność tras"
|
|
2334
2335
|
},
|
|
2335
2336
|
"editor": {
|
|
2336
2337
|
"useBaseModel": "Użyj modelu bazowego",
|
|
@@ -2355,6 +2356,30 @@
|
|
|
2355
2356
|
"confirmDelete": {
|
|
2356
2357
|
"title": "Usunąć ten preset modelu?",
|
|
2357
2358
|
"body": "\"{name}\" zostanie usunięty. Zadania go używające wrócą do domyślnego ustawienia obszaru roboczego."
|
|
2359
|
+
},
|
|
2360
|
+
"routes": {
|
|
2361
|
+
"direct": "Własne API dostawcy modelu",
|
|
2362
|
+
"bedrock": "AWS Bedrock",
|
|
2363
|
+
"openrouter": "Brama OpenRouter",
|
|
2364
|
+
"cloudflare": "Cloudflare Workers AI",
|
|
2365
|
+
"subscription": "Subskrypcja (Claude Code / Codex)"
|
|
2366
|
+
},
|
|
2367
|
+
"routeHints": {
|
|
2368
|
+
"direct": "Wymaga klucza API tego dostawcy.",
|
|
2369
|
+
"bedrock": "Działa w Twoim regionie AWS, na modelach dozwolonych dla Twojego konta.",
|
|
2370
|
+
"openrouter": "Jeden klucz, wielu dostawców, odsprzedawanych z marżą.",
|
|
2371
|
+
"cloudflare": "Zawsze dostępne, bez buforowania promptów.",
|
|
2372
|
+
"subscription": "Zryczałtowany limit w połączonym planie."
|
|
2373
|
+
},
|
|
2374
|
+
"routeOrder": {
|
|
2375
|
+
"label": "Kolejność tras",
|
|
2376
|
+
"defaultHint": "Ten preset korzysta z domyślnej kolejności wdrożenia. Przesuń trasę w górę, aby ją preferować.",
|
|
2377
|
+
"customHint": "Ten preset preferuje trasy w tej kolejności. Model dostępny tylko na niższej trasie nadal działa, jest tylko próbowany później.",
|
|
2378
|
+
"reset": "Użyj domyślnej kolejności",
|
|
2379
|
+
"moveUp": "Preferuj tę trasę bardziej",
|
|
2380
|
+
"moveDown": "Preferuj tę trasę mniej",
|
|
2381
|
+
"subscriptionOverrideHint": "Podłączona subskrypcja nadal wygrywa w przypadku modeli, które ją oferują: silnik kieruje je do planu niezależnie od tej kolejności. Trasy poniżej pozycji subskrypcji dotyczą wszystkich pozostałych modeli.",
|
|
2382
|
+
"badgesUseDefaultPresetHint": "Trasa pokazana obok każdego modelu powyżej to trasa domyślnego presetu przestrzeni roboczej, a nie tego presetu."
|
|
2358
2383
|
}
|
|
2359
2384
|
},
|
|
2360
2385
|
"account": {
|
|
@@ -5802,7 +5827,7 @@
|
|
|
5802
5827
|
"newDescription": "Pojawiły się nowe wbudowane presety modelu. Dodaj je do biblioteki tej tablicy.",
|
|
5803
5828
|
"add": "Dodaj",
|
|
5804
5829
|
"updatesHeading": "Dostępne aktualizacje",
|
|
5805
|
-
"updatesDescription": "Dostępna jest nowsza wersja tych wbudowanych presetów modelu. Zregeneruj, aby ją
|
|
5830
|
+
"updatesDescription": "Dostępna jest nowsza wersja tych wbudowanych presetów modelu. Zregeneruj, aby ją przyjąć: domyślny i kolejność są zachowane, ale własna kolejność tras na presecie zostanie wyczyszczona.",
|
|
5806
5831
|
"versionAvailable": "Dostępna wersja {from} → {to}.",
|
|
5807
5832
|
"reseed": "Zregeneruj",
|
|
5808
5833
|
"reseedAll": "Zaktualizuj wszystkie ({count})",
|
package/i18n/locales/tr.json
CHANGED
|
@@ -2330,7 +2330,8 @@
|
|
|
2330
2330
|
"deleteTitle": "Hazır ayarı sil",
|
|
2331
2331
|
"basePrefix": "Temel:",
|
|
2332
2332
|
"overrideCount": "{count} geçersiz kılma | {count} geçersiz kılma",
|
|
2333
|
-
"empty": "Henüz hazır ayar yok. Modelleri ajanlarınıza eşlemek için bir tane oluşturun."
|
|
2333
|
+
"empty": "Henüz hazır ayar yok. Modelleri ajanlarınıza eşlemek için bir tane oluşturun.",
|
|
2334
|
+
"customRouteOrder": "özel rota sırası"
|
|
2334
2335
|
},
|
|
2335
2336
|
"editor": {
|
|
2336
2337
|
"useBaseModel": "Temel modeli kullan",
|
|
@@ -2355,6 +2356,30 @@
|
|
|
2355
2356
|
"confirmDelete": {
|
|
2356
2357
|
"title": "Bu model ön ayarı silinsin mi?",
|
|
2357
2358
|
"body": "\"{name}\" kaldırılacak. Onu kullanan görevler çalışma alanı varsayılanına döner."
|
|
2359
|
+
},
|
|
2360
|
+
"routes": {
|
|
2361
|
+
"direct": "Modelin kendi sağlayıcı API'si",
|
|
2362
|
+
"bedrock": "AWS Bedrock",
|
|
2363
|
+
"openrouter": "OpenRouter geçidi",
|
|
2364
|
+
"cloudflare": "Cloudflare Workers AI",
|
|
2365
|
+
"subscription": "Abonelik (Claude Code / Codex)"
|
|
2366
|
+
},
|
|
2367
|
+
"routeHints": {
|
|
2368
|
+
"direct": "Bu sağlayıcı için bir API anahtarı gerekir.",
|
|
2369
|
+
"bedrock": "AWS bölgenizde, hesabınızın izin verdiği modellerle çalışır.",
|
|
2370
|
+
"openrouter": "Tek anahtar, çok sağlayıcı, kâr payıyla yeniden satılır.",
|
|
2371
|
+
"cloudflare": "Her zaman kullanılabilir, istem önbelleği yok.",
|
|
2372
|
+
"subscription": "Bağlı bir planda sabit ücretli kota."
|
|
2373
|
+
},
|
|
2374
|
+
"routeOrder": {
|
|
2375
|
+
"label": "Rota sırası",
|
|
2376
|
+
"defaultHint": "Bu hazır ayar dağıtımın varsayılanını izler. Bir rotayı tercih etmek için yukarı taşıyın.",
|
|
2377
|
+
"customHint": "Bu hazır ayar rotaları bu sırayla tercih eder. Yalnızca daha alt bir rotadan erişilebilen bir model yine çalışır, sadece daha sonra denenir.",
|
|
2378
|
+
"reset": "Varsayılan sırayı kullan",
|
|
2379
|
+
"moveUp": "Bu rotayı daha çok tercih et",
|
|
2380
|
+
"moveDown": "Bu rotayı daha az tercih et",
|
|
2381
|
+
"subscriptionOverrideHint": "Bağlı bir abonelik, abonelik sunan modellerde hâlâ önceliklidir: motor bu sıralamadan bağımsız olarak onları plana yönlendirir. Abonelik girdisinin altındaki rotalar diğer tüm modeller için geçerlidir.",
|
|
2382
|
+
"badgesUseDefaultPresetHint": "Yukarıda her modelin yanında gösterilen rota, bu ön ayarın değil, çalışma alanının varsayılan ön ayarının rotasıdır."
|
|
2358
2383
|
}
|
|
2359
2384
|
},
|
|
2360
2385
|
"account": {
|
|
@@ -5814,7 +5839,7 @@
|
|
|
5814
5839
|
"newDescription": "Yeni yerleşik model ön ayarları geldi. Bu panonun kütüphanesine ekleyin.",
|
|
5815
5840
|
"add": "Ekle",
|
|
5816
5841
|
"updatesHeading": "Güncellemeler mevcut",
|
|
5817
|
-
"updatesDescription": "Bu yerleşik model ön ayarlarının daha yeni bir sürümü geldi. Benimsemek için yeniden tohumlayın
|
|
5842
|
+
"updatesDescription": "Bu yerleşik model ön ayarlarının daha yeni bir sürümü geldi. Benimsemek için yeniden tohumlayın: varsayılan ve sıralama korunur, ancak ön ayardaki özel rota sırası temizlenir.",
|
|
5818
5843
|
"versionAvailable": "Sürüm {from} → {to} mevcut.",
|
|
5819
5844
|
"reseed": "Yeniden tohumla",
|
|
5820
5845
|
"reseedAll": "Tümünü güncelle ({count})",
|
package/i18n/locales/uk.json
CHANGED
|
@@ -2330,7 +2330,8 @@
|
|
|
2330
2330
|
"deleteTitle": "Видалити набір",
|
|
2331
2331
|
"basePrefix": "Базова:",
|
|
2332
2332
|
"overrideCount": "{count} перевизначення | {count} перевизначення | {count} перевизначень",
|
|
2333
|
-
"empty": "Наборів ще немає. Створіть один, щоб призначити моделі вашим агентам."
|
|
2333
|
+
"empty": "Наборів ще немає. Створіть один, щоб призначити моделі вашим агентам.",
|
|
2334
|
+
"customRouteOrder": "власний порядок маршрутів"
|
|
2334
2335
|
},
|
|
2335
2336
|
"editor": {
|
|
2336
2337
|
"useBaseModel": "Використати базову модель",
|
|
@@ -2355,6 +2356,30 @@
|
|
|
2355
2356
|
"confirmDelete": {
|
|
2356
2357
|
"title": "Видалити цей пресет моделі?",
|
|
2357
2358
|
"body": "\"{name}\" буде видалено. Завдання, що його використовують, повернуться до типового пресету робочого простору."
|
|
2359
|
+
},
|
|
2360
|
+
"routes": {
|
|
2361
|
+
"direct": "Власний API постачальника моделі",
|
|
2362
|
+
"bedrock": "AWS Bedrock",
|
|
2363
|
+
"openrouter": "Шлюз OpenRouter",
|
|
2364
|
+
"cloudflare": "Cloudflare Workers AI",
|
|
2365
|
+
"subscription": "Підписка (Claude Code / Codex)"
|
|
2366
|
+
},
|
|
2367
|
+
"routeHints": {
|
|
2368
|
+
"direct": "Потрібен ключ API для цього постачальника.",
|
|
2369
|
+
"bedrock": "Працює у вашому регіоні AWS, на моделях, дозволених для вашого облікового запису.",
|
|
2370
|
+
"openrouter": "Один ключ, багато постачальників, перепродаж із націнкою.",
|
|
2371
|
+
"cloudflare": "Завжди доступно, без кешування промптів.",
|
|
2372
|
+
"subscription": "Фіксована квота підключеного плану."
|
|
2373
|
+
},
|
|
2374
|
+
"routeOrder": {
|
|
2375
|
+
"label": "Порядок маршрутів",
|
|
2376
|
+
"defaultHint": "Цей пресет використовує типовий порядок розгортання. Підніміть маршрут вище, щоб надати йому перевагу.",
|
|
2377
|
+
"customHint": "Цей пресет надає перевагу маршрутам у такому порядку. Модель, доступна лише на нижчому маршруті, усе одно працює, її просто спробують пізніше.",
|
|
2378
|
+
"reset": "Використати типовий порядок",
|
|
2379
|
+
"moveUp": "Більше надавати перевагу цьому маршруту",
|
|
2380
|
+
"moveDown": "Менше надавати перевагу цьому маршруту",
|
|
2381
|
+
"subscriptionOverrideHint": "Підключена підписка все одно перемагає для моделей, які її пропонують: рушій спрямовує їх до тарифу незалежно від цього порядку. Маршрути нижче запису підписки діють для всіх інших моделей.",
|
|
2382
|
+
"badgesUseDefaultPresetHint": "Маршрут, показаний біля кожної моделі вище, належить стандартному пресету робочого простору, а не цьому пресету."
|
|
2358
2383
|
}
|
|
2359
2384
|
},
|
|
2360
2385
|
"account": {
|
|
@@ -5802,7 +5827,7 @@
|
|
|
5802
5827
|
"newDescription": "З'явилися нові вбудовані пресети моделі. Додайте їх до бібліотеки цієї дошки.",
|
|
5803
5828
|
"add": "Додати",
|
|
5804
5829
|
"updatesHeading": "Доступні оновлення",
|
|
5805
|
-
"updatesDescription": "Доступна новіша версія цих вбудованих пресетів моделі. Перегенеруйте, щоб застосувати
|
|
5830
|
+
"updatesDescription": "Доступна новіша версія цих вбудованих пресетів моделі. Перегенеруйте, щоб застосувати її: стандартний пресет і порядок збережено, але власний порядок маршрутів у пресеті буде очищено.",
|
|
5806
5831
|
"versionAvailable": "Доступна версія {from} → {to}.",
|
|
5807
5832
|
"reseed": "Перегенерувати",
|
|
5808
5833
|
"reseedAll": "Оновити всі ({count})",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cat-factory/app",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.213.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",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"valibot": "^1.4.2",
|
|
41
41
|
"vue": "3.5.40",
|
|
42
42
|
"wretch": "^3.0.9",
|
|
43
|
-
"@cat-factory/contracts": "0.
|
|
43
|
+
"@cat-factory/contracts": "0.222.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@toad-contracts/testing": "0.3.2",
|