From 501a427da153ecc1fe48199a82d4f00ceb010269 Mon Sep 17 00:00:00 2001
From: Luka Forder
Date: Wed, 17 Jun 2026 15:28:25 +0100
Subject: [PATCH 1/7] fix: scary fix to prevent enter ever submitting the form
for session creation
---
src/routes/(app)/workbench/+page.svelte | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/src/routes/(app)/workbench/+page.svelte b/src/routes/(app)/workbench/+page.svelte
index ee3dbf8..a52dadc 100644
--- a/src/routes/(app)/workbench/+page.svelte
+++ b/src/routes/(app)/workbench/+page.svelte
@@ -644,12 +644,25 @@
+
-
-
{/if}
From 916b839c05e56e858169f34751b26b2eb4d325b8 Mon Sep 17 00:00:00 2001
From: Luka Forder
Date: Wed, 17 Jun 2026 18:07:25 +0100
Subject: [PATCH 3/7] fix: changed min and fixed json import for agent budgets
---
src/lib/sessionSchema/index.ts | 1 +
src/lib/sessionSchema/types.ts | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/lib/sessionSchema/index.ts b/src/lib/sessionSchema/index.ts
index 8df01a4..ceb5657 100644
--- a/src/lib/sessionSchema/index.ts
+++ b/src/lib/sessionSchema/index.ts
@@ -183,6 +183,7 @@ export const importFromPayload = (json: string): z.output => {
blocking: agent.blocking ?? true,
systemPrompt: agent.systemPrompt,
plugins: agent.plugins ?? [],
+ budgetSettings: agent.budgetSettings ?? {},
options: agent.options ? (structuredClone(agent.options) as any) : {},
customToolAccess: new Set(
(agent.customToolAccess ?? []).map((t) => toolMap[t]).filter(Boolean) as string[] // typescript is stupid this is safe because .filter(Boolean)
diff --git a/src/lib/sessionSchema/types.ts b/src/lib/sessionSchema/types.ts
index 077eb90..7c88bac 100644
--- a/src/lib/sessionSchema/types.ts
+++ b/src/lib/sessionSchema/types.ts
@@ -243,7 +243,7 @@ const formSchema = z.object({
])
.default({
type: 'kill_session',
- minimum: 100000
+ minimum: 1000000
})
}),
tools: z.record(z.string().nonempty(), CustomToolSchema),
From 7be86af2ec4193d9d021d587fd964da465b7b7d3 Mon Sep 17 00:00:00 2001
From: Luka Forder
Date: Wed, 17 Jun 2026 18:07:35 +0100
Subject: [PATCH 4/7] feat: selects all on focus
---
src/routes/(app)/workbench/options/CurrencyInput.svelte | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/routes/(app)/workbench/options/CurrencyInput.svelte b/src/routes/(app)/workbench/options/CurrencyInput.svelte
index 8d96475..f8caba4 100644
--- a/src/routes/(app)/workbench/options/CurrencyInput.svelte
+++ b/src/routes/(app)/workbench/options/CurrencyInput.svelte
@@ -2,6 +2,7 @@
import * as ButtonGroup from '@coral-os/component-library/ui/button-group/index.js';
import * as InputGroup from '@coral-os/component-library/ui/input-group/index.js';
import * as Label from '@coral-os/component-library/ui/label/index.js';
+ import { tick } from 'svelte';
const MICRODOLLARS_PER_DOLLAR = 100_000_000;
@@ -42,9 +43,14 @@
const dollars = $derived(toDollars(value ?? 0));
- function onFocus(e: FocusEvent & { currentTarget: HTMLInputElement }) {
+ async function onFocus(e: FocusEvent & { currentTarget: HTMLInputElement }) {
isEditing = true;
editingValue = isNaN(dollars) ? '' : dollars.toFixed(10).replace(/\.?0+$/, '');
+
+ await tick();
+ e.currentTarget.select();
+
+ // TODO: without the await tick it doesnt select! :)
}
function onBlur(e: FocusEvent & { currentTarget: HTMLInputElement }) {
From 249775973cfa25660134e789ec9de199f557c7a1 Mon Sep 17 00:00:00 2001
From: Luka Forder
Date: Wed, 17 Jun 2026 18:07:48 +0100
Subject: [PATCH 5/7] feat: fixed and updated the agent budget settings
---
src/routes/(app)/workbench/+page.svelte | 1 -
.../(app)/workbench/panes/AgentPane.svelte | 196 ++++++++----------
2 files changed, 92 insertions(+), 105 deletions(-)
diff --git a/src/routes/(app)/workbench/+page.svelte b/src/routes/(app)/workbench/+page.svelte
index a52dadc..bca1844 100644
--- a/src/routes/(app)/workbench/+page.svelte
+++ b/src/routes/(app)/workbench/+page.svelte
@@ -514,7 +514,6 @@
onMount(async () => {
if (sessionDraft.current && sessionDraft.current.agentGraphRequest.agents.length >= 0) {
- // ensure required 'from' property is present for importSession
sessCtx.importSession({
from: JSON.stringify(sessionDraft.current),
success: 'Loaded previous workbench draft'
diff --git a/src/routes/(app)/workbench/panes/AgentPane.svelte b/src/routes/(app)/workbench/panes/AgentPane.svelte
index 442e42e..678e74b 100644
--- a/src/routes/(app)/workbench/panes/AgentPane.svelte
+++ b/src/routes/(app)/workbench/panes/AgentPane.svelte
@@ -37,6 +37,7 @@
import { getSessionDataFromTemplateName } from '../templates/TemplateLib';
import { getSessionContext } from '$lib/sessionCreatorContext';
import { cn } from '$lib/utils';
+ import CurrencyInput from '../options/CurrencyInput.svelte';
let appCtx = appContext.get();
@@ -95,11 +96,9 @@
return $formData.agents[agentIdx]?.budgetSettings?.exhaustionBehavior;
}
- function isKillBehavior(
- behavior: ReturnType
- ): behavior is { type: 'kill'; force: boolean; minimum: number } {
- return behavior?.type === 'kill';
- }
+ const agentBehavior = $derived(
+ $formData.agents[ctx.selectedAgent!]?.budgetSettings?.exhaustionBehavior
+ );
{#if ctx.selectedAgent !== null && curAgent && curCatalog}
@@ -254,14 +253,15 @@
-
-
+
Agent budget
+ {@const agentIdx = ctx.selectedAgent!}
@@ -273,42 +273,35 @@
required: true,
type: 'integer'
}}
- class="max-w-1/4 min-w-1/4 "
+ class="max-w-1/4 min-w-1/4"
>
Agent budget
-
-
- $
-
-
- {
- const dollars = e.currentTarget.valueAsNumber;
- $formData.agents[ctx.selectedAgent!]!.budgetSettings!.budget =
- Number.isNaN(dollars) ? 0 : Math.round(dollars * 100000000);
- }}
- type="number"
- step="0.01"
- placeholder="0.00"
- />
-
-
+
+ {
+ const agent = $formData.agents[agentIdx];
+ if (!agent) return;
+
+ agent.budgetSettings ??= {};
+
+ agent.budgetSettings.budget = micro;
+
+ $formData.agents = $formData.agents;
+ }}
+ />
{/snippet}
{#snippet children()}
- {@const agentIdx = ctx.selectedAgent!}
{@const exhaustionBehavior = getAgentExhaustionBehavior(agentIdx)}
- {#if isKillBehavior(getAgentExhaustionBehavior(ctx.selectedAgent!))}
- {@const agentIdx = ctx.selectedAgent!}
- {@const killBehavior = getAgentExhaustionBehavior(agentIdx) as {
- type: 'kill';
- force: boolean;
- minimum: number;
- }}
+ {#if agentBehavior?.type !== 'consume_session' && agentBehavior}
+ {@const killBehavior = getAgentExhaustionBehavior(agentIdx)}
+ {@const force = killBehavior?.type === 'kill' ? killBehavior.force : false}
Force kill agent
+ True
+
+ False
+
{/snippet}
-
-
- {#snippet children({ props })}
-
- Minimum
-
-
-
- $
-
-
- {
- const dollars = e.currentTarget.valueAsNumber;
- const behavior =
- $formData.agents[agentIdx]?.budgetSettings?.exhaustionBehavior;
- if (behavior?.type === 'kill') {
- behavior.minimum = Number.isNaN(dollars)
- ? 0
- : Math.round(dollars * 100000000);
- $formData.agents = $formData.agents;
- }
- }}
- type="number"
- step="0.01"
- placeholder="0.00"
- />
-
-
- {/snippet}
-
-
+ {#if killBehavior?.type === 'kill'}
+
+
+ {#snippet children({ props })}
+
+ Minimum
+
+ {
+ killBehavior.minimum = micro;
+ $formData.agents = $formData.agents;
+ }}
+ />
+ {/snippet}
+
+
+ {/if}
{/if}
From e6bacc3b64bd47dd2fc9670e2dccfdd2b4544d12 Mon Sep 17 00:00:00 2001
From: Luka Forder
Date: Wed, 17 Jun 2026 18:15:27 +0100
Subject: [PATCH 6/7] fix: switched to toggle groups for true/false from the
previous button groups
---
.../(app)/workbench/panes/AgentPane.svelte | 64 ++++++++-----------
.../(app)/workbench/panes/BudgetPane.svelte | 44 +++++--------
2 files changed, 42 insertions(+), 66 deletions(-)
diff --git a/src/routes/(app)/workbench/panes/AgentPane.svelte b/src/routes/(app)/workbench/panes/AgentPane.svelte
index 678e74b..8c43eab 100644
--- a/src/routes/(app)/workbench/panes/AgentPane.svelte
+++ b/src/routes/(app)/workbench/panes/AgentPane.svelte
@@ -405,49 +405,35 @@
>
Force kill agent
-
-
-
-
+ agent.budgetSettings.exhaustionBehavior = {
+ type: 'kill',
+ force: v === 'true',
+ minimum: existing?.type === 'kill' ? existing.minimum : 0
+ };
+
+ $formData.agents = $formData.agents;
+ }}
+ >
+ True
+
+ False
+
{/snippet}
diff --git a/src/routes/(app)/workbench/panes/BudgetPane.svelte b/src/routes/(app)/workbench/panes/BudgetPane.svelte
index 6234390..c518dc4 100644
--- a/src/routes/(app)/workbench/panes/BudgetPane.svelte
+++ b/src/routes/(app)/workbench/panes/BudgetPane.svelte
@@ -224,33 +224,23 @@
>
Force kill agent
-
-
-
-
+ {
+ if (v && $formData.sessionBudgetSettings.exhaustionBehavior.type === 'kill_agent') {
+ $formData.sessionBudgetSettings.exhaustionBehavior.force = v === 'true';
+ }
+ }}
+ >
+ True
+
+ False
+
{/snippet}
From 9e59af93b4b558b097746c8b9ec6a95a780e6895 Mon Sep 17 00:00:00 2001
From: Luka Forder
Date: Thu, 18 Jun 2026 15:14:10 +0100
Subject: [PATCH 7/7] fix: alan changes
Co-authored-by: Alan Panayotov
---
src/routes/(app)/workbench/options/CurrencyInput.svelte | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/routes/(app)/workbench/options/CurrencyInput.svelte b/src/routes/(app)/workbench/options/CurrencyInput.svelte
index f8caba4..7b41c1e 100644
--- a/src/routes/(app)/workbench/options/CurrencyInput.svelte
+++ b/src/routes/(app)/workbench/options/CurrencyInput.svelte
@@ -10,11 +10,10 @@
const toMicro = (dollars: number) => Math.round(dollars * MICRODOLLARS_PER_DOLLAR);
const formatUSD = (value: number) => {
- if (value === 0) return '$0.00';
- if (value < 0.01) return '$' + value.toFixed(10).replace(/\.?0+$/, '');
- return new Intl.NumberFormat('en-US', {
+ return new Intl.NumberFormat(undefined, {
style: 'currency',
currency: 'USD',
+ currencyDisplay: 'narrowSymbol',
minimumFractionDigits: 2,
maximumFractionDigits: 8
}).format(value);