@cat-factory/app 0.30.1 → 0.30.2
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.
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// The latter three are body-only section components rendered in tabs here (no longer
|
|
9
9
|
// standalone modals).
|
|
10
10
|
import { reactive, ref, watch } from 'vue'
|
|
11
|
-
import type { CreateTaskType, TaskLimitMode
|
|
11
|
+
import type { CreateTaskType, TaskLimitMode } from '~/types/domain'
|
|
12
12
|
import MergeThresholdsPanel from '~/components/settings/MergeThresholdsPanel.vue'
|
|
13
13
|
import IssueTrackerPanel from '~/components/settings/IssueTrackerPanel.vue'
|
|
14
14
|
import ServiceFragmentDefaultsPanel from '~/components/settings/ServiceFragmentDefaultsPanel.vue'
|
|
@@ -71,7 +71,6 @@ const draft = reactive({
|
|
|
71
71
|
// Budget: empty string ⇒ "use the built-in default" (null on the wire).
|
|
72
72
|
spendCurrency: '',
|
|
73
73
|
spendMonthlyLimit: '',
|
|
74
|
-
spendModelPrices: '',
|
|
75
74
|
})
|
|
76
75
|
|
|
77
76
|
function hydrate() {
|
|
@@ -84,7 +83,6 @@ function hydrate() {
|
|
|
84
83
|
draft.storeAgentContext = s.storeAgentContext
|
|
85
84
|
draft.spendCurrency = s.spendCurrency ?? ''
|
|
86
85
|
draft.spendMonthlyLimit = s.spendMonthlyLimit == null ? '' : String(s.spendMonthlyLimit)
|
|
87
|
-
draft.spendModelPrices = s.spendModelPrices ? JSON.stringify(s.spendModelPrices, null, 2) : ''
|
|
88
86
|
}
|
|
89
87
|
|
|
90
88
|
watch(() => store.settings, hydrate, { immediate: true, deep: true })
|
|
@@ -126,28 +124,15 @@ async function save() {
|
|
|
126
124
|
const savingBudget = ref(false)
|
|
127
125
|
|
|
128
126
|
async function saveBudget() {
|
|
129
|
-
// Parse the optional per-model price overrides JSON (blank ⇒ no overrides).
|
|
130
|
-
let prices: WorkspaceSettings['spendModelPrices'] = null
|
|
131
|
-
const raw = draft.spendModelPrices.trim()
|
|
132
|
-
if (raw) {
|
|
133
|
-
try {
|
|
134
|
-
prices = JSON.parse(raw)
|
|
135
|
-
} catch {
|
|
136
|
-
toast.add({
|
|
137
|
-
title: 'Per-model prices must be valid JSON',
|
|
138
|
-
icon: 'i-lucide-triangle-alert',
|
|
139
|
-
color: 'error',
|
|
140
|
-
})
|
|
141
|
-
return
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
127
|
savingBudget.value = true
|
|
128
|
+
// The number input emits a raw number once edited but starts as a string from hydrate, so
|
|
129
|
+
// coerce through String() before trimming. Blank ⇒ "use the built-in default" (null on the wire).
|
|
130
|
+
const raw = String(draft.spendMonthlyLimit ?? '').trim()
|
|
131
|
+
const monthlyLimit = raw === '' ? null : Number(raw)
|
|
145
132
|
try {
|
|
146
133
|
await store.update({
|
|
147
134
|
spendCurrency: draft.spendCurrency.trim() ? draft.spendCurrency.trim().toUpperCase() : null,
|
|
148
|
-
spendMonthlyLimit:
|
|
149
|
-
draft.spendMonthlyLimit.trim() === '' ? null : Number(draft.spendMonthlyLimit),
|
|
150
|
-
spendModelPrices: prices,
|
|
135
|
+
spendMonthlyLimit: monthlyLimit,
|
|
151
136
|
})
|
|
152
137
|
toast.add({ title: 'Budget saved', icon: 'i-lucide-check', color: 'success' })
|
|
153
138
|
} catch (e) {
|
|
@@ -304,22 +289,6 @@ async function saveBudget() {
|
|
|
304
289
|
</div>
|
|
305
290
|
</section>
|
|
306
291
|
|
|
307
|
-
<section class="space-y-2">
|
|
308
|
-
<h3 class="text-sm font-semibold text-slate-200">Per-model price overrides</h3>
|
|
309
|
-
<p class="text-[11px] text-slate-400">
|
|
310
|
-
Optional. JSON object of <code>"provider:model"</code> (or a bare
|
|
311
|
-
<code>"provider"</code>) → <code>{ inputPerMillion, outputPerMillion }</code>,
|
|
312
|
-
overlaid on the built-in price table. Leave blank to use the defaults.
|
|
313
|
-
</p>
|
|
314
|
-
<UTextarea
|
|
315
|
-
v-model="draft.spendModelPrices"
|
|
316
|
-
:rows="6"
|
|
317
|
-
size="sm"
|
|
318
|
-
class="w-full font-mono text-[11px]"
|
|
319
|
-
placeholder='{"openai:gpt-4o":{"inputPerMillion":2.3,"outputPerMillion":9.2}}'
|
|
320
|
-
/>
|
|
321
|
-
</section>
|
|
322
|
-
|
|
323
292
|
<div class="flex justify-end">
|
|
324
293
|
<UButton
|
|
325
294
|
color="primary"
|
package/app/types/domain.ts
CHANGED
|
@@ -499,8 +499,6 @@ export interface WorkspaceSettings {
|
|
|
499
499
|
spendCurrency: string | null
|
|
500
500
|
/** Monthly spend budget in `spendCurrency`. Null ⇒ the built-in default. */
|
|
501
501
|
spendMonthlyLimit: number | null
|
|
502
|
-
/** Per-model price overrides (`provider:model` → per-1M rates). Null ⇒ none. */
|
|
503
|
-
spendModelPrices: Record<string, { inputPerMillion: number; outputPerMillion: number }> | null
|
|
504
502
|
}
|
|
505
503
|
|
|
506
504
|
/** Patch a workspace's settings (only the supplied fields change). */
|
|
@@ -512,7 +510,6 @@ export interface UpdateWorkspaceSettingsInput {
|
|
|
512
510
|
storeAgentContext?: boolean
|
|
513
511
|
spendCurrency?: string | null
|
|
514
512
|
spendMonthlyLimit?: number | null
|
|
515
|
-
spendModelPrices?: Record<string, { inputPerMillion: number; outputPerMillion: number }> | null
|
|
516
513
|
}
|
|
517
514
|
|
|
518
515
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cat-factory/app",
|
|
3
|
-
"version": "0.30.
|
|
3
|
+
"version": "0.30.2",
|
|
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",
|