@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, WorkspaceSettings } from '~/types/domain'
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"
@@ -12,7 +12,6 @@ const DEFAULTS: WorkspaceSettings = {
12
12
  storeAgentContext: true,
13
13
  spendCurrency: null,
14
14
  spendMonthlyLimit: null,
15
- spendModelPrices: null,
16
15
  }
17
16
 
18
17
  /**
@@ -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.1",
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",