bazilion 0.0.0 → 0.1.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/README.md +53 -152
- package/dist/cli.js +2730 -0
- package/dist/cli.js.map +1 -0
- package/dist/daemon.js +5888 -0
- package/dist/daemon.js.map +1 -0
- package/dist/worker.js +1830 -0
- package/dist/worker.js.map +1 -0
- package/package.json +57 -28
- package/.understand-anything/.understandignore +0 -25
- package/.understand-anything/fingerprints.json +0 -14267
- package/.understand-anything/knowledge-graph.json +0 -18128
- package/.understand-anything/meta.json +0 -6
- package/CLAUDE.md +0 -164
- package/apps/cli/package.json +0 -21
- package/apps/cli/src/auth-file.ts +0 -18
- package/apps/cli/src/client.ts +0 -37
- package/apps/cli/src/columnize.ts +0 -32
- package/apps/cli/src/commands/agent.ts +0 -574
- package/apps/cli/src/commands/auth.ts +0 -110
- package/apps/cli/src/commands/backup.ts +0 -135
- package/apps/cli/src/commands/completion.ts +0 -155
- package/apps/cli/src/commands/config.ts +0 -95
- package/apps/cli/src/commands/doctor.ts +0 -131
- package/apps/cli/src/commands/group.ts +0 -132
- package/apps/cli/src/commands/inbox.ts +0 -82
- package/apps/cli/src/commands/login.ts +0 -73
- package/apps/cli/src/commands/memory.ts +0 -106
- package/apps/cli/src/commands/profile.ts +0 -259
- package/apps/cli/src/commands/provider.ts +0 -170
- package/apps/cli/src/commands/send.ts +0 -24
- package/apps/cli/src/commands/serve.ts +0 -89
- package/apps/cli/src/commands/skill.ts +0 -120
- package/apps/cli/src/commands/token.ts +0 -148
- package/apps/cli/src/commands/trigger.ts +0 -129
- package/apps/cli/src/commands/uninstall.ts +0 -156
- package/apps/cli/src/index.ts +0 -196
- package/apps/cli/src/paths.ts +0 -12
- package/apps/cli/test/agent.test.ts +0 -213
- package/apps/cli/test/backup.test.ts +0 -95
- package/apps/cli/test/chat.test.ts +0 -539
- package/apps/cli/test/columnize.test.ts +0 -29
- package/apps/cli/test/completion.test.ts +0 -45
- package/apps/cli/test/config-page.test.ts +0 -151
- package/apps/cli/test/group.test.ts +0 -74
- package/apps/cli/test/helpers.ts +0 -70
- package/apps/cli/test/inbox-autodeliver.test.ts +0 -143
- package/apps/cli/test/inbox.test.ts +0 -147
- package/apps/cli/test/memory.test.ts +0 -69
- package/apps/cli/test/profile.test.ts +0 -110
- package/apps/cli/test/send.test.ts +0 -30
- package/apps/cli/test/server-fixture.ts +0 -212
- package/apps/cli/test/session-head.test.ts +0 -45
- package/apps/cli/test/skill.test.ts +0 -128
- package/apps/cli/test/token.test.ts +0 -109
- package/apps/cli/test/trigger.test.ts +0 -245
- package/apps/cli/tsconfig.json +0 -4
- package/apps/daemon/package.json +0 -31
- package/apps/daemon/src/app.ts +0 -41
- package/apps/daemon/src/core/agent/archive.ts +0 -8
- package/apps/daemon/src/core/agent/delete.ts +0 -30
- package/apps/daemon/src/core/agent/resolve.ts +0 -31
- package/apps/daemon/src/core/agent/spawn.ts +0 -95
- package/apps/daemon/src/core/agent/unarchive.ts +0 -11
- package/apps/daemon/src/core/availableModels.ts +0 -58
- package/apps/daemon/src/core/db/client.ts +0 -113
- package/apps/daemon/src/core/db/migrate.ts +0 -41
- package/apps/daemon/src/core/db/migrations/0001_init.sql +0 -179
- package/apps/daemon/src/core/group/delete.ts +0 -21
- package/apps/daemon/src/core/group/register.ts +0 -68
- package/apps/daemon/src/core/index.ts +0 -71
- package/apps/daemon/src/core/paths.ts +0 -56
- package/apps/daemon/src/core/profile/create.ts +0 -78
- package/apps/daemon/src/core/profile/delete.ts +0 -26
- package/apps/daemon/src/core/profile/identity.ts +0 -70
- package/apps/daemon/src/core/profile/load.ts +0 -45
- package/apps/daemon/src/core/profile/seed.ts +0 -74
- package/apps/daemon/src/core/profile/templates.ts +0 -60
- package/apps/daemon/src/core/profile/update.ts +0 -57
- package/apps/daemon/src/core/profile/validate.ts +0 -9
- package/apps/daemon/src/core/repos/agents.ts +0 -202
- package/apps/daemon/src/core/repos/config.ts +0 -78
- package/apps/daemon/src/core/repos/groups.ts +0 -55
- package/apps/daemon/src/core/repos/messages.ts +0 -127
- package/apps/daemon/src/core/repos/profiles.ts +0 -83
- package/apps/daemon/src/core/repos/providerModels.ts +0 -58
- package/apps/daemon/src/core/repos/providerState.ts +0 -37
- package/apps/daemon/src/core/repos/secrets.ts +0 -145
- package/apps/daemon/src/core/repos/skillMeta.ts +0 -49
- package/apps/daemon/src/core/repos/triggers.ts +0 -101
- package/apps/daemon/src/core/repos/webTokens.ts +0 -87
- package/apps/daemon/src/core/secrets.ts +0 -65
- package/apps/daemon/src/core/services.ts +0 -264
- package/apps/daemon/src/core/skills/discover.ts +0 -28
- package/apps/daemon/src/core/skills/import.ts +0 -136
- package/apps/daemon/src/core/skills/parse.ts +0 -52
- package/apps/daemon/src/core/skills/resolve.ts +0 -50
- package/apps/daemon/src/index.ts +0 -45
- package/apps/daemon/src/lib/agent-cancel.ts +0 -48
- package/apps/daemon/src/lib/agent-id.ts +0 -13
- package/apps/daemon/src/lib/agent-turn.ts +0 -56
- package/apps/daemon/src/lib/api-key.ts +0 -56
- package/apps/daemon/src/lib/auth.ts +0 -41
- package/apps/daemon/src/lib/cron.ts +0 -93
- package/apps/daemon/src/lib/ctx.ts +0 -80
- package/apps/daemon/src/lib/messaging-host.ts +0 -34
- package/apps/daemon/src/lib/middleware-auth.ts +0 -52
- package/apps/daemon/src/lib/scheduler.ts +0 -294
- package/apps/daemon/src/routes/agents.ts +0 -772
- package/apps/daemon/src/routes/auth-login.ts +0 -193
- package/apps/daemon/src/routes/config.ts +0 -267
- package/apps/daemon/src/routes/groups.ts +0 -133
- package/apps/daemon/src/routes/messages.ts +0 -29
- package/apps/daemon/src/routes/misc.ts +0 -239
- package/apps/daemon/src/routes/profiles.ts +0 -197
- package/apps/daemon/src/routes/skills.ts +0 -123
- package/apps/daemon/src/routes/triggers.ts +0 -29
- package/apps/daemon/src/runtime/auth/openai-codex.ts +0 -121
- package/apps/daemon/src/runtime/auto-reply/heartbeat.ts +0 -31
- package/apps/daemon/src/runtime/index.ts +0 -77
- package/apps/daemon/src/runtime/memory/files.ts +0 -103
- package/apps/daemon/src/runtime/memory/qmd.ts +0 -152
- package/apps/daemon/src/runtime/memory/types.ts +0 -16
- package/apps/daemon/src/runtime/pi/events.ts +0 -173
- package/apps/daemon/src/runtime/pi/session.ts +0 -536
- package/apps/daemon/src/runtime/pi/tools.ts +0 -85
- package/apps/daemon/src/runtime/providers/catalog.ts +0 -145
- package/apps/daemon/src/runtime/providers/pi-adapter.ts +0 -272
- package/apps/daemon/src/runtime/providers/registry.ts +0 -374
- package/apps/daemon/src/runtime/providers/retry.ts +0 -176
- package/apps/daemon/src/runtime/providers/types.ts +0 -33
- package/apps/daemon/src/runtime/session/prompt.ts +0 -83
- package/apps/daemon/src/runtime/tools/bootstrap.ts +0 -22
- package/apps/daemon/src/runtime/tools/home.ts +0 -114
- package/apps/daemon/src/runtime/tools/memory.ts +0 -81
- package/apps/daemon/src/runtime/tools/messaging.ts +0 -127
- package/apps/daemon/src/runtime/tools/registry.ts +0 -29
- package/apps/daemon/src/runtime/tools/types.ts +0 -13
- package/apps/daemon/src/runtime/tools/web-extract.ts +0 -110
- package/apps/daemon/src/runtime/tools/web-ssrf.ts +0 -245
- package/apps/daemon/src/runtime/tools/web.ts +0 -273
- package/apps/daemon/src/runtime/worker/entry.ts +0 -221
- package/apps/daemon/src/runtime/worker/ipc-protocol.ts +0 -75
- package/apps/daemon/src/runtime/worker/spawn.ts +0 -249
- package/apps/daemon/test/core/agents.test.ts +0 -319
- package/apps/daemon/test/core/available-models.test.ts +0 -63
- package/apps/daemon/test/core/config.test.ts +0 -99
- package/apps/daemon/test/core/groups.test.ts +0 -63
- package/apps/daemon/test/core/helpers.ts +0 -50
- package/apps/daemon/test/core/identity.test.ts +0 -85
- package/apps/daemon/test/core/migrations.test.ts +0 -83
- package/apps/daemon/test/core/profiles.test.ts +0 -182
- package/apps/daemon/test/core/provider-models.test.ts +0 -57
- package/apps/daemon/test/core/provider-state.test.ts +0 -36
- package/apps/daemon/test/core/skill-meta.test.ts +0 -45
- package/apps/daemon/test/core/skills.test.ts +0 -271
- package/apps/daemon/test/core/triggers.test.ts +0 -182
- package/apps/daemon/test/core/web-tokens.test.ts +0 -79
- package/apps/daemon/test/cron.test.ts +0 -90
- package/apps/daemon/test/runtime/heartbeat.test.ts +0 -34
- package/apps/daemon/test/runtime/memory-qmd.test.ts +0 -97
- package/apps/daemon/test/runtime/memory.test.ts +0 -78
- package/apps/daemon/test/runtime/messaging.test.ts +0 -213
- package/apps/daemon/test/runtime/mock-server.ts +0 -65
- package/apps/daemon/test/runtime/openai-codex-auth.test.ts +0 -116
- package/apps/daemon/test/runtime/providers.test.ts +0 -306
- package/apps/daemon/test/runtime/retry.test.ts +0 -191
- package/apps/daemon/test/runtime/session-head.test.ts +0 -90
- package/apps/daemon/test/runtime/tools-home.test.ts +0 -102
- package/apps/daemon/test/runtime/tools-web.test.ts +0 -206
- package/apps/daemon/tsconfig.json +0 -4
- package/apps/mobile/README.md +0 -60
- package/apps/mobile/app/_layout.tsx +0 -58
- package/apps/mobile/app/agents/[id]/chat.tsx +0 -486
- package/apps/mobile/app/agents/[id]/index.tsx +0 -166
- package/apps/mobile/app/agents/index.tsx +0 -212
- package/apps/mobile/app/index.tsx +0 -21
- package/apps/mobile/app/pair.tsx +0 -226
- package/apps/mobile/app/settings.tsx +0 -419
- package/apps/mobile/app.json +0 -49
- package/apps/mobile/assets/adaptive-icon.png +0 -0
- package/apps/mobile/assets/favicon.png +0 -0
- package/apps/mobile/assets/icon.png +0 -0
- package/apps/mobile/assets/splash-icon.png +0 -0
- package/apps/mobile/babel.config.js +0 -6
- package/apps/mobile/metro.config.js +0 -28
- package/apps/mobile/package.json +0 -44
- package/apps/mobile/src/auth.ts +0 -66
- package/apps/mobile/src/pair-url.ts +0 -48
- package/apps/mobile/src/theme-context.tsx +0 -88
- package/apps/mobile/src/theme.ts +0 -135
- package/apps/mobile/test/pair-url.test.ts +0 -46
- package/apps/mobile/tsconfig.json +0 -23
- package/apps/web/components.json +0 -25
- package/apps/web/package.json +0 -39
- package/apps/web/public/baziu.svg +0 -8
- package/apps/web/src/components/AgentTabs.tsx +0 -45
- package/apps/web/src/components/BaziuLogo.tsx +0 -21
- package/apps/web/src/components/ChatPane.tsx +0 -1033
- package/apps/web/src/components/ConfigTabs.tsx +0 -29
- package/apps/web/src/components/CopyButton.tsx +0 -68
- package/apps/web/src/components/CreateGroupDialog.tsx +0 -127
- package/apps/web/src/components/FieldRow.tsx +0 -94
- package/apps/web/src/components/Footer.tsx +0 -10
- package/apps/web/src/components/PawIcon.tsx +0 -15
- package/apps/web/src/components/Sidebar.tsx +0 -287
- package/apps/web/src/components/SpawnDialog.tsx +0 -129
- package/apps/web/src/components/ThemeToggle.tsx +0 -75
- package/apps/web/src/components/TopNav.tsx +0 -34
- package/apps/web/src/components/ui/button.tsx +0 -67
- package/apps/web/src/components/ui/card.tsx +0 -103
- package/apps/web/src/components/ui/checkbox.tsx +0 -31
- package/apps/web/src/components/ui/dialog.tsx +0 -168
- package/apps/web/src/components/ui/input.tsx +0 -19
- package/apps/web/src/components/ui/label.tsx +0 -22
- package/apps/web/src/components/ui/radio-group.tsx +0 -44
- package/apps/web/src/components/ui/select.tsx +0 -192
- package/apps/web/src/components/ui/separator.tsx +0 -26
- package/apps/web/src/components/ui/table.tsx +0 -116
- package/apps/web/src/components/ui/tabs.tsx +0 -88
- package/apps/web/src/components/ui/textarea.tsx +0 -18
- package/apps/web/src/lib/auth.ts +0 -50
- package/apps/web/src/lib/daemon-client.ts +0 -34
- package/apps/web/src/lib/md.ts +0 -45
- package/apps/web/src/lib/utils.ts +0 -6
- package/apps/web/src/lib/wire-constants.ts +0 -27
- package/apps/web/src/routeTree.gen.ts +0 -408
- package/apps/web/src/router.tsx +0 -20
- package/apps/web/src/routes/__root.tsx +0 -123
- package/apps/web/src/routes/agents/$id/inbox.tsx +0 -207
- package/apps/web/src/routes/agents/$id/index.tsx +0 -527
- package/apps/web/src/routes/agents/$id/triggers.tsx +0 -239
- package/apps/web/src/routes/agents/index.tsx +0 -265
- package/apps/web/src/routes/api/$.ts +0 -88
- package/apps/web/src/routes/config/index.tsx +0 -315
- package/apps/web/src/routes/config/services.tsx +0 -49
- package/apps/web/src/routes/config/tokens.tsx +0 -192
- package/apps/web/src/routes/groups/$id/index.tsx +0 -153
- package/apps/web/src/routes/groups/$id/memory.tsx +0 -321
- package/apps/web/src/routes/groups/index.tsx +0 -191
- package/apps/web/src/routes/index.tsx +0 -133
- package/apps/web/src/routes/login.tsx +0 -63
- package/apps/web/src/routes/profiles/$id.tsx +0 -549
- package/apps/web/src/routes/profiles/index.tsx +0 -458
- package/apps/web/src/routes/skills/index.tsx +0 -297
- package/apps/web/src/routes/welcome.tsx +0 -61
- package/apps/web/src/styles.css +0 -449
- package/apps/web/tsconfig.json +0 -25
- package/apps/web/vite.config.ts +0 -25
- package/biome.json +0 -23
- package/docs/agent-engine.md +0 -219
- package/docs/architecture.md +0 -627
- package/docs/backlog/README.md +0 -42
- package/docs/backlog/draft/BAZ-001-a2a-federation-spike.md +0 -125
- package/docs/openclaw-reference.md +0 -210
- package/packages/api-types/package.json +0 -11
- package/packages/api-types/src/entities.ts +0 -146
- package/packages/api-types/src/events.ts +0 -55
- package/packages/api-types/src/index.ts +0 -488
- package/packages/api-types/src/memory.ts +0 -15
- package/packages/client/package.json +0 -13
- package/packages/client/src/index.ts +0 -117
- package/pnpm-workspace.yaml +0 -3
- package/tsconfig.base.json +0 -23
- package/tsconfig.json +0 -11
- package/vitest.config.ts +0 -22
|
@@ -1,315 +0,0 @@
|
|
|
1
|
-
import type { ProviderConfigEntry, ProviderConfigResponse } from '@bazilion/api-types'
|
|
2
|
-
import { createFileRoute, useRouter } from '@tanstack/react-router'
|
|
3
|
-
import { createServerFn } from '@tanstack/react-start'
|
|
4
|
-
import { useState } from 'react'
|
|
5
|
-
import { ConfigTabs } from '../../components/ConfigTabs'
|
|
6
|
-
import { FieldRow } from '../../components/FieldRow'
|
|
7
|
-
import { daemonClient } from '../../lib/daemon-client'
|
|
8
|
-
|
|
9
|
-
interface OpenAICodexStatus {
|
|
10
|
-
connected: boolean
|
|
11
|
-
expiresAt: number | null
|
|
12
|
-
accountId: string | null
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
interface ProvidersData {
|
|
16
|
-
providers: ProviderConfigEntry[]
|
|
17
|
-
openaiCodex: OpenAICodexStatus
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const fetchProvidersData = createServerFn({ method: 'GET' }).handler(
|
|
21
|
-
async (): Promise<ProvidersData> => {
|
|
22
|
-
const c = daemonClient()
|
|
23
|
-
const [{ providers }, openaiCodex] = await Promise.all([
|
|
24
|
-
c.get<ProviderConfigResponse>('/api/config/providers'),
|
|
25
|
-
c.get<OpenAICodexStatus>('/api/auth/openai'),
|
|
26
|
-
])
|
|
27
|
-
return { providers, openaiCodex }
|
|
28
|
-
},
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
export const Route = createFileRoute('/config/')({
|
|
32
|
-
loader: () => fetchProvidersData(),
|
|
33
|
-
component: ProvidersPage,
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
function ProvidersPage() {
|
|
37
|
-
const { providers, openaiCodex } = Route.useLoaderData()
|
|
38
|
-
return (
|
|
39
|
-
<main className="mx-auto max-w-5xl px-6 py-8">
|
|
40
|
-
<h1 className="font-serif text-3xl text-foreground mb-2">config</h1>
|
|
41
|
-
<ConfigTabs active="providers" />
|
|
42
|
-
<p className="text-muted-foreground text-sm mb-6">
|
|
43
|
-
Each card configures one LLM provider end to end: credentials (encrypted in the{' '}
|
|
44
|
-
<code className="font-mono">secrets</code> table), URLs and IDs (plaintext in the{' '}
|
|
45
|
-
<code className="font-mono">config</code> table), and the curated model list that
|
|
46
|
-
powers profile / agent dropdowns.
|
|
47
|
-
</p>
|
|
48
|
-
{providers.map((p) => (
|
|
49
|
-
<ProviderCard
|
|
50
|
-
key={p.id}
|
|
51
|
-
p={p}
|
|
52
|
-
openaiCodexStatus={p.id === 'openai-codex' ? openaiCodex : undefined}
|
|
53
|
-
/>
|
|
54
|
-
))}
|
|
55
|
-
</main>
|
|
56
|
-
)
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function ProviderCard({
|
|
60
|
-
p,
|
|
61
|
-
openaiCodexStatus,
|
|
62
|
-
}: {
|
|
63
|
-
p: ProviderConfigEntry
|
|
64
|
-
openaiCodexStatus: OpenAICodexStatus | undefined
|
|
65
|
-
}) {
|
|
66
|
-
const router = useRouter()
|
|
67
|
-
const [enabled, setEnabled] = useState(p.enabled)
|
|
68
|
-
const [models, setModels] = useState(p.curated.join('\n'))
|
|
69
|
-
const [savingModels, setSavingModels] = useState(false)
|
|
70
|
-
const [modelStatus, setModelStatus] = useState<string | null>(null)
|
|
71
|
-
|
|
72
|
-
async function toggle(next: boolean) {
|
|
73
|
-
setEnabled(next)
|
|
74
|
-
try {
|
|
75
|
-
await fetch(`/api/config/providers/${encodeURIComponent(p.id)}/enabled`, {
|
|
76
|
-
method: 'PUT',
|
|
77
|
-
headers: { 'content-type': 'application/json' },
|
|
78
|
-
body: JSON.stringify({ enabled: next }),
|
|
79
|
-
})
|
|
80
|
-
await router.invalidate()
|
|
81
|
-
} catch {
|
|
82
|
-
setEnabled(!next)
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
async function saveModels(e: React.FormEvent) {
|
|
87
|
-
e.preventDefault()
|
|
88
|
-
setSavingModels(true)
|
|
89
|
-
setModelStatus(null)
|
|
90
|
-
try {
|
|
91
|
-
const list = models
|
|
92
|
-
.split(/\r?\n/)
|
|
93
|
-
.map((s) => s.trim())
|
|
94
|
-
.filter(Boolean)
|
|
95
|
-
const res = await fetch(`/api/config/providers/${encodeURIComponent(p.id)}/models`, {
|
|
96
|
-
method: 'PUT',
|
|
97
|
-
headers: { 'content-type': 'application/json' },
|
|
98
|
-
body: JSON.stringify({ models: list }),
|
|
99
|
-
})
|
|
100
|
-
if (!res.ok) {
|
|
101
|
-
const j = (await res.json().catch(() => ({}))) as { error?: string }
|
|
102
|
-
throw new Error(j.error ?? `${res.status} ${res.statusText}`)
|
|
103
|
-
}
|
|
104
|
-
setModelStatus('saved ✓')
|
|
105
|
-
await router.invalidate()
|
|
106
|
-
} catch (e) {
|
|
107
|
-
setModelStatus(`error: ${(e as Error).message}`)
|
|
108
|
-
} finally {
|
|
109
|
-
setSavingModels(false)
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return (
|
|
114
|
-
<section className="rounded-lg border bg-card mb-3 overflow-hidden">
|
|
115
|
-
<header className="flex items-center gap-3 px-4 py-3">
|
|
116
|
-
<span className="font-mono font-semibold">{p.id}</span>
|
|
117
|
-
<span className="text-muted-foreground text-sm">· {p.displayName}</span>
|
|
118
|
-
<label className="flex items-center gap-1.5 text-xs uppercase tracking-wide font-semibold cursor-pointer">
|
|
119
|
-
<input
|
|
120
|
-
type="checkbox"
|
|
121
|
-
checked={enabled}
|
|
122
|
-
onChange={(e) => toggle(e.target.checked)}
|
|
123
|
-
className="size-4"
|
|
124
|
-
/>
|
|
125
|
-
<span className={enabled ? 'text-emerald-700' : 'text-muted-foreground'}>
|
|
126
|
-
{enabled ? 'enabled' : 'disabled'}
|
|
127
|
-
</span>
|
|
128
|
-
</label>
|
|
129
|
-
<span className="ml-auto text-xs text-muted-foreground">
|
|
130
|
-
{p.curated.length > 0 && <span>{p.curated.length} curated</span>}
|
|
131
|
-
{p.catalog.length > 0 && <span> · {p.catalog.length} catalog</span>}
|
|
132
|
-
{p.live && !p.live.error && <span> · {p.live.models.length} live</span>}
|
|
133
|
-
</span>
|
|
134
|
-
</header>
|
|
135
|
-
|
|
136
|
-
{enabled && (
|
|
137
|
-
<div className="border-t border-dashed px-4 py-3">
|
|
138
|
-
{p.hint && <p className="text-xs text-muted-foreground mb-2">{p.hint}</p>}
|
|
139
|
-
|
|
140
|
-
{p.id === 'openai-codex' && openaiCodexStatus && (
|
|
141
|
-
<OpenAICodexCard status={openaiCodexStatus} />
|
|
142
|
-
)}
|
|
143
|
-
|
|
144
|
-
{p.fields.length === 0 && p.envHint && p.id !== 'openai-codex' && (
|
|
145
|
-
<p className="text-xs text-muted-foreground">
|
|
146
|
-
Credentials come from the process env: <code className="font-mono">{p.envHint}</code>
|
|
147
|
-
</p>
|
|
148
|
-
)}
|
|
149
|
-
|
|
150
|
-
{p.fields.map((f) => (
|
|
151
|
-
<FieldRow key={f.envVar} field={f} />
|
|
152
|
-
))}
|
|
153
|
-
|
|
154
|
-
<h4 className="mt-4 mb-1 text-xs uppercase tracking-wide text-muted-foreground">
|
|
155
|
-
curated models (one per line)
|
|
156
|
-
</h4>
|
|
157
|
-
<form onSubmit={saveModels}>
|
|
158
|
-
<textarea
|
|
159
|
-
value={models}
|
|
160
|
-
onChange={(e) => setModels(e.target.value)}
|
|
161
|
-
rows={Math.max(3, Math.min(8, models.split('\n').length))}
|
|
162
|
-
className="w-full rounded-md border bg-background px-2 py-1.5 font-mono text-sm outline-none focus:ring-2 focus:ring-ring/30"
|
|
163
|
-
placeholder={
|
|
164
|
-
p.catalog.length === 0 && !p.live
|
|
165
|
-
? 'Type model names one per line, e.g. qwen3-coder-30b'
|
|
166
|
-
: 'Click catalog chips below, or type names one per line'
|
|
167
|
-
}
|
|
168
|
-
/>
|
|
169
|
-
<div className="flex items-center gap-3 mt-2">
|
|
170
|
-
<button
|
|
171
|
-
type="submit"
|
|
172
|
-
disabled={savingModels}
|
|
173
|
-
className="rounded-md bg-primary px-3 py-1.5 text-sm font-medium text-primary-foreground disabled:opacity-50"
|
|
174
|
-
>
|
|
175
|
-
save models
|
|
176
|
-
</button>
|
|
177
|
-
{modelStatus && (
|
|
178
|
-
<span className="text-xs text-muted-foreground">{modelStatus}</span>
|
|
179
|
-
)}
|
|
180
|
-
</div>
|
|
181
|
-
</form>
|
|
182
|
-
|
|
183
|
-
{p.catalog.length > 0 && (
|
|
184
|
-
<>
|
|
185
|
-
<h4 className="mt-4 mb-1 text-xs uppercase tracking-wide text-muted-foreground">
|
|
186
|
-
catalog
|
|
187
|
-
</h4>
|
|
188
|
-
<ChipList
|
|
189
|
-
items={p.catalog}
|
|
190
|
-
onPick={(name) => setModels((m) => (m.includes(name) ? m : `${m}\n${name}`.trim()))}
|
|
191
|
-
/>
|
|
192
|
-
</>
|
|
193
|
-
)}
|
|
194
|
-
{p.live && !p.live.error && p.live.models.length > 0 && (
|
|
195
|
-
<>
|
|
196
|
-
<h4 className="mt-4 mb-1 text-xs uppercase tracking-wide text-muted-foreground">
|
|
197
|
-
live
|
|
198
|
-
</h4>
|
|
199
|
-
<ChipList
|
|
200
|
-
items={p.live.models}
|
|
201
|
-
onPick={(name) => setModels((m) => (m.includes(name) ? m : `${m}\n${name}`.trim()))}
|
|
202
|
-
/>
|
|
203
|
-
</>
|
|
204
|
-
)}
|
|
205
|
-
{p.live?.error && (
|
|
206
|
-
<p className="text-xs text-rose-700 mt-2">could not fetch: {p.live.error}</p>
|
|
207
|
-
)}
|
|
208
|
-
</div>
|
|
209
|
-
)}
|
|
210
|
-
</section>
|
|
211
|
-
)
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
function ChipList({ items, onPick }: { items: string[]; onPick: (name: string) => void }) {
|
|
215
|
-
return (
|
|
216
|
-
<div className="flex flex-wrap gap-1.5 max-h-40 overflow-y-auto rounded-md border bg-background p-1.5">
|
|
217
|
-
{items.map((m) => (
|
|
218
|
-
<button
|
|
219
|
-
key={m}
|
|
220
|
-
type="button"
|
|
221
|
-
onClick={() => onPick(m)}
|
|
222
|
-
className="rounded border bg-card px-2 py-0.5 font-mono text-xs hover:border-primary hover:bg-accent"
|
|
223
|
-
>
|
|
224
|
-
{m}
|
|
225
|
-
</button>
|
|
226
|
-
))}
|
|
227
|
-
</div>
|
|
228
|
-
)
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
function OpenAICodexCard({ status }: { status: OpenAICodexStatus }) {
|
|
232
|
-
const router = useRouter()
|
|
233
|
-
const [busy, setBusy] = useState(false)
|
|
234
|
-
const [err, setErr] = useState<string | null>(null)
|
|
235
|
-
|
|
236
|
-
async function connect() {
|
|
237
|
-
setBusy(true)
|
|
238
|
-
setErr(null)
|
|
239
|
-
try {
|
|
240
|
-
const res = await fetch('/api/auth/openai/login', { method: 'POST' })
|
|
241
|
-
if (!res.ok) {
|
|
242
|
-
const j = (await res.json().catch(() => ({}))) as { error?: string }
|
|
243
|
-
throw new Error(j.error ?? `${res.status} ${res.statusText}`)
|
|
244
|
-
}
|
|
245
|
-
await router.invalidate()
|
|
246
|
-
} catch (e) {
|
|
247
|
-
setErr((e as Error).message)
|
|
248
|
-
} finally {
|
|
249
|
-
setBusy(false)
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
async function disconnect() {
|
|
253
|
-
setBusy(true)
|
|
254
|
-
setErr(null)
|
|
255
|
-
try {
|
|
256
|
-
await fetch('/api/auth/openai', { method: 'DELETE' })
|
|
257
|
-
await router.invalidate()
|
|
258
|
-
} catch (e) {
|
|
259
|
-
setErr((e as Error).message)
|
|
260
|
-
} finally {
|
|
261
|
-
setBusy(false)
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
return (
|
|
266
|
-
<div className="rounded-md border bg-muted/30 p-3 mb-3">
|
|
267
|
-
{status.connected ? (
|
|
268
|
-
<>
|
|
269
|
-
<div className="flex flex-wrap gap-2 items-center mb-2">
|
|
270
|
-
<span className="rounded-full bg-emerald-100 text-emerald-800 px-2 py-0.5 text-xs font-semibold uppercase">
|
|
271
|
-
connected
|
|
272
|
-
</span>
|
|
273
|
-
{status.accountId && (
|
|
274
|
-
<span className="text-xs text-muted-foreground">
|
|
275
|
-
account <code className="font-mono">{status.accountId}</code>
|
|
276
|
-
</span>
|
|
277
|
-
)}
|
|
278
|
-
{status.expiresAt && (
|
|
279
|
-
<span className="text-xs text-muted-foreground">
|
|
280
|
-
token expires{' '}
|
|
281
|
-
{new Date(status.expiresAt).toISOString().replace(/\.\d+Z$/, 'Z')}
|
|
282
|
-
</span>
|
|
283
|
-
)}
|
|
284
|
-
</div>
|
|
285
|
-
<button
|
|
286
|
-
type="button"
|
|
287
|
-
onClick={disconnect}
|
|
288
|
-
disabled={busy}
|
|
289
|
-
className="rounded-md border px-3 py-1.5 text-sm text-rose-700 hover:bg-rose-50 disabled:opacity-50"
|
|
290
|
-
>
|
|
291
|
-
disconnect
|
|
292
|
-
</button>
|
|
293
|
-
</>
|
|
294
|
-
) : (
|
|
295
|
-
<>
|
|
296
|
-
<p className="text-xs text-muted-foreground mb-2">
|
|
297
|
-
Sign in with your ChatGPT account — the OAuth flow opens a new browser tab. The
|
|
298
|
-
loopback callback at <code className="font-mono">localhost:1455</code> only works
|
|
299
|
-
when you're using the web UI on the same machine as the daemon. For remote setups,
|
|
300
|
-
run <code className="font-mono">bazilion auth openai login</code> on the client.
|
|
301
|
-
</p>
|
|
302
|
-
<button
|
|
303
|
-
type="button"
|
|
304
|
-
onClick={connect}
|
|
305
|
-
disabled={busy}
|
|
306
|
-
className="rounded-md bg-primary px-3 py-1.5 text-sm font-medium text-primary-foreground disabled:opacity-50"
|
|
307
|
-
>
|
|
308
|
-
{busy ? 'opening browser…' : 'Connect ChatGPT →'}
|
|
309
|
-
</button>
|
|
310
|
-
</>
|
|
311
|
-
)}
|
|
312
|
-
{err && <p className="text-sm text-rose-700 mt-2">{err}</p>}
|
|
313
|
-
</div>
|
|
314
|
-
)
|
|
315
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import type { ServiceConfigResponse } from '@bazilion/api-types'
|
|
2
|
-
import { createFileRoute } from '@tanstack/react-router'
|
|
3
|
-
import { createServerFn } from '@tanstack/react-start'
|
|
4
|
-
import { ConfigTabs } from '../../components/ConfigTabs'
|
|
5
|
-
import { FieldRow } from '../../components/FieldRow'
|
|
6
|
-
import { daemonClient } from '../../lib/daemon-client'
|
|
7
|
-
|
|
8
|
-
const fetchServices = createServerFn({ method: 'GET' }).handler(() =>
|
|
9
|
-
daemonClient().get<ServiceConfigResponse>('/api/config/services'),
|
|
10
|
-
)
|
|
11
|
-
|
|
12
|
-
export const Route = createFileRoute('/config/services')({
|
|
13
|
-
loader: () => fetchServices(),
|
|
14
|
-
component: ServicesPage,
|
|
15
|
-
})
|
|
16
|
-
|
|
17
|
-
function ServicesPage() {
|
|
18
|
-
const { services } = Route.useLoaderData()
|
|
19
|
-
return (
|
|
20
|
-
<main className="mx-auto max-w-5xl px-6 py-8">
|
|
21
|
-
<h1 className="font-serif text-3xl text-foreground mb-2">config</h1>
|
|
22
|
-
<ConfigTabs active="services" />
|
|
23
|
-
|
|
24
|
-
<p className="text-muted-foreground text-sm mb-6">
|
|
25
|
-
Configuration for non-LLM integrations — web search, crawlers, and similar. Fields
|
|
26
|
-
marked as secrets are encrypted in the <code className="font-mono">secrets</code>{' '}
|
|
27
|
-
table; plaintext URLs and IDs live in the <code className="font-mono">config</code>{' '}
|
|
28
|
-
table.
|
|
29
|
-
</p>
|
|
30
|
-
|
|
31
|
-
{services.length === 0 && (
|
|
32
|
-
<p className="text-muted-foreground italic">(no services registered)</p>
|
|
33
|
-
)}
|
|
34
|
-
|
|
35
|
-
{services.map((s) => (
|
|
36
|
-
<section key={s.id} className="rounded-lg border bg-card p-5 mb-3">
|
|
37
|
-
<header className="flex items-center gap-2 mb-3">
|
|
38
|
-
<span className="font-mono font-semibold">{s.id}</span>
|
|
39
|
-
<span className="text-muted-foreground text-sm">· {s.displayName}</span>
|
|
40
|
-
</header>
|
|
41
|
-
{s.hint && <p className="text-xs text-muted-foreground mb-2">{s.hint}</p>}
|
|
42
|
-
{s.fields.map((f) => (
|
|
43
|
-
<FieldRow key={f.envVar} field={f} />
|
|
44
|
-
))}
|
|
45
|
-
</section>
|
|
46
|
-
))}
|
|
47
|
-
</main>
|
|
48
|
-
)
|
|
49
|
-
}
|
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
import type { ListTokensResponse } from '@bazilion/api-types'
|
|
2
|
-
import { createFileRoute, useRouter } from '@tanstack/react-router'
|
|
3
|
-
import { createServerFn } from '@tanstack/react-start'
|
|
4
|
-
import { useState } from 'react'
|
|
5
|
-
import { ConfigTabs } from '../../components/ConfigTabs'
|
|
6
|
-
import { daemonClient } from '../../lib/daemon-client'
|
|
7
|
-
|
|
8
|
-
const fetchTokens = createServerFn({ method: 'POST' })
|
|
9
|
-
.inputValidator((d: { all: boolean }) => d)
|
|
10
|
-
.handler(({ data }) =>
|
|
11
|
-
daemonClient().get<ListTokensResponse>(
|
|
12
|
-
`/api/tokens${data.all ? '?includeRevoked=1' : ''}`,
|
|
13
|
-
),
|
|
14
|
-
)
|
|
15
|
-
|
|
16
|
-
export const Route = createFileRoute('/config/tokens')({
|
|
17
|
-
validateSearch: (s: Record<string, unknown>): { all?: '1' } => ({
|
|
18
|
-
all: s.all === '1' ? '1' : undefined,
|
|
19
|
-
}),
|
|
20
|
-
loaderDeps: ({ search }) => ({ all: search.all === '1' }),
|
|
21
|
-
loader: ({ deps }) => fetchTokens({ data: deps }),
|
|
22
|
-
component: TokensPage,
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
function fmtTs(ts: number): string {
|
|
26
|
-
return new Date(ts).toISOString().slice(0, 16).replace('T', ' ')
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function TokensPage() {
|
|
30
|
-
const { tokens } = Route.useLoaderData()
|
|
31
|
-
const { all } = Route.useSearch()
|
|
32
|
-
const includeRevoked = all === '1'
|
|
33
|
-
const router = useRouter()
|
|
34
|
-
const [label, setLabel] = useState('')
|
|
35
|
-
const [created, setCreated] = useState<string | null>(null)
|
|
36
|
-
const [err, setErr] = useState<string | null>(null)
|
|
37
|
-
const [busy, setBusy] = useState(false)
|
|
38
|
-
|
|
39
|
-
async function mint(e: React.FormEvent) {
|
|
40
|
-
e.preventDefault()
|
|
41
|
-
setErr(null)
|
|
42
|
-
setBusy(true)
|
|
43
|
-
try {
|
|
44
|
-
const res = await fetch('/api/tokens', {
|
|
45
|
-
method: 'POST',
|
|
46
|
-
headers: { 'content-type': 'application/json' },
|
|
47
|
-
body: JSON.stringify({ label }),
|
|
48
|
-
})
|
|
49
|
-
if (!res.ok) {
|
|
50
|
-
const j = (await res.json().catch(() => ({}))) as { error?: string }
|
|
51
|
-
throw new Error(j.error ?? `${res.status} ${res.statusText}`)
|
|
52
|
-
}
|
|
53
|
-
const body = (await res.json()) as { token: string }
|
|
54
|
-
setCreated(body.token)
|
|
55
|
-
setLabel('')
|
|
56
|
-
await router.invalidate()
|
|
57
|
-
} catch (e) {
|
|
58
|
-
setErr((e as Error).message)
|
|
59
|
-
} finally {
|
|
60
|
-
setBusy(false)
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
async function revoke(id: string) {
|
|
65
|
-
await fetch(`/api/tokens/${id}`, { method: 'DELETE' })
|
|
66
|
-
await router.invalidate()
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return (
|
|
70
|
-
<main className="mx-auto max-w-5xl px-6 py-8">
|
|
71
|
-
<h1 className="font-serif text-3xl text-foreground mb-2">config</h1>
|
|
72
|
-
<ConfigTabs active="tokens" />
|
|
73
|
-
|
|
74
|
-
<p className="text-muted-foreground text-sm mb-6">
|
|
75
|
-
Per-client credentials for the HTTP API and CLI. The row labelled{' '}
|
|
76
|
-
<code className="font-mono">bootstrap</code> is the loopback token in{' '}
|
|
77
|
-
<code className="font-mono">~/.bazilion/auth.json</code> — revoking it locks the local
|
|
78
|
-
CLI out, so it can't be revoked from this page. Mint additional tokens here for
|
|
79
|
-
Tailscale/LAN clients (mobile, remote machines); revoke any of those at any time.
|
|
80
|
-
</p>
|
|
81
|
-
|
|
82
|
-
<section className="rounded-lg border bg-card p-5 mb-6">
|
|
83
|
-
<h3 className="font-serif text-xl mb-3">Mint a new token</h3>
|
|
84
|
-
<form onSubmit={mint} className="flex gap-2 items-end mb-3">
|
|
85
|
-
<label className="text-sm">
|
|
86
|
-
Label
|
|
87
|
-
<input
|
|
88
|
-
type="text"
|
|
89
|
-
value={label}
|
|
90
|
-
onChange={(e) => setLabel(e.target.value)}
|
|
91
|
-
required
|
|
92
|
-
placeholder="e.g. laptop-tailscale"
|
|
93
|
-
autoComplete="off"
|
|
94
|
-
className="block mt-1 rounded-md border bg-background px-3 py-2 text-sm w-72"
|
|
95
|
-
/>
|
|
96
|
-
</label>
|
|
97
|
-
<button
|
|
98
|
-
type="submit"
|
|
99
|
-
disabled={busy}
|
|
100
|
-
className="rounded-md bg-primary px-3 py-2 text-sm font-medium text-primary-foreground disabled:opacity-50"
|
|
101
|
-
>
|
|
102
|
-
{busy ? 'creating…' : 'create'}
|
|
103
|
-
</button>
|
|
104
|
-
</form>
|
|
105
|
-
{created && (
|
|
106
|
-
<div className="rounded-md border border-amber-200 bg-amber-50 p-3">
|
|
107
|
-
<p className="text-xs text-amber-800 mb-1">
|
|
108
|
-
copy this token now — it is not recoverable later.
|
|
109
|
-
</p>
|
|
110
|
-
<pre className="font-mono text-xs whitespace-pre-wrap break-all">{created}</pre>
|
|
111
|
-
</div>
|
|
112
|
-
)}
|
|
113
|
-
{err && <p className="text-sm text-rose-700">{err}</p>}
|
|
114
|
-
</section>
|
|
115
|
-
|
|
116
|
-
<div className="mb-3">
|
|
117
|
-
<label className="text-sm flex items-center gap-2">
|
|
118
|
-
<input
|
|
119
|
-
type="checkbox"
|
|
120
|
-
checked={includeRevoked}
|
|
121
|
-
onChange={(e) => {
|
|
122
|
-
window.location.assign(e.target.checked ? '/config/tokens?all=1' : '/config/tokens')
|
|
123
|
-
}}
|
|
124
|
-
/>
|
|
125
|
-
show revoked
|
|
126
|
-
</label>
|
|
127
|
-
</div>
|
|
128
|
-
|
|
129
|
-
<table className="w-full text-sm">
|
|
130
|
-
<thead className="text-left text-muted-foreground border-b">
|
|
131
|
-
<tr>
|
|
132
|
-
<th className="py-2">label</th>
|
|
133
|
-
<th>id</th>
|
|
134
|
-
<th>state</th>
|
|
135
|
-
<th>created</th>
|
|
136
|
-
<th>last used</th>
|
|
137
|
-
<th />
|
|
138
|
-
</tr>
|
|
139
|
-
</thead>
|
|
140
|
-
<tbody>
|
|
141
|
-
{tokens.length === 0 && (
|
|
142
|
-
<tr>
|
|
143
|
-
<td colSpan={6} className="py-6 text-center text-muted-foreground italic">
|
|
144
|
-
no tokens yet — mint one above
|
|
145
|
-
</td>
|
|
146
|
-
</tr>
|
|
147
|
-
)}
|
|
148
|
-
{tokens.map((t) => {
|
|
149
|
-
const isBootstrap = t.label === 'bootstrap'
|
|
150
|
-
return (
|
|
151
|
-
<tr key={t.id} className="border-b last:border-0 hover:bg-accent/30">
|
|
152
|
-
<td className="py-2">
|
|
153
|
-
{t.label}
|
|
154
|
-
{isBootstrap && (
|
|
155
|
-
<span className="ml-2 text-[0.7em] uppercase tracking-wide text-muted-foreground">
|
|
156
|
-
auth.json
|
|
157
|
-
</span>
|
|
158
|
-
)}
|
|
159
|
-
</td>
|
|
160
|
-
<td>
|
|
161
|
-
<code className="font-mono text-xs">{t.id}</code>
|
|
162
|
-
</td>
|
|
163
|
-
<td>
|
|
164
|
-
{t.revokedAt ? (
|
|
165
|
-
<span className="text-muted-foreground">revoked</span>
|
|
166
|
-
) : (
|
|
167
|
-
<span className="text-emerald-700">active</span>
|
|
168
|
-
)}
|
|
169
|
-
</td>
|
|
170
|
-
<td className="text-muted-foreground text-xs">{fmtTs(t.createdAt)}</td>
|
|
171
|
-
<td className="text-muted-foreground text-xs">
|
|
172
|
-
{t.lastUsedAt ? fmtTs(t.lastUsedAt) : '(never)'}
|
|
173
|
-
</td>
|
|
174
|
-
<td>
|
|
175
|
-
{!t.revokedAt && !isBootstrap && (
|
|
176
|
-
<button
|
|
177
|
-
type="button"
|
|
178
|
-
onClick={() => revoke(t.id)}
|
|
179
|
-
className="rounded-md border px-2 py-1 text-xs text-rose-700 hover:bg-rose-50"
|
|
180
|
-
>
|
|
181
|
-
revoke
|
|
182
|
-
</button>
|
|
183
|
-
)}
|
|
184
|
-
</td>
|
|
185
|
-
</tr>
|
|
186
|
-
)
|
|
187
|
-
})}
|
|
188
|
-
</tbody>
|
|
189
|
-
</table>
|
|
190
|
-
</main>
|
|
191
|
-
)
|
|
192
|
-
}
|