bazilion 0.0.0 → 0.1.1
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 +6460 -0
- package/dist/daemon.js.map +1 -0
- package/dist/worker.js +2176 -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,145 +0,0 @@
|
|
|
1
|
-
// Catalog lookup for config UI + CLI: "what models does provider X offer?"
|
|
2
|
-
//
|
|
3
|
-
// Two sources, merged and de-duplicated:
|
|
4
|
-
// 1. pi-ai's typed catalog (`getModels(provider)`) — static list of
|
|
5
|
-
// known cloud models with cost + context-window metadata, bundled with
|
|
6
|
-
// pi-ai. Works for the 10ish KnownProvider names; empty for local /
|
|
7
|
-
// alias providers (lmstudio, ollama, bedrock-via-our-alias).
|
|
8
|
-
// 2. For OpenAI-compat endpoints (lmstudio, ollama, openrouter,
|
|
9
|
-
// vercel-ai-gateway, openai with custom baseURL), we query
|
|
10
|
-
// `GET {baseURL}/models` and extract `data[].id`. This picks up
|
|
11
|
-
// newly released models, user-loaded local models, etc.
|
|
12
|
-
//
|
|
13
|
-
// `listCatalogModels(providerName)` returns the union. Errors from live
|
|
14
|
-
// fetches are surfaced so callers can show "couldn't reach lmstudio" rather
|
|
15
|
-
// than a silent empty list.
|
|
16
|
-
|
|
17
|
-
import { getModels as piGetModels } from '@mariozechner/pi-ai'
|
|
18
|
-
|
|
19
|
-
// piProviderName: what pi-ai's catalog indexes by. For bedrock we use the
|
|
20
|
-
// Bazilion-registry-key 'bedrock' externally but pi uses 'amazon-bedrock'.
|
|
21
|
-
const REGISTRY_TO_PI: Record<string, string> = {
|
|
22
|
-
bedrock: 'amazon-bedrock',
|
|
23
|
-
'azure-openai': 'azure-openai-responses',
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// baseURL for providers whose /v1/models we can probe. Omitted for the
|
|
27
|
-
// big cloud APIs that require a real key and generally aren't "explore me"
|
|
28
|
-
// — those come from the pi catalog. `process.env` reads pick up the same
|
|
29
|
-
// secrets/config merge the rest of the runtime uses.
|
|
30
|
-
function liveEndpointFor(providerName: string, env: NodeJS.ProcessEnv): string | null {
|
|
31
|
-
switch (providerName) {
|
|
32
|
-
case 'lmstudio':
|
|
33
|
-
return env.LMSTUDIO_URL ?? 'http://127.0.0.1:1234/v1'
|
|
34
|
-
case 'ollama':
|
|
35
|
-
// Ollama has its own /api/tags for model list; its OpenAI-compat /v1
|
|
36
|
-
// endpoint supports /models though, so use that.
|
|
37
|
-
return env.OLLAMA_URL ?? 'http://127.0.0.1:11434/v1'
|
|
38
|
-
case 'openrouter':
|
|
39
|
-
return 'https://openrouter.ai/api/v1'
|
|
40
|
-
case 'vercel-ai-gateway':
|
|
41
|
-
return env.AI_GATEWAY_BASE_URL ?? 'https://ai-gateway.vercel.sh/v1'
|
|
42
|
-
case 'groq':
|
|
43
|
-
return 'https://api.groq.com/openai/v1'
|
|
44
|
-
case 'cerebras':
|
|
45
|
-
return 'https://api.cerebras.ai/v1'
|
|
46
|
-
case 'xai':
|
|
47
|
-
return 'https://api.x.ai/v1'
|
|
48
|
-
case 'mistral':
|
|
49
|
-
return 'https://api.mistral.ai/v1'
|
|
50
|
-
default:
|
|
51
|
-
return null
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function piModels(providerName: string): string[] {
|
|
56
|
-
const piName = REGISTRY_TO_PI[providerName] ?? providerName
|
|
57
|
-
try {
|
|
58
|
-
const models = (piGetModels as unknown as (p: string) => { id: string }[] | undefined)(piName)
|
|
59
|
-
if (!models) return []
|
|
60
|
-
return models.map((m) => m.id)
|
|
61
|
-
} catch {
|
|
62
|
-
return []
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export interface LiveFetchResult {
|
|
67
|
-
models: string[]
|
|
68
|
-
/** Only populated on failure; caller renders for UX. */
|
|
69
|
-
error?: string
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
async function fetchModelsFrom(
|
|
73
|
-
baseURL: string,
|
|
74
|
-
apiKey: string | undefined,
|
|
75
|
-
signal?: AbortSignal,
|
|
76
|
-
): Promise<LiveFetchResult> {
|
|
77
|
-
try {
|
|
78
|
-
const headers: Record<string, string> = { accept: 'application/json' }
|
|
79
|
-
if (apiKey) headers.authorization = `Bearer ${apiKey}`
|
|
80
|
-
const res = await fetch(`${baseURL.replace(/\/$/, '')}/models`, { headers, signal })
|
|
81
|
-
if (!res.ok) return { models: [], error: `${res.status} ${res.statusText}` }
|
|
82
|
-
const body = (await res.json()) as { data?: Array<{ id?: string }> } | null
|
|
83
|
-
const ids = (body?.data ?? []).map((m) => m.id).filter((id): id is string => !!id)
|
|
84
|
-
return { models: ids }
|
|
85
|
-
} catch (err) {
|
|
86
|
-
return { models: [], error: (err as Error).message }
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function apiKeyFor(providerName: string, env: NodeJS.ProcessEnv): string | undefined {
|
|
91
|
-
switch (providerName) {
|
|
92
|
-
case 'lmstudio':
|
|
93
|
-
return env.LMSTUDIO_API_KEY ?? 'lm-studio'
|
|
94
|
-
case 'ollama':
|
|
95
|
-
return env.OLLAMA_API_KEY ?? 'ollama'
|
|
96
|
-
case 'openrouter':
|
|
97
|
-
return env.OPENROUTER_API_KEY
|
|
98
|
-
case 'vercel-ai-gateway':
|
|
99
|
-
return env.AI_GATEWAY_API_KEY
|
|
100
|
-
case 'groq':
|
|
101
|
-
return env.GROQ_API_KEY
|
|
102
|
-
case 'cerebras':
|
|
103
|
-
return env.CEREBRAS_API_KEY
|
|
104
|
-
case 'xai':
|
|
105
|
-
return env.XAI_API_KEY
|
|
106
|
-
case 'mistral':
|
|
107
|
-
return env.MISTRAL_API_KEY
|
|
108
|
-
default:
|
|
109
|
-
return undefined
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export interface CatalogResult {
|
|
114
|
-
/** Models from pi-ai's typed catalog — stable, no network. */
|
|
115
|
-
catalog: string[]
|
|
116
|
-
/** Live `/v1/models` query — populated only for openai-compat endpoints we know how to probe. */
|
|
117
|
-
live?: LiveFetchResult
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* List known models for a provider. Combines pi's static catalog with a live
|
|
122
|
-
* `/v1/models` query for endpoints that expose one. Returns both separately
|
|
123
|
-
* so the UI can surface which ones come from where.
|
|
124
|
-
*
|
|
125
|
-
* `live` is omitted (not just empty) when the provider doesn't expose a
|
|
126
|
-
* `/v1/models` endpoint — e.g. Anthropic or Bedrock. Those rely on the
|
|
127
|
-
* catalog only.
|
|
128
|
-
*/
|
|
129
|
-
export async function listCatalogModels(
|
|
130
|
-
providerName: string,
|
|
131
|
-
env: NodeJS.ProcessEnv = process.env,
|
|
132
|
-
signal?: AbortSignal,
|
|
133
|
-
): Promise<CatalogResult> {
|
|
134
|
-
const catalog = piModels(providerName)
|
|
135
|
-
const endpoint = liveEndpointFor(providerName, env)
|
|
136
|
-
if (!endpoint) return { catalog }
|
|
137
|
-
const key = apiKeyFor(providerName, env)
|
|
138
|
-
const live = await fetchModelsFrom(endpoint, key, signal)
|
|
139
|
-
return { catalog, live }
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/** Synchronous variant for contexts that only want the pi catalog slice. */
|
|
143
|
-
export function listCatalogModelsSync(providerName: string): string[] {
|
|
144
|
-
return piModels(providerName)
|
|
145
|
-
}
|
|
@@ -1,272 +0,0 @@
|
|
|
1
|
-
// Adapter from Bazilion's Provider interface → pi-ai's streamSimple.
|
|
2
|
-
//
|
|
3
|
-
// Pi-ai (`@mariozechner/pi-ai`) is Mario Zechner's unified LLM SDK — 15+
|
|
4
|
-
// providers behind one event-stream API. This file is the only place in the
|
|
5
|
-
// codebase that touches pi-ai directly; everything else downstream
|
|
6
|
-
// (`runTurnStream`, `persistRun`, the worker entry, CLI, web) sees the same
|
|
7
|
-
// `Provider.chat(ProviderRequest): Promise<ProviderResponse>` contract it
|
|
8
|
-
// always has. That keeps the wire format, DB schema, and chat UI stable while
|
|
9
|
-
// giving us cost/usage, thinking levels, prompt caching, and every provider
|
|
10
|
-
// pi supports — for free.
|
|
11
|
-
//
|
|
12
|
-
// Model resolution: we prefer pi's typed catalog via `getModel(provider, id)`
|
|
13
|
-
// which carries cost + context-window metadata; for anything outside the
|
|
14
|
-
// catalog (local models, newly-released models, custom OpenAI-compat
|
|
15
|
-
// endpoints) we construct a `Model<>` literal with sensible defaults. This
|
|
16
|
-
// preserves Bazilion's "any model string" flexibility.
|
|
17
|
-
|
|
18
|
-
import type { ProviderMessage, ReasoningLevel, ToolCall, ToolDef } from '@bazilion/api-types'
|
|
19
|
-
import {
|
|
20
|
-
type AssistantMessage,
|
|
21
|
-
getModel,
|
|
22
|
-
type Model,
|
|
23
|
-
type Message as PiMessage,
|
|
24
|
-
type Tool as PiTool,
|
|
25
|
-
type ToolCall as PiToolCall,
|
|
26
|
-
streamSimple,
|
|
27
|
-
type TextContent,
|
|
28
|
-
Type,
|
|
29
|
-
} from '@mariozechner/pi-ai'
|
|
30
|
-
import type { Provider, ProviderRequest, ProviderResponse, StopReason } from './types.ts'
|
|
31
|
-
|
|
32
|
-
export interface PiProviderConfig {
|
|
33
|
-
/** Display name on the returned Provider; also the registry key (e.g. 'bedrock', 'azure-openai'). */
|
|
34
|
-
providerName: string
|
|
35
|
-
/** Pi's canonical provider name for catalog lookup (e.g. 'amazon-bedrock', 'azure-openai-responses'). Defaults to providerName. */
|
|
36
|
-
piProviderName?: string
|
|
37
|
-
/** Override baseUrl for openai-compat endpoints (lmstudio, ollama, custom). */
|
|
38
|
-
baseUrl?: string
|
|
39
|
-
/**
|
|
40
|
-
* Static key or an async supplier. Suppliers are called at the top of each
|
|
41
|
-
* chat() so OAuth-backed providers can refresh expiring tokens without
|
|
42
|
-
* rebuilding the Provider instance (which the registry caches).
|
|
43
|
-
*/
|
|
44
|
-
apiKey?: string | (() => string | Promise<string>)
|
|
45
|
-
/** Which pi `Api` to use when the model isn't in pi's catalog. */
|
|
46
|
-
fallbackApi: string
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function defaultBaseUrlFor(providerName: string): string {
|
|
50
|
-
switch (providerName) {
|
|
51
|
-
case 'lmstudio':
|
|
52
|
-
return process.env.LMSTUDIO_URL ?? 'http://127.0.0.1:1234/v1'
|
|
53
|
-
case 'ollama':
|
|
54
|
-
return process.env.OLLAMA_URL ?? 'http://127.0.0.1:11434/v1'
|
|
55
|
-
default:
|
|
56
|
-
return ''
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function buildModelLiteral(cfg: PiProviderConfig, modelId: string): Model<string> {
|
|
61
|
-
return {
|
|
62
|
-
id: modelId,
|
|
63
|
-
name: modelId,
|
|
64
|
-
api: cfg.fallbackApi,
|
|
65
|
-
provider: cfg.providerName,
|
|
66
|
-
baseUrl: cfg.baseUrl ?? defaultBaseUrlFor(cfg.providerName),
|
|
67
|
-
reasoning: false,
|
|
68
|
-
input: ['text'],
|
|
69
|
-
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
70
|
-
contextWindow: 32_768,
|
|
71
|
-
maxTokens: 4_096,
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export function resolveModel(cfg: PiProviderConfig, modelId: string): Model<string> {
|
|
76
|
-
const lookupName = cfg.piProviderName ?? cfg.providerName
|
|
77
|
-
// Try pi's typed catalog first — gets us cost, context window, reasoning flags
|
|
78
|
-
// for free on the known providers' known models.
|
|
79
|
-
try {
|
|
80
|
-
// getModel's type signature is catalog-constrained, but at runtime it just
|
|
81
|
-
// indexes MODELS[provider][id]. Cast through unknown so unknown ids fall
|
|
82
|
-
// through to the literal builder instead of tripping the compiler.
|
|
83
|
-
const known = (getModel as unknown as (p: string, m: string) => Model<string> | undefined)(
|
|
84
|
-
lookupName,
|
|
85
|
-
modelId,
|
|
86
|
-
)
|
|
87
|
-
if (known && typeof known === 'object' && 'api' in known) {
|
|
88
|
-
// Override baseUrl + provider for local / compat endpoints — pi's catalog
|
|
89
|
-
// doesn't know about lmstudio/ollama but if a user types
|
|
90
|
-
// `openai:gpt-4o` with a custom OPENAI_BASE_URL, honor that here.
|
|
91
|
-
if (cfg.baseUrl) return { ...known, baseUrl: cfg.baseUrl }
|
|
92
|
-
return known
|
|
93
|
-
}
|
|
94
|
-
} catch {
|
|
95
|
-
// Fall through.
|
|
96
|
-
}
|
|
97
|
-
return buildModelLiteral(cfg, modelId)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function convertMessages(messages: ProviderMessage[]): PiMessage[] {
|
|
101
|
-
const out: PiMessage[] = []
|
|
102
|
-
const now = Date.now()
|
|
103
|
-
for (const m of messages) {
|
|
104
|
-
if (m.role === 'system') continue // pi takes system prompt separately
|
|
105
|
-
if (m.role === 'user') {
|
|
106
|
-
out.push({ role: 'user', content: m.content, timestamp: now })
|
|
107
|
-
continue
|
|
108
|
-
}
|
|
109
|
-
if (m.role === 'assistant') {
|
|
110
|
-
const content: AssistantMessage['content'] = []
|
|
111
|
-
if (m.content) content.push({ type: 'text', text: m.content } satisfies TextContent)
|
|
112
|
-
if (m.toolCalls) {
|
|
113
|
-
for (const tc of m.toolCalls) {
|
|
114
|
-
let parsed: Record<string, unknown> = {}
|
|
115
|
-
try {
|
|
116
|
-
parsed = JSON.parse(tc.arguments) as Record<string, unknown>
|
|
117
|
-
} catch {
|
|
118
|
-
// leave empty
|
|
119
|
-
}
|
|
120
|
-
content.push({
|
|
121
|
-
type: 'toolCall',
|
|
122
|
-
id: tc.id,
|
|
123
|
-
name: tc.name,
|
|
124
|
-
arguments: parsed,
|
|
125
|
-
} satisfies PiToolCall)
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
// Synthesize the AssistantMessage fields pi expects on replays — these
|
|
129
|
-
// are only load-bearing for the LLM that gets the transcript; since we
|
|
130
|
-
// don't persist usage/stopReason in Bazilion's message store, defaults
|
|
131
|
-
// are fine.
|
|
132
|
-
out.push({
|
|
133
|
-
role: 'assistant',
|
|
134
|
-
content,
|
|
135
|
-
api: 'anthropic-messages',
|
|
136
|
-
provider: 'anthropic',
|
|
137
|
-
model: 'unknown',
|
|
138
|
-
usage: {
|
|
139
|
-
input: 0,
|
|
140
|
-
output: 0,
|
|
141
|
-
cacheRead: 0,
|
|
142
|
-
cacheWrite: 0,
|
|
143
|
-
totalTokens: 0,
|
|
144
|
-
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
|
145
|
-
},
|
|
146
|
-
stopReason: 'stop',
|
|
147
|
-
timestamp: now,
|
|
148
|
-
})
|
|
149
|
-
continue
|
|
150
|
-
}
|
|
151
|
-
if (m.role === 'tool') {
|
|
152
|
-
out.push({
|
|
153
|
-
role: 'toolResult',
|
|
154
|
-
toolCallId: m.toolCallId ?? '',
|
|
155
|
-
toolName: m.toolName ?? 'tool',
|
|
156
|
-
content: [{ type: 'text', text: m.content }],
|
|
157
|
-
isError: false,
|
|
158
|
-
timestamp: now,
|
|
159
|
-
})
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
return out
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
function convertTools(tools: ToolDef[] | undefined): PiTool[] | undefined {
|
|
166
|
-
if (!tools || tools.length === 0) return undefined
|
|
167
|
-
return tools.map((t) => ({
|
|
168
|
-
name: t.name,
|
|
169
|
-
description: t.description,
|
|
170
|
-
// Type.Unsafe lets us pass raw JSON Schema through without re-authoring in
|
|
171
|
-
// typebox. Providers validate against the schema, not typebox's TSchema.
|
|
172
|
-
parameters: Type.Unsafe<unknown>(t.parameters as Record<string, unknown>),
|
|
173
|
-
}))
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
function toBazilionStopReason(reason: string): StopReason {
|
|
177
|
-
switch (reason) {
|
|
178
|
-
case 'stop':
|
|
179
|
-
return 'stop'
|
|
180
|
-
case 'length':
|
|
181
|
-
return 'length'
|
|
182
|
-
case 'toolUse':
|
|
183
|
-
return 'tool_use'
|
|
184
|
-
default:
|
|
185
|
-
return 'error'
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
function extractFinalResponse(msg: AssistantMessage): ProviderResponse {
|
|
190
|
-
let text = ''
|
|
191
|
-
const toolCalls: ToolCall[] = []
|
|
192
|
-
for (const block of msg.content) {
|
|
193
|
-
if (block.type === 'text') {
|
|
194
|
-
text += block.text
|
|
195
|
-
} else if (block.type === 'toolCall') {
|
|
196
|
-
toolCalls.push({
|
|
197
|
-
id: block.id,
|
|
198
|
-
name: block.name,
|
|
199
|
-
arguments: JSON.stringify(block.arguments ?? {}),
|
|
200
|
-
})
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
const res: ProviderResponse = {
|
|
204
|
-
content: text,
|
|
205
|
-
toolCalls,
|
|
206
|
-
stopReason: toBazilionStopReason(msg.stopReason),
|
|
207
|
-
}
|
|
208
|
-
if (msg.usage) {
|
|
209
|
-
res.usage = {
|
|
210
|
-
promptTokens: msg.usage.input,
|
|
211
|
-
completionTokens: msg.usage.output,
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
return res
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
function mapReasoning(
|
|
218
|
-
r: ReasoningLevel | undefined,
|
|
219
|
-
): 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | undefined {
|
|
220
|
-
if (!r || r === 'off') return undefined
|
|
221
|
-
return r
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
async function resolveApiKey(cfg: PiProviderConfig): Promise<string | undefined> {
|
|
225
|
-
if (typeof cfg.apiKey === 'function') return await cfg.apiKey()
|
|
226
|
-
return cfg.apiKey
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
export function piProvider(cfg: PiProviderConfig): Provider {
|
|
230
|
-
return {
|
|
231
|
-
name: cfg.providerName,
|
|
232
|
-
async chat(req: ProviderRequest): Promise<ProviderResponse> {
|
|
233
|
-
const model = resolveModel(cfg, req.model)
|
|
234
|
-
const apiKey = await resolveApiKey(cfg)
|
|
235
|
-
|
|
236
|
-
const stream = streamSimple(
|
|
237
|
-
model,
|
|
238
|
-
{
|
|
239
|
-
systemPrompt: req.system ?? '',
|
|
240
|
-
messages: convertMessages(req.messages),
|
|
241
|
-
tools: convertTools(req.tools),
|
|
242
|
-
},
|
|
243
|
-
{
|
|
244
|
-
signal: req.signal,
|
|
245
|
-
apiKey,
|
|
246
|
-
reasoning: mapReasoning(req.reasoning),
|
|
247
|
-
maxTokens: req.maxTokens,
|
|
248
|
-
temperature: req.temperature,
|
|
249
|
-
},
|
|
250
|
-
)
|
|
251
|
-
|
|
252
|
-
let finalMessage: AssistantMessage | null = null
|
|
253
|
-
for await (const event of stream) {
|
|
254
|
-
if (event.type === 'text_delta' && req.onDelta) {
|
|
255
|
-
req.onDelta(event.delta)
|
|
256
|
-
} else if (event.type === 'done') {
|
|
257
|
-
finalMessage = event.message
|
|
258
|
-
} else if (event.type === 'error') {
|
|
259
|
-
finalMessage = event.error
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
if (!finalMessage) {
|
|
263
|
-
throw new Error(`pi provider ${cfg.providerName} returned no terminal event`)
|
|
264
|
-
}
|
|
265
|
-
if (finalMessage.stopReason === 'aborted' || finalMessage.stopReason === 'error') {
|
|
266
|
-
const msg = finalMessage.errorMessage ?? 'provider error'
|
|
267
|
-
throw new Error(msg)
|
|
268
|
-
}
|
|
269
|
-
return extractFinalResponse(finalMessage)
|
|
270
|
-
},
|
|
271
|
-
}
|
|
272
|
-
}
|