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.
Files changed (265) hide show
  1. package/README.md +53 -152
  2. package/dist/cli.js +2730 -0
  3. package/dist/cli.js.map +1 -0
  4. package/dist/daemon.js +6460 -0
  5. package/dist/daemon.js.map +1 -0
  6. package/dist/worker.js +2176 -0
  7. package/dist/worker.js.map +1 -0
  8. package/package.json +57 -28
  9. package/.understand-anything/.understandignore +0 -25
  10. package/.understand-anything/fingerprints.json +0 -14267
  11. package/.understand-anything/knowledge-graph.json +0 -18128
  12. package/.understand-anything/meta.json +0 -6
  13. package/CLAUDE.md +0 -164
  14. package/apps/cli/package.json +0 -21
  15. package/apps/cli/src/auth-file.ts +0 -18
  16. package/apps/cli/src/client.ts +0 -37
  17. package/apps/cli/src/columnize.ts +0 -32
  18. package/apps/cli/src/commands/agent.ts +0 -574
  19. package/apps/cli/src/commands/auth.ts +0 -110
  20. package/apps/cli/src/commands/backup.ts +0 -135
  21. package/apps/cli/src/commands/completion.ts +0 -155
  22. package/apps/cli/src/commands/config.ts +0 -95
  23. package/apps/cli/src/commands/doctor.ts +0 -131
  24. package/apps/cli/src/commands/group.ts +0 -132
  25. package/apps/cli/src/commands/inbox.ts +0 -82
  26. package/apps/cli/src/commands/login.ts +0 -73
  27. package/apps/cli/src/commands/memory.ts +0 -106
  28. package/apps/cli/src/commands/profile.ts +0 -259
  29. package/apps/cli/src/commands/provider.ts +0 -170
  30. package/apps/cli/src/commands/send.ts +0 -24
  31. package/apps/cli/src/commands/serve.ts +0 -89
  32. package/apps/cli/src/commands/skill.ts +0 -120
  33. package/apps/cli/src/commands/token.ts +0 -148
  34. package/apps/cli/src/commands/trigger.ts +0 -129
  35. package/apps/cli/src/commands/uninstall.ts +0 -156
  36. package/apps/cli/src/index.ts +0 -196
  37. package/apps/cli/src/paths.ts +0 -12
  38. package/apps/cli/test/agent.test.ts +0 -213
  39. package/apps/cli/test/backup.test.ts +0 -95
  40. package/apps/cli/test/chat.test.ts +0 -539
  41. package/apps/cli/test/columnize.test.ts +0 -29
  42. package/apps/cli/test/completion.test.ts +0 -45
  43. package/apps/cli/test/config-page.test.ts +0 -151
  44. package/apps/cli/test/group.test.ts +0 -74
  45. package/apps/cli/test/helpers.ts +0 -70
  46. package/apps/cli/test/inbox-autodeliver.test.ts +0 -143
  47. package/apps/cli/test/inbox.test.ts +0 -147
  48. package/apps/cli/test/memory.test.ts +0 -69
  49. package/apps/cli/test/profile.test.ts +0 -110
  50. package/apps/cli/test/send.test.ts +0 -30
  51. package/apps/cli/test/server-fixture.ts +0 -212
  52. package/apps/cli/test/session-head.test.ts +0 -45
  53. package/apps/cli/test/skill.test.ts +0 -128
  54. package/apps/cli/test/token.test.ts +0 -109
  55. package/apps/cli/test/trigger.test.ts +0 -245
  56. package/apps/cli/tsconfig.json +0 -4
  57. package/apps/daemon/package.json +0 -31
  58. package/apps/daemon/src/app.ts +0 -41
  59. package/apps/daemon/src/core/agent/archive.ts +0 -8
  60. package/apps/daemon/src/core/agent/delete.ts +0 -30
  61. package/apps/daemon/src/core/agent/resolve.ts +0 -31
  62. package/apps/daemon/src/core/agent/spawn.ts +0 -95
  63. package/apps/daemon/src/core/agent/unarchive.ts +0 -11
  64. package/apps/daemon/src/core/availableModels.ts +0 -58
  65. package/apps/daemon/src/core/db/client.ts +0 -113
  66. package/apps/daemon/src/core/db/migrate.ts +0 -41
  67. package/apps/daemon/src/core/db/migrations/0001_init.sql +0 -179
  68. package/apps/daemon/src/core/group/delete.ts +0 -21
  69. package/apps/daemon/src/core/group/register.ts +0 -68
  70. package/apps/daemon/src/core/index.ts +0 -71
  71. package/apps/daemon/src/core/paths.ts +0 -56
  72. package/apps/daemon/src/core/profile/create.ts +0 -78
  73. package/apps/daemon/src/core/profile/delete.ts +0 -26
  74. package/apps/daemon/src/core/profile/identity.ts +0 -70
  75. package/apps/daemon/src/core/profile/load.ts +0 -45
  76. package/apps/daemon/src/core/profile/seed.ts +0 -74
  77. package/apps/daemon/src/core/profile/templates.ts +0 -60
  78. package/apps/daemon/src/core/profile/update.ts +0 -57
  79. package/apps/daemon/src/core/profile/validate.ts +0 -9
  80. package/apps/daemon/src/core/repos/agents.ts +0 -202
  81. package/apps/daemon/src/core/repos/config.ts +0 -78
  82. package/apps/daemon/src/core/repos/groups.ts +0 -55
  83. package/apps/daemon/src/core/repos/messages.ts +0 -127
  84. package/apps/daemon/src/core/repos/profiles.ts +0 -83
  85. package/apps/daemon/src/core/repos/providerModels.ts +0 -58
  86. package/apps/daemon/src/core/repos/providerState.ts +0 -37
  87. package/apps/daemon/src/core/repos/secrets.ts +0 -145
  88. package/apps/daemon/src/core/repos/skillMeta.ts +0 -49
  89. package/apps/daemon/src/core/repos/triggers.ts +0 -101
  90. package/apps/daemon/src/core/repos/webTokens.ts +0 -87
  91. package/apps/daemon/src/core/secrets.ts +0 -65
  92. package/apps/daemon/src/core/services.ts +0 -264
  93. package/apps/daemon/src/core/skills/discover.ts +0 -28
  94. package/apps/daemon/src/core/skills/import.ts +0 -136
  95. package/apps/daemon/src/core/skills/parse.ts +0 -52
  96. package/apps/daemon/src/core/skills/resolve.ts +0 -50
  97. package/apps/daemon/src/index.ts +0 -45
  98. package/apps/daemon/src/lib/agent-cancel.ts +0 -48
  99. package/apps/daemon/src/lib/agent-id.ts +0 -13
  100. package/apps/daemon/src/lib/agent-turn.ts +0 -56
  101. package/apps/daemon/src/lib/api-key.ts +0 -56
  102. package/apps/daemon/src/lib/auth.ts +0 -41
  103. package/apps/daemon/src/lib/cron.ts +0 -93
  104. package/apps/daemon/src/lib/ctx.ts +0 -80
  105. package/apps/daemon/src/lib/messaging-host.ts +0 -34
  106. package/apps/daemon/src/lib/middleware-auth.ts +0 -52
  107. package/apps/daemon/src/lib/scheduler.ts +0 -294
  108. package/apps/daemon/src/routes/agents.ts +0 -772
  109. package/apps/daemon/src/routes/auth-login.ts +0 -193
  110. package/apps/daemon/src/routes/config.ts +0 -267
  111. package/apps/daemon/src/routes/groups.ts +0 -133
  112. package/apps/daemon/src/routes/messages.ts +0 -29
  113. package/apps/daemon/src/routes/misc.ts +0 -239
  114. package/apps/daemon/src/routes/profiles.ts +0 -197
  115. package/apps/daemon/src/routes/skills.ts +0 -123
  116. package/apps/daemon/src/routes/triggers.ts +0 -29
  117. package/apps/daemon/src/runtime/auth/openai-codex.ts +0 -121
  118. package/apps/daemon/src/runtime/auto-reply/heartbeat.ts +0 -31
  119. package/apps/daemon/src/runtime/index.ts +0 -77
  120. package/apps/daemon/src/runtime/memory/files.ts +0 -103
  121. package/apps/daemon/src/runtime/memory/qmd.ts +0 -152
  122. package/apps/daemon/src/runtime/memory/types.ts +0 -16
  123. package/apps/daemon/src/runtime/pi/events.ts +0 -173
  124. package/apps/daemon/src/runtime/pi/session.ts +0 -536
  125. package/apps/daemon/src/runtime/pi/tools.ts +0 -85
  126. package/apps/daemon/src/runtime/providers/catalog.ts +0 -145
  127. package/apps/daemon/src/runtime/providers/pi-adapter.ts +0 -272
  128. package/apps/daemon/src/runtime/providers/registry.ts +0 -374
  129. package/apps/daemon/src/runtime/providers/retry.ts +0 -176
  130. package/apps/daemon/src/runtime/providers/types.ts +0 -33
  131. package/apps/daemon/src/runtime/session/prompt.ts +0 -83
  132. package/apps/daemon/src/runtime/tools/bootstrap.ts +0 -22
  133. package/apps/daemon/src/runtime/tools/home.ts +0 -114
  134. package/apps/daemon/src/runtime/tools/memory.ts +0 -81
  135. package/apps/daemon/src/runtime/tools/messaging.ts +0 -127
  136. package/apps/daemon/src/runtime/tools/registry.ts +0 -29
  137. package/apps/daemon/src/runtime/tools/types.ts +0 -13
  138. package/apps/daemon/src/runtime/tools/web-extract.ts +0 -110
  139. package/apps/daemon/src/runtime/tools/web-ssrf.ts +0 -245
  140. package/apps/daemon/src/runtime/tools/web.ts +0 -273
  141. package/apps/daemon/src/runtime/worker/entry.ts +0 -221
  142. package/apps/daemon/src/runtime/worker/ipc-protocol.ts +0 -75
  143. package/apps/daemon/src/runtime/worker/spawn.ts +0 -249
  144. package/apps/daemon/test/core/agents.test.ts +0 -319
  145. package/apps/daemon/test/core/available-models.test.ts +0 -63
  146. package/apps/daemon/test/core/config.test.ts +0 -99
  147. package/apps/daemon/test/core/groups.test.ts +0 -63
  148. package/apps/daemon/test/core/helpers.ts +0 -50
  149. package/apps/daemon/test/core/identity.test.ts +0 -85
  150. package/apps/daemon/test/core/migrations.test.ts +0 -83
  151. package/apps/daemon/test/core/profiles.test.ts +0 -182
  152. package/apps/daemon/test/core/provider-models.test.ts +0 -57
  153. package/apps/daemon/test/core/provider-state.test.ts +0 -36
  154. package/apps/daemon/test/core/skill-meta.test.ts +0 -45
  155. package/apps/daemon/test/core/skills.test.ts +0 -271
  156. package/apps/daemon/test/core/triggers.test.ts +0 -182
  157. package/apps/daemon/test/core/web-tokens.test.ts +0 -79
  158. package/apps/daemon/test/cron.test.ts +0 -90
  159. package/apps/daemon/test/runtime/heartbeat.test.ts +0 -34
  160. package/apps/daemon/test/runtime/memory-qmd.test.ts +0 -97
  161. package/apps/daemon/test/runtime/memory.test.ts +0 -78
  162. package/apps/daemon/test/runtime/messaging.test.ts +0 -213
  163. package/apps/daemon/test/runtime/mock-server.ts +0 -65
  164. package/apps/daemon/test/runtime/openai-codex-auth.test.ts +0 -116
  165. package/apps/daemon/test/runtime/providers.test.ts +0 -306
  166. package/apps/daemon/test/runtime/retry.test.ts +0 -191
  167. package/apps/daemon/test/runtime/session-head.test.ts +0 -90
  168. package/apps/daemon/test/runtime/tools-home.test.ts +0 -102
  169. package/apps/daemon/test/runtime/tools-web.test.ts +0 -206
  170. package/apps/daemon/tsconfig.json +0 -4
  171. package/apps/mobile/README.md +0 -60
  172. package/apps/mobile/app/_layout.tsx +0 -58
  173. package/apps/mobile/app/agents/[id]/chat.tsx +0 -486
  174. package/apps/mobile/app/agents/[id]/index.tsx +0 -166
  175. package/apps/mobile/app/agents/index.tsx +0 -212
  176. package/apps/mobile/app/index.tsx +0 -21
  177. package/apps/mobile/app/pair.tsx +0 -226
  178. package/apps/mobile/app/settings.tsx +0 -419
  179. package/apps/mobile/app.json +0 -49
  180. package/apps/mobile/assets/adaptive-icon.png +0 -0
  181. package/apps/mobile/assets/favicon.png +0 -0
  182. package/apps/mobile/assets/icon.png +0 -0
  183. package/apps/mobile/assets/splash-icon.png +0 -0
  184. package/apps/mobile/babel.config.js +0 -6
  185. package/apps/mobile/metro.config.js +0 -28
  186. package/apps/mobile/package.json +0 -44
  187. package/apps/mobile/src/auth.ts +0 -66
  188. package/apps/mobile/src/pair-url.ts +0 -48
  189. package/apps/mobile/src/theme-context.tsx +0 -88
  190. package/apps/mobile/src/theme.ts +0 -135
  191. package/apps/mobile/test/pair-url.test.ts +0 -46
  192. package/apps/mobile/tsconfig.json +0 -23
  193. package/apps/web/components.json +0 -25
  194. package/apps/web/package.json +0 -39
  195. package/apps/web/public/baziu.svg +0 -8
  196. package/apps/web/src/components/AgentTabs.tsx +0 -45
  197. package/apps/web/src/components/BaziuLogo.tsx +0 -21
  198. package/apps/web/src/components/ChatPane.tsx +0 -1033
  199. package/apps/web/src/components/ConfigTabs.tsx +0 -29
  200. package/apps/web/src/components/CopyButton.tsx +0 -68
  201. package/apps/web/src/components/CreateGroupDialog.tsx +0 -127
  202. package/apps/web/src/components/FieldRow.tsx +0 -94
  203. package/apps/web/src/components/Footer.tsx +0 -10
  204. package/apps/web/src/components/PawIcon.tsx +0 -15
  205. package/apps/web/src/components/Sidebar.tsx +0 -287
  206. package/apps/web/src/components/SpawnDialog.tsx +0 -129
  207. package/apps/web/src/components/ThemeToggle.tsx +0 -75
  208. package/apps/web/src/components/TopNav.tsx +0 -34
  209. package/apps/web/src/components/ui/button.tsx +0 -67
  210. package/apps/web/src/components/ui/card.tsx +0 -103
  211. package/apps/web/src/components/ui/checkbox.tsx +0 -31
  212. package/apps/web/src/components/ui/dialog.tsx +0 -168
  213. package/apps/web/src/components/ui/input.tsx +0 -19
  214. package/apps/web/src/components/ui/label.tsx +0 -22
  215. package/apps/web/src/components/ui/radio-group.tsx +0 -44
  216. package/apps/web/src/components/ui/select.tsx +0 -192
  217. package/apps/web/src/components/ui/separator.tsx +0 -26
  218. package/apps/web/src/components/ui/table.tsx +0 -116
  219. package/apps/web/src/components/ui/tabs.tsx +0 -88
  220. package/apps/web/src/components/ui/textarea.tsx +0 -18
  221. package/apps/web/src/lib/auth.ts +0 -50
  222. package/apps/web/src/lib/daemon-client.ts +0 -34
  223. package/apps/web/src/lib/md.ts +0 -45
  224. package/apps/web/src/lib/utils.ts +0 -6
  225. package/apps/web/src/lib/wire-constants.ts +0 -27
  226. package/apps/web/src/routeTree.gen.ts +0 -408
  227. package/apps/web/src/router.tsx +0 -20
  228. package/apps/web/src/routes/__root.tsx +0 -123
  229. package/apps/web/src/routes/agents/$id/inbox.tsx +0 -207
  230. package/apps/web/src/routes/agents/$id/index.tsx +0 -527
  231. package/apps/web/src/routes/agents/$id/triggers.tsx +0 -239
  232. package/apps/web/src/routes/agents/index.tsx +0 -265
  233. package/apps/web/src/routes/api/$.ts +0 -88
  234. package/apps/web/src/routes/config/index.tsx +0 -315
  235. package/apps/web/src/routes/config/services.tsx +0 -49
  236. package/apps/web/src/routes/config/tokens.tsx +0 -192
  237. package/apps/web/src/routes/groups/$id/index.tsx +0 -153
  238. package/apps/web/src/routes/groups/$id/memory.tsx +0 -321
  239. package/apps/web/src/routes/groups/index.tsx +0 -191
  240. package/apps/web/src/routes/index.tsx +0 -133
  241. package/apps/web/src/routes/login.tsx +0 -63
  242. package/apps/web/src/routes/profiles/$id.tsx +0 -549
  243. package/apps/web/src/routes/profiles/index.tsx +0 -458
  244. package/apps/web/src/routes/skills/index.tsx +0 -297
  245. package/apps/web/src/routes/welcome.tsx +0 -61
  246. package/apps/web/src/styles.css +0 -449
  247. package/apps/web/tsconfig.json +0 -25
  248. package/apps/web/vite.config.ts +0 -25
  249. package/biome.json +0 -23
  250. package/docs/agent-engine.md +0 -219
  251. package/docs/architecture.md +0 -627
  252. package/docs/backlog/README.md +0 -42
  253. package/docs/backlog/draft/BAZ-001-a2a-federation-spike.md +0 -125
  254. package/docs/openclaw-reference.md +0 -210
  255. package/packages/api-types/package.json +0 -11
  256. package/packages/api-types/src/entities.ts +0 -146
  257. package/packages/api-types/src/events.ts +0 -55
  258. package/packages/api-types/src/index.ts +0 -488
  259. package/packages/api-types/src/memory.ts +0 -15
  260. package/packages/client/package.json +0 -13
  261. package/packages/client/src/index.ts +0 -117
  262. package/pnpm-workspace.yaml +0 -3
  263. package/tsconfig.base.json +0 -23
  264. package/tsconfig.json +0 -11
  265. package/vitest.config.ts +0 -22
@@ -1,374 +0,0 @@
1
- import type { BazilionDb } from '../../core/index.ts'
2
- import {
3
- hasCredentials as hasOpenAICodexCredentials,
4
- loadAccessToken as loadOpenAICodexAccessToken,
5
- } from '../auth/openai-codex.ts'
6
- import { piProvider } from './pi-adapter.ts'
7
- import { type RetryOptions, withRetry } from './retry.ts'
8
- import type { Provider } from './types.ts'
9
-
10
- export interface ProviderConfig {
11
- anthropic?: { apiKey: string; baseURL?: string }
12
- openai?: { apiKey: string; baseURL?: string }
13
- /** ChatGPT/Codex OAuth. The apiKey is fetched+refreshed lazily from secrets. */
14
- openaiCodex?: { db: BazilionDb; authToken: string }
15
- google?: { apiKey: string; baseURL?: string }
16
- azureOpenai?: { apiKey: string; baseURL?: string }
17
- bedrock?: { apiKey?: string } // auth via AWS SDK env (AWS_PROFILE / AWS_ACCESS_KEY_ID / ...)
18
- googleVertex?: Record<string, never> // auth via ADC + GOOGLE_CLOUD_PROJECT
19
- mistral?: { apiKey: string; baseURL?: string }
20
- groq?: { apiKey: string; baseURL?: string }
21
- cerebras?: { apiKey: string; baseURL?: string }
22
- xai?: { apiKey: string; baseURL?: string }
23
- zai?: { apiKey: string; baseURL?: string }
24
- huggingface?: { apiKey: string; baseURL?: string }
25
- openrouter?: { apiKey: string; baseURL?: string }
26
- vercelAiGateway?: { apiKey: string; baseURL?: string }
27
- lmstudio?: { baseURL?: string; apiKey?: string }
28
- ollama?: { baseURL?: string; apiKey?: string }
29
- }
30
-
31
- export interface ResolvedModel {
32
- provider: Provider
33
- model: string
34
- }
35
-
36
- /**
37
- * Env var → provider config. Empty / missing vars leave that provider unconfigured.
38
- *
39
- * Pass `oauth` (the daemon's `{db, authToken}` pair) to also pick up
40
- * OAuth-backed providers whose credentials live in the `secrets` table
41
- * (currently: `openai-codex` / ChatGPT). Env-only callers can omit it —
42
- * those providers just won't be configured.
43
- */
44
- export function loadProviderConfigFromEnv(
45
- env: NodeJS.ProcessEnv = process.env,
46
- oauth?: { db: BazilionDb; authToken: string },
47
- ): ProviderConfig {
48
- const config: ProviderConfig = {
49
- lmstudio: {
50
- ...(env.LMSTUDIO_URL !== undefined ? { baseURL: env.LMSTUDIO_URL } : {}),
51
- ...(env.LMSTUDIO_API_KEY !== undefined ? { apiKey: env.LMSTUDIO_API_KEY } : {}),
52
- },
53
- ollama: {
54
- ...(env.OLLAMA_URL !== undefined ? { baseURL: env.OLLAMA_URL } : {}),
55
- ...(env.OLLAMA_API_KEY !== undefined ? { apiKey: env.OLLAMA_API_KEY } : {}),
56
- },
57
- }
58
- if (env.ANTHROPIC_API_KEY || env.ANTHROPIC_OAUTH_TOKEN) {
59
- config.anthropic = { apiKey: env.ANTHROPIC_OAUTH_TOKEN ?? env.ANTHROPIC_API_KEY ?? '' }
60
- }
61
- if (env.OPENAI_API_KEY) config.openai = { apiKey: env.OPENAI_API_KEY }
62
- if (env.GEMINI_API_KEY) config.google = { apiKey: env.GEMINI_API_KEY }
63
- if (env.AZURE_OPENAI_API_KEY) config.azureOpenai = { apiKey: env.AZURE_OPENAI_API_KEY }
64
- if (
65
- env.AWS_PROFILE ||
66
- env.AWS_BEARER_TOKEN_BEDROCK ||
67
- (env.AWS_ACCESS_KEY_ID && env.AWS_SECRET_ACCESS_KEY)
68
- ) {
69
- config.bedrock = {}
70
- }
71
- if (env.GOOGLE_CLOUD_PROJECT && env.GOOGLE_CLOUD_LOCATION) {
72
- config.googleVertex = {}
73
- }
74
- if (env.MISTRAL_API_KEY) config.mistral = { apiKey: env.MISTRAL_API_KEY }
75
- if (env.GROQ_API_KEY) config.groq = { apiKey: env.GROQ_API_KEY }
76
- if (env.CEREBRAS_API_KEY) config.cerebras = { apiKey: env.CEREBRAS_API_KEY }
77
- if (env.XAI_API_KEY) config.xai = { apiKey: env.XAI_API_KEY }
78
- if (env.ZAI_API_KEY) config.zai = { apiKey: env.ZAI_API_KEY }
79
- if (env.HF_TOKEN) config.huggingface = { apiKey: env.HF_TOKEN }
80
- if (env.OPENROUTER_API_KEY) config.openrouter = { apiKey: env.OPENROUTER_API_KEY }
81
- if (env.AI_GATEWAY_API_KEY) config.vercelAiGateway = { apiKey: env.AI_GATEWAY_API_KEY }
82
- if (oauth && hasOpenAICodexCredentials(oauth.db, oauth.authToken)) {
83
- config.openaiCodex = oauth
84
- }
85
- return config
86
- }
87
-
88
- export interface ProviderRegistry {
89
- resolve(modelString: string): ResolvedModel
90
- list(): string[]
91
- }
92
-
93
- export interface ProviderRegistryOptions {
94
- /** If provided, resolve() refuses any provider not in the set with "disabled by admin". */
95
- enabledSet?: ReadonlySet<string>
96
- /** Retry policy applied uniformly to every provider; omit for built-in defaults. */
97
- retry?: RetryOptions
98
- }
99
-
100
- interface ProviderEntry {
101
- configured: (c: ProviderConfig) => boolean
102
- build: (c: ProviderConfig) => Provider
103
- /** Helpful error hint when the caller references this provider but env isn't set. */
104
- hint: string
105
- }
106
-
107
- const PROVIDERS: Record<string, ProviderEntry> = {
108
- anthropic: {
109
- configured: (c) => !!c.anthropic,
110
- build: (c) =>
111
- piProvider({
112
- providerName: 'anthropic',
113
- fallbackApi: 'anthropic-messages',
114
- apiKey: c.anthropic?.apiKey,
115
- baseUrl: c.anthropic?.baseURL,
116
- }),
117
- hint: 'ANTHROPIC_API_KEY or ANTHROPIC_OAUTH_TOKEN',
118
- },
119
- openai: {
120
- configured: (c) => !!c.openai,
121
- build: (c) =>
122
- piProvider({
123
- providerName: 'openai',
124
- fallbackApi: 'openai-completions',
125
- apiKey: c.openai?.apiKey,
126
- baseUrl: c.openai?.baseURL,
127
- }),
128
- hint: 'OPENAI_API_KEY',
129
- },
130
- 'openai-codex': {
131
- configured: (c) => !!c.openaiCodex,
132
- // Pi-ai's `openai-codex-responses` speaks the ChatGPT backend's Responses
133
- // API (https://chatgpt.com/backend-api) using a JWT access token as the
134
- // apiKey. We pass a supplier that refreshes lazily via the OAuth refresh
135
- // token, so the registry-cached Provider instance stays valid across
136
- // expiries without rebuild.
137
- build: (c) => {
138
- const openaiCodex = c.openaiCodex
139
- if (!openaiCodex) throw new Error('openai-codex not configured')
140
- return piProvider({
141
- providerName: 'openai-codex',
142
- fallbackApi: 'openai-codex-responses',
143
- apiKey: () => loadOpenAICodexAccessToken(openaiCodex.db, openaiCodex.authToken),
144
- })
145
- },
146
- hint: 'run `bazilion auth openai login` (or click Connect on /config)',
147
- },
148
- google: {
149
- configured: (c) => !!c.google,
150
- build: (c) =>
151
- piProvider({
152
- providerName: 'google',
153
- fallbackApi: 'google-generative-ai',
154
- apiKey: c.google?.apiKey,
155
- baseUrl: c.google?.baseURL,
156
- }),
157
- hint: 'GEMINI_API_KEY',
158
- },
159
- 'google-vertex': {
160
- configured: (c) => !!c.googleVertex,
161
- build: () => piProvider({ providerName: 'google-vertex', fallbackApi: 'google-vertex' }),
162
- hint: 'GOOGLE_CLOUD_PROJECT + GOOGLE_CLOUD_LOCATION + ADC (gcloud auth)',
163
- },
164
- 'azure-openai': {
165
- configured: (c) => !!c.azureOpenai,
166
- build: (c) =>
167
- piProvider({
168
- providerName: 'azure-openai',
169
- fallbackApi: 'azure-openai-responses',
170
- apiKey: c.azureOpenai?.apiKey,
171
- baseUrl: c.azureOpenai?.baseURL,
172
- }),
173
- hint: 'AZURE_OPENAI_API_KEY',
174
- },
175
- bedrock: {
176
- configured: (c) => !!c.bedrock,
177
- build: () =>
178
- piProvider({
179
- providerName: 'bedrock',
180
- piProviderName: 'amazon-bedrock',
181
- fallbackApi: 'bedrock-converse-stream',
182
- }),
183
- hint: 'AWS_PROFILE or AWS_ACCESS_KEY_ID+AWS_SECRET_ACCESS_KEY',
184
- },
185
- mistral: {
186
- configured: (c) => !!c.mistral,
187
- build: (c) =>
188
- piProvider({
189
- providerName: 'mistral',
190
- fallbackApi: 'openai-completions',
191
- apiKey: c.mistral?.apiKey,
192
- baseUrl: c.mistral?.baseURL,
193
- }),
194
- hint: 'MISTRAL_API_KEY',
195
- },
196
- groq: {
197
- configured: (c) => !!c.groq,
198
- build: (c) =>
199
- piProvider({
200
- providerName: 'groq',
201
- fallbackApi: 'openai-completions',
202
- apiKey: c.groq?.apiKey,
203
- baseUrl: c.groq?.baseURL,
204
- }),
205
- hint: 'GROQ_API_KEY',
206
- },
207
- cerebras: {
208
- configured: (c) => !!c.cerebras,
209
- build: (c) =>
210
- piProvider({
211
- providerName: 'cerebras',
212
- fallbackApi: 'openai-completions',
213
- apiKey: c.cerebras?.apiKey,
214
- baseUrl: c.cerebras?.baseURL,
215
- }),
216
- hint: 'CEREBRAS_API_KEY',
217
- },
218
- xai: {
219
- configured: (c) => !!c.xai,
220
- build: (c) =>
221
- piProvider({
222
- providerName: 'xai',
223
- fallbackApi: 'openai-completions',
224
- apiKey: c.xai?.apiKey,
225
- baseUrl: c.xai?.baseURL,
226
- }),
227
- hint: 'XAI_API_KEY',
228
- },
229
- zai: {
230
- configured: (c) => !!c.zai,
231
- build: (c) =>
232
- piProvider({
233
- providerName: 'zai',
234
- fallbackApi: 'openai-completions',
235
- apiKey: c.zai?.apiKey,
236
- baseUrl: c.zai?.baseURL,
237
- }),
238
- hint: 'ZAI_API_KEY',
239
- },
240
- huggingface: {
241
- configured: (c) => !!c.huggingface,
242
- build: (c) =>
243
- piProvider({
244
- providerName: 'huggingface',
245
- fallbackApi: 'openai-completions',
246
- apiKey: c.huggingface?.apiKey,
247
- baseUrl: c.huggingface?.baseURL,
248
- }),
249
- hint: 'HF_TOKEN',
250
- },
251
- openrouter: {
252
- configured: (c) => !!c.openrouter,
253
- build: (c) =>
254
- piProvider({
255
- providerName: 'openrouter',
256
- fallbackApi: 'openai-completions',
257
- apiKey: c.openrouter?.apiKey,
258
- baseUrl: c.openrouter?.baseURL,
259
- }),
260
- hint: 'OPENROUTER_API_KEY',
261
- },
262
- 'vercel-ai-gateway': {
263
- configured: (c) => !!c.vercelAiGateway,
264
- build: (c) =>
265
- piProvider({
266
- providerName: 'vercel-ai-gateway',
267
- fallbackApi: 'openai-completions',
268
- apiKey: c.vercelAiGateway?.apiKey,
269
- baseUrl: c.vercelAiGateway?.baseURL,
270
- }),
271
- hint: 'AI_GATEWAY_API_KEY',
272
- },
273
- lmstudio: {
274
- configured: () => true,
275
- build: (c) =>
276
- piProvider({
277
- providerName: 'lmstudio',
278
- fallbackApi: 'openai-completions',
279
- apiKey: c.lmstudio?.apiKey ?? 'lm-studio',
280
- baseUrl: c.lmstudio?.baseURL ?? 'http://127.0.0.1:1234/v1',
281
- }),
282
- hint: 'LMSTUDIO_URL (default http://127.0.0.1:1234/v1)',
283
- },
284
- ollama: {
285
- configured: () => true,
286
- build: (c) =>
287
- piProvider({
288
- providerName: 'ollama',
289
- fallbackApi: 'openai-completions',
290
- apiKey: c.ollama?.apiKey ?? 'ollama',
291
- baseUrl: c.ollama?.baseURL ?? 'http://127.0.0.1:11434/v1',
292
- }),
293
- hint: 'OLLAMA_URL (default http://127.0.0.1:11434/v1)',
294
- },
295
- }
296
-
297
- /**
298
- * Model strings are `provider:model`, e.g.:
299
- * - `anthropic:claude-opus-4-6`
300
- * - `openai:gpt-4o`
301
- * - `google:gemini-2.0-flash-exp`
302
- * - `groq:llama-3.3-70b-versatile`
303
- * - `lmstudio:my-loaded-model`
304
- * - `ollama:llama2`
305
- */
306
- export function createProviderRegistry(
307
- config: ProviderConfig,
308
- opts: ProviderRegistryOptions = {},
309
- ): ProviderRegistry {
310
- const cache = new Map<string, Provider>()
311
- const enabledSet = opts.enabledSet
312
-
313
- function get(name: string): Provider {
314
- const cached = cache.get(name)
315
- if (cached) return cached
316
- const entry = PROVIDERS[name]
317
- if (!entry) throw new Error(`unknown provider: ${name}`)
318
- if (enabledSet && !enabledSet.has(name)) {
319
- throw new Error(`${name} provider is disabled — enable it on the /config page`)
320
- }
321
- if (!entry.configured(config)) {
322
- throw new Error(`${name} provider not configured (set ${entry.hint})`)
323
- }
324
- const raw = entry.build(config)
325
- const provider = withRetry(raw, {
326
- ...(opts.retry ?? {}),
327
- onRetry: (info) => {
328
- opts.retry?.onRetry?.(info)
329
- console.warn(
330
- `[provider/${name}] transient error on attempt ${info.attempt}, retrying in ${info.delayMs}ms: ${info.error.message.slice(0, 160)}`,
331
- )
332
- },
333
- })
334
- cache.set(name, provider)
335
- return provider
336
- }
337
-
338
- return {
339
- resolve(modelString: string): ResolvedModel {
340
- const idx = modelString.indexOf(':')
341
- if (idx === -1) {
342
- throw new Error(`invalid model string "${modelString}": expected "provider:model"`)
343
- }
344
- const providerName = modelString.slice(0, idx)
345
- const model = modelString.slice(idx + 1)
346
- return { provider: get(providerName), model }
347
- },
348
- list() {
349
- return Object.entries(PROVIDERS)
350
- .filter(([name, entry]) => {
351
- if (!entry.configured(config)) return false
352
- if (enabledSet && !enabledSet.has(name)) return false
353
- return true
354
- })
355
- .map(([name]) => name)
356
- },
357
- }
358
- }
359
-
360
- export interface ProviderMeta {
361
- name: string
362
- enabled: boolean
363
- /** Hint shown when the provider isn't configured — the env var(s) required. */
364
- envHint: string
365
- }
366
-
367
- /** List every provider the registry knows about, plus whether each is configured. */
368
- export function listAllProviders(config: ProviderConfig): ProviderMeta[] {
369
- return Object.entries(PROVIDERS).map(([name, entry]) => ({
370
- name,
371
- enabled: entry.configured(config),
372
- envHint: entry.hint,
373
- }))
374
- }
@@ -1,176 +0,0 @@
1
- // Transient-error retry wrapper for Provider.chat().
2
- //
3
- // Applied uniformly in `createProviderRegistry` so every provider (anthropic,
4
- // openai, openai-codex, lmstudio, ollama, …) gets the same retry policy. A
5
- // one-shot upstream 5xx or rate-limit shouldn't kill the agent's turn — the
6
- // runtime marks the run `failed` and the user is stuck re-sending the same
7
- // message by hand, which is hostile UX.
8
- //
9
- // What counts as retryable is a small allowlist (server 5xx, rate-limit, a
10
- // handful of network errnos). Auth errors, invalid-request errors, context
11
- // overflows, and user-triggered aborts bypass retry entirely — they won't
12
- // resolve by trying again and the fast failure is the right signal.
13
- //
14
- // One hard rule: if the underlying chat already streamed text back via
15
- // onDelta, we can't retry — a second attempt would emit duplicated text into
16
- // the UI. The wrapper detects this by shadowing onDelta and tracking whether
17
- // the callback fired.
18
-
19
- import type { Provider, ProviderRequest, ProviderResponse } from './types.ts'
20
-
21
- export interface RetryOptions {
22
- /** How many *extra* attempts beyond the first. Default 2 → up to 3 tries total. */
23
- maxRetries?: number
24
- /** First backoff delay in ms. Doubles each retry up to maxDelayMs. Default 500. */
25
- initialDelayMs?: number
26
- /** Upper bound on a single backoff delay. Default 8000. */
27
- maxDelayMs?: number
28
- /** Optional callback invoked before each retry (for logging / telemetry). */
29
- onRetry?: (info: { attempt: number; delayMs: number; error: Error }) => void
30
- }
31
-
32
- /**
33
- * Lowercased substrings that mark an error as worth retrying. Checked with a
34
- * simple `includes` so we don't need to parse the upstream JSON shapes.
35
- */
36
- const RETRYABLE_MARKERS: readonly string[] = [
37
- 'server_error',
38
- 'internal_server',
39
- 'rate_limit',
40
- 'rate limit',
41
- 'too many requests',
42
- 'overloaded', // covers 'overloaded_error' (Anthropic)
43
- 'service_unavailable',
44
- 'service unavailable',
45
- 'gateway_timeout',
46
- 'gateway timeout',
47
- 'bad_gateway',
48
- 'bad gateway',
49
- 'econnreset',
50
- 'etimedout',
51
- 'econnrefused',
52
- 'enotfound',
53
- 'eai_again',
54
- 'socket hang up',
55
- 'fetch failed',
56
- 'network error',
57
- 'connection reset',
58
- 'status 429',
59
- 'status 500',
60
- 'status 502',
61
- 'status 503',
62
- 'status 504',
63
- '"status":429',
64
- '"status":500',
65
- '"status":502',
66
- '"status":503',
67
- '"status":504',
68
- ]
69
-
70
- /**
71
- * Non-retryable markers win over retryable ones — if an error mentions
72
- * authentication or a 4xx (other than 429), retrying won't help.
73
- */
74
- const NON_RETRYABLE_MARKERS: readonly string[] = [
75
- 'invalid_api_key',
76
- 'invalid api key',
77
- 'incorrect_api_key',
78
- 'authentication',
79
- 'unauthorized',
80
- 'permission_denied',
81
- 'permission denied',
82
- 'forbidden',
83
- 'invalid_request',
84
- 'invalid request',
85
- 'not_found',
86
- 'model_not_found',
87
- 'context_length_exceeded',
88
- 'context length',
89
- 'content_filter',
90
- 'quota_exceeded',
91
- 'insufficient_quota',
92
- 'billing',
93
- 'status 400',
94
- 'status 401',
95
- 'status 403',
96
- 'status 404',
97
- 'status 422',
98
- ]
99
-
100
- export function isRetryableError(err: unknown): boolean {
101
- const raw = err instanceof Error ? err.message : typeof err === 'string' ? err : String(err)
102
- const msg = raw.toLowerCase()
103
- for (const deny of NON_RETRYABLE_MARKERS) {
104
- if (msg.includes(deny)) return false
105
- }
106
- for (const allow of RETRYABLE_MARKERS) {
107
- if (msg.includes(allow)) return true
108
- }
109
- return false
110
- }
111
-
112
- function sleepWithAbort(ms: number, signal?: AbortSignal): Promise<void> {
113
- return new Promise((resolve, reject) => {
114
- if (signal?.aborted) {
115
- reject(new Error('aborted'))
116
- return
117
- }
118
- const t = setTimeout(() => {
119
- if (signal) signal.removeEventListener('abort', onAbort)
120
- resolve()
121
- }, ms)
122
- const onAbort = () => {
123
- clearTimeout(t)
124
- reject(new Error('aborted'))
125
- }
126
- signal?.addEventListener('abort', onAbort, { once: true })
127
- })
128
- }
129
-
130
- export function withRetry(provider: Provider, opts: RetryOptions = {}): Provider {
131
- const maxRetries = opts.maxRetries ?? 2
132
- const initialDelayMs = opts.initialDelayMs ?? 500
133
- const maxDelayMs = opts.maxDelayMs ?? 8_000
134
-
135
- return {
136
- name: provider.name,
137
- async chat(req: ProviderRequest): Promise<ProviderResponse> {
138
- let attempt = 0
139
- // Use `let` so each retry gets a fresh shadow; we need to know whether
140
- // onDelta fired on the *most recent* attempt.
141
- let lastError: Error | null = null
142
- while (true) {
143
- let streamed = false
144
- const wrappedReq: ProviderRequest = req.onDelta
145
- ? {
146
- ...req,
147
- onDelta: (delta: string) => {
148
- streamed = true
149
- req.onDelta?.(delta)
150
- },
151
- }
152
- : req
153
- try {
154
- return await provider.chat(wrappedReq)
155
- } catch (err) {
156
- lastError = err instanceof Error ? err : new Error(String(err))
157
- if (req.signal?.aborted) throw lastError
158
- if (streamed) throw lastError
159
- if (attempt >= maxRetries) throw lastError
160
- if (!isRetryableError(lastError)) throw lastError
161
- const delayMs = Math.min(initialDelayMs * 2 ** attempt, maxDelayMs)
162
- opts.onRetry?.({ attempt: attempt + 1, delayMs, error: lastError })
163
- try {
164
- await sleepWithAbort(delayMs, req.signal)
165
- } catch {
166
- // Aborted during backoff — surface the original provider error
167
- // rather than the synthetic abort so the run's failure reason
168
- // still points at what actually went wrong.
169
- throw lastError
170
- }
171
- attempt++
172
- }
173
- }
174
- },
175
- }
176
- }
@@ -1,33 +0,0 @@
1
- import type { ProviderMessage, ReasoningLevel, ToolCall, ToolDef } from '@bazilion/api-types'
2
-
3
- export interface ProviderRequest {
4
- model: string
5
- system?: string
6
- messages: ProviderMessage[]
7
- tools?: ToolDef[]
8
- temperature?: number
9
- maxTokens?: number
10
- /** Reasoning/thinking level — only honored by providers/models that support it. */
11
- reasoning?: ReasoningLevel
12
- /** Cancels the in-flight provider call. Providers forward it to fetch(). */
13
- signal?: AbortSignal
14
- /** Optional token-delta callback. Fires once per streamed text chunk as the response assembles. */
15
- onDelta?: (delta: string) => void
16
- }
17
-
18
- export type StopReason = 'stop' | 'tool_use' | 'length' | 'error'
19
-
20
- export interface ProviderResponse {
21
- content: string
22
- toolCalls: ToolCall[]
23
- stopReason: StopReason
24
- usage?: {
25
- promptTokens: number
26
- completionTokens: number
27
- }
28
- }
29
-
30
- export interface Provider {
31
- name: string
32
- chat(request: ProviderRequest): Promise<ProviderResponse>
33
- }
@@ -1,83 +0,0 @@
1
- // Bazilion system-prompt builder. Feeds pi's `getAppendSystemPrompt()` hook
2
- // so the agent sees its persona + skills + workspaces + memory guidance
3
- // stacked on top of pi's built-in base prompt (which lists coding tools and
4
- // general guidelines). Pure filesystem read — no LLM, no DB.
5
-
6
- import { existsSync, readFileSync } from 'node:fs'
7
- import { join } from 'node:path'
8
- import type { ResolvedAgent } from '@bazilion/api-types'
9
-
10
- // Prompt order: peers first (who else is around), then persona, then tooling
11
- // hints, then self-knowledge, then the wake-up playbook, then the one-shot
12
- // bootstrap intro.
13
- const CONTEXT_FILE_ORDER = [
14
- 'AGENTS.md',
15
- 'SOUL.md',
16
- 'TOOLS.md',
17
- 'IDENTITY.md',
18
- 'HEARTBEAT.md',
19
- 'BOOTSTRAP.md',
20
- ] as const
21
-
22
- export function buildSystemPrompt(agent: ResolvedAgent): string {
23
- const parts: string[] = []
24
-
25
- const contextBlocks: string[] = []
26
- let bootstrapPresent = false
27
- for (const file of CONTEXT_FILE_ORDER) {
28
- const path = join(agent.agent.dir, file)
29
- if (!existsSync(path)) continue
30
- const content = readFileSync(path, 'utf8').trimEnd()
31
- if (!content) continue
32
- contextBlocks.push(`## ${file}\n\n${content}`)
33
- if (file === 'BOOTSTRAP.md') bootstrapPresent = true
34
- }
35
- if (contextBlocks.length > 0) {
36
- parts.push(`# Project Context\n\n${contextBlocks.join('\n\n')}`)
37
- }
38
- if (bootstrapPresent) {
39
- parts.push(
40
- 'NOTE: This is your first session. After you have completed the bootstrap conversation, call the `bootstrap_done` tool to delete BOOTSTRAP.md.',
41
- )
42
- }
43
-
44
- parts.push(
45
- [
46
- '# Agent Home',
47
- '',
48
- 'Your private home holds who you are — identity, soul, behaviour rules, wake-up routine. It is not shared with other agents and cannot be overwritten by them. The files above (IDENTITY.md, SOUL.md, AGENTS.md, TOOLS.md, HEARTBEAT.md, BOOTSTRAP.md) live in this home.',
49
- '',
50
- '- To change who you are (name, vibe, personality, how you behave): use `home_write`.',
51
- '- To inspect exact wording of your own files: use `home_read` or `home_list`.',
52
- '- To remember facts the user told you or things you learned: use `memory_write` — NOT `home_write`.',
53
- '- To produce work output (code, docs, artefacts): use `write` / `edit` — those land in your workspace, not your home.',
54
- ].join('\n'),
55
- )
56
-
57
- if (agent.skills.length > 0) {
58
- parts.push(
59
- `# Available Skills\n\nYou have access to the following skills: ${agent.skills.join(', ')}.`,
60
- )
61
- }
62
-
63
- const groupLines = [
64
- '# Group',
65
- '',
66
- `- ${agent.group.id} (${agent.group.name}): ${agent.group.path}`,
67
- '',
68
- 'Your group is where work product lives — code, docs, artefacts, shared scratch. It may be shared with other agents in the same group. Your coding tools (`read`, `bash`, `edit`, `write`, `grep`, `find`, `ls`) are rooted at the group directory. Never use these tools to edit your identity/soul/behaviour files — those live in your home and are reached via `home_write` / `home_read`.',
69
- ]
70
- parts.push(groupLines.join('\n'))
71
-
72
- if (agent.group.userMd.trim()) {
73
- parts.push(
74
- `# About the User\n\nRead-only context about the human you're working with in this group. You cannot edit this — if it's wrong, say so and they will update it.\n\n${agent.group.userMd.trim()}`,
75
- )
76
- }
77
-
78
- parts.push(
79
- '# Memory\n\nYou share a persistent memory backend with every other agent in this group. Use `memory_write` to remember things across sessions, and `memory_search` / `memory_read` / `memory_list` to recall them. This memory is for project knowledge — codebase notes, decisions, things the user told you about the work. For personal notes about yourself (preferences, persona quirks), use `home_write` on IDENTITY.md instead. Always check memory at the start of a session: another agent in the group may have already learned something useful.',
80
- )
81
-
82
- return parts.join('\n\n---\n\n')
83
- }
@@ -1,22 +0,0 @@
1
- import { existsSync, rmSync } from 'node:fs'
2
- import { join } from 'node:path'
3
- import type { ToolHandler } from './types.ts'
4
-
5
- export function bootstrapTool(agentDir: string): ToolHandler {
6
- return {
7
- def: {
8
- name: 'bootstrap_done',
9
- description:
10
- 'Call this once you have finished your bootstrap conversation (introduced yourself, learned the user, updated IDENTITY.md). Removes BOOTSTRAP.md so it does not appear in future sessions.',
11
- parameters: { type: 'object', properties: {} },
12
- },
13
- async invoke() {
14
- const path = join(agentDir, 'BOOTSTRAP.md')
15
- if (existsSync(path)) {
16
- rmSync(path)
17
- return 'BOOTSTRAP.md removed. Bootstrap is complete.'
18
- }
19
- return 'BOOTSTRAP.md was already removed.'
20
- },
21
- }
22
- }