summaryrefslogtreecommitdiffhomepage
path: root/packages/frontend/src/lib/components/ConfigPanel.svelte
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-04 21:21:20 +0900
committerAdam Malczewski <[email protected]>2026-06-04 21:21:20 +0900
commit394f1ed37ce860da6fdc385769bf29f9737105cd (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /packages/frontend/src/lib/components/ConfigPanel.svelte
parent81a9cdbadf8c9d940d4fe9a2a0de607dee1f5f1a (diff)
downloaddispatch-394f1ed37ce860da6fdc385769bf29f9737105cd.tar.gz
dispatch-394f1ed37ce860da6fdc385769bf29f9737105cd.zip
chore: genesis — remove all files to rebuild from scratch (arch rewrite)
Diffstat (limited to 'packages/frontend/src/lib/components/ConfigPanel.svelte')
-rw-r--r--packages/frontend/src/lib/components/ConfigPanel.svelte251
1 files changed, 0 insertions, 251 deletions
diff --git a/packages/frontend/src/lib/components/ConfigPanel.svelte b/packages/frontend/src/lib/components/ConfigPanel.svelte
deleted file mode 100644
index f517d28..0000000
--- a/packages/frontend/src/lib/components/ConfigPanel.svelte
+++ /dev/null
@@ -1,251 +0,0 @@
-<script lang="ts">
-interface AgentTemplate {
- name: string;
- description?: string;
- model_tag?: string;
- tools?: string[];
-}
-
-interface ModelEntry {
- id: string;
- provider?: string;
- tags?: string[];
-}
-
-interface KeyEntry {
- id: string;
- provider?: string;
- status?: string;
- lastError?: string;
- exhaustedAt?: string;
-}
-
-interface ConfigData {
- agents?: Record<string, AgentTemplate>;
- models?: Record<string, { provider?: string; tags?: string[] }>;
- keys?: Record<string, { env?: string }>;
- fallback?: string[];
- permissions?: Record<string, unknown>;
-}
-
-interface ModelsData {
- models?: ModelEntry[];
- tags?: Record<string, string[]>;
- keys?: KeyEntry[];
-}
-
-const { apiBase }: { apiBase: string } = $props();
-
-let configData = $state<ConfigData | null>(null);
-let modelsData = $state<ModelsData | null>(null);
-let error = $state<string | null>(null);
-let loading = $state(false);
-
-async function fetchData() {
- loading = true;
- error = null;
- try {
- const [configRes, modelsRes] = await Promise.all([
- fetch(`${apiBase}/config`),
- fetch(`${apiBase}/models`),
- ]);
- if (!configRes.ok) throw new Error(`/config returned ${configRes.status}`);
- if (!modelsRes.ok) throw new Error(`/models returned ${modelsRes.status}`);
- const configJson = await configRes.json();
- const modelsJson = await modelsRes.json();
- configData = configJson.config ?? configJson;
- modelsData = modelsJson;
- } catch (e) {
- error = e instanceof Error ? e.message : String(e);
- } finally {
- loading = false;
- }
-}
-
-$effect(() => {
- fetchData();
-});
-
-const modelCount = $derived(modelsData?.models?.length ?? 0);
-const keyCount = $derived(modelsData?.keys?.length ?? 0);
-
-function formatDate(iso: string | undefined): string {
- if (!iso) return "";
- try {
- return new Date(iso).toLocaleString();
- } catch {
- return iso;
- }
-}
-
-function permissionEntries(
- permissions: Record<string, unknown>,
-): Array<{ name: string; value: unknown }> {
- return Object.entries(permissions).map(([name, value]) => ({ name, value }));
-}
-
-function isSimpleRule(value: unknown): value is { action: string } {
- return (
- typeof value === "object" &&
- value !== null &&
- "action" in value &&
- Object.keys(value).length === 1
- );
-}
-
-function isPatternRule(value: unknown): value is Record<string, { action: string }> {
- return typeof value === "object" && value !== null && !("action" in value);
-}
-</script>
-
-<details class="collapse collapse-arrow bg-base-200 mt-2">
- <summary class="collapse-title text-sm font-medium flex items-center gap-2">
- <span>Configuration</span>
- {#if modelCount > 0 || keyCount > 0}
- <span class="badge badge-sm badge-neutral">{modelCount} models</span>
- <span class="badge badge-sm badge-neutral">{keyCount} keys</span>
- {/if}
- {#if loading}
- <span class="loading loading-spinner loading-xs ml-auto"></span>
- {/if}
- </summary>
-
- <div class="collapse-content text-xs">
- {#if error}
- <div class="alert alert-error alert-sm py-1 mb-2 text-xs">
- <span>Failed to load config: {error}</span>
- </div>
- {/if}
-
- <div class="flex justify-end mb-2">
- <button
- type="button"
- class="btn btn-xs btn-ghost"
- onclick={fetchData}
- disabled={loading}
- >
- {loading ? "Loading…" : "Refresh"}
- </button>
- </div>
-
- <!-- Agent Templates -->
- {#if configData?.agents && Object.keys(configData.agents).length > 0}
- <div class="mb-3">
- <div class="text-xs font-semibold text-base-content/60 uppercase tracking-wide mb-1">Agent Templates</div>
- {#each Object.entries(configData.agents) as [name, template]}
- <div class="bg-base-100 rounded p-2 mb-1">
- <div class="flex items-center gap-2 flex-wrap">
- <span class="font-medium">{name}</span>
- {#if template.model_tag}
- <span class="badge badge-xs badge-info">{template.model_tag}</span>
- {/if}
- </div>
- {#if template.description}
- <p class="text-base-content/60 mt-0.5">{template.description}</p>
- {/if}
- {#if template.tools && template.tools.length > 0}
- <div class="flex flex-wrap gap-1 mt-1">
- {#each template.tools as tool}
- <span class="badge badge-xs badge-ghost">{tool}</span>
- {/each}
- </div>
- {/if}
- </div>
- {/each}
- </div>
- {/if}
-
- <!-- Models -->
- {#if modelsData?.models && modelsData.models.length > 0}
- <div class="mb-3">
- <div class="text-xs font-semibold text-base-content/60 uppercase tracking-wide mb-1">Models</div>
- {#each modelsData.models as model}
- <div class="flex items-center gap-2 flex-wrap py-0.5 border-b border-base-300">
- <span class="font-mono">{model.id}</span>
- {#if model.provider}
- <span class="badge badge-xs badge-primary">{model.provider}</span>
- {/if}
- {#if model.tags && model.tags.length > 0}
- {#each model.tags as tag}
- <span class="badge badge-xs badge-ghost">{tag}</span>
- {/each}
- {/if}
- </div>
- {/each}
- </div>
- {/if}
-
- <!-- Keys -->
- {#if modelsData?.keys && modelsData.keys.length > 0}
- <div class="mb-3">
- <div class="text-xs font-semibold text-base-content/60 uppercase tracking-wide mb-1">API Keys</div>
- {#each modelsData.keys as key}
- <div class="bg-base-100 rounded p-1.5 mb-1">
- <div class="flex items-center gap-2 flex-wrap">
- <span class="font-mono">{key.id}</span>
- {#if key.provider}
- <span class="badge badge-xs badge-secondary">{key.provider}</span>
- {/if}
- {#if key.status === "exhausted"}
- <span class="badge badge-xs badge-error">exhausted</span>
- {:else}
- <span class="badge badge-xs badge-success">active</span>
- {/if}
- </div>
- {#if key.status === "exhausted" && key.lastError}
- <p class="text-error/80 mt-0.5 truncate">{key.lastError}</p>
- {/if}
- {#if key.exhaustedAt}
- <p class="text-base-content/40 mt-0.5">Since {formatDate(key.exhaustedAt)}</p>
- {/if}
- </div>
- {/each}
- </div>
- {/if}
-
- <!-- Fallback Order -->
- {#if configData?.fallback && configData.fallback.length > 0}
- <div class="mb-3">
- <div class="text-xs font-semibold text-base-content/60 uppercase tracking-wide mb-1">Fallback Order</div>
- <ol class="list-none space-y-0.5">
- {#each configData.fallback as keyId, i}
- <li class="flex items-center gap-2">
- <span class="badge badge-xs badge-outline">{i + 1}</span>
- <span class="font-mono">{keyId}</span>
- </li>
- {/each}
- </ol>
- </div>
- {/if}
-
- <!-- Permissions -->
- {#if configData?.permissions && Object.keys(configData.permissions).length > 0}
- <div class="mb-1">
- <div class="text-xs font-semibold text-base-content/60 uppercase tracking-wide mb-1">Permissions</div>
- {#each permissionEntries(configData.permissions) as entry}
- <div class="py-0.5 border-b border-base-300">
- <span class="font-medium text-base-content/80">{entry.name}</span>
- {#if isSimpleRule(entry.value)}
- <span class="ml-2 badge badge-xs {entry.value.action === 'allow' ? 'badge-success' : 'badge-error'}">{entry.value.action}</span>
- {:else if isPatternRule(entry.value)}
- {#each Object.entries(entry.value) as [pattern, rule]}
- <div class="pl-2 flex items-center gap-2">
- <span class="text-base-content/50 font-mono truncate max-w-32">{pattern}</span>
- {#if typeof rule === "object" && rule !== null && "action" in rule}
- <span class="badge badge-xs {(rule as { action: string }).action === 'allow' ? 'badge-success' : 'badge-error'}">{(rule as { action: string }).action}</span>
- {/if}
- </div>
- {/each}
- {:else}
- <span class="text-base-content/40 ml-2">{JSON.stringify(entry.value)}</span>
- {/if}
- </div>
- {/each}
- </div>
- {/if}
-
- {#if !loading && !error && !configData && !modelsData}
- <p class="text-base-content/40 italic">No configuration loaded.</p>
- {/if}
- </div>
-</details>