luca 3.0.0 → 3.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.
Files changed (388) hide show
  1. package/.github/workflows/release.yaml +1 -0
  2. package/CLAUDE.md +10 -2
  3. package/README.md +130 -112
  4. package/assistants/codingAssistant/CORE.md +6 -1
  5. package/assistants/codingAssistant/hooks.ts +1 -1
  6. package/assistants/inkbot/hooks.ts +1 -1
  7. package/assistants/inkbot/tools.ts +1 -1
  8. package/bun.lock +264 -321
  9. package/commands/audit-docs.ts +2 -2
  10. package/commands/build-bootstrap.ts +2 -3
  11. package/commands/build-python-bridge.ts +2 -3
  12. package/commands/build-scaffolds.ts +2 -3
  13. package/commands/bundle-consumer-project.ts +521 -0
  14. package/commands/generate-api-docs.ts +2 -2
  15. package/commands/inkbot.ts +2 -2
  16. package/commands/release.ts +2 -2
  17. package/commands/social.ts +137 -0
  18. package/commands/try-all-challenges.ts +3 -3
  19. package/commands/try-challenge.ts +3 -3
  20. package/datasets/lora/agentic-loop-session-candidates.jsonl +91 -0
  21. package/datasets/lora/agentic-loop-session-curation-summary.json +123 -0
  22. package/datasets/lora/luca-session-candidates.jsonl +29 -0
  23. package/datasets/lora/luca-session-curation-summary.json +121 -0
  24. package/datasets/lora/review-batch-1.jsonl +30 -0
  25. package/datasets/lora/review-manifest.json +41 -0
  26. package/datasets/lora/review-queue.jsonl +120 -0
  27. package/datasets/lora/review-schema.json +134 -0
  28. package/datasets/lora/review-template.jsonl +2 -0
  29. package/datasets/lora/review-ui.html +725 -0
  30. package/dist/agi/container.server.d.ts +2 -2
  31. package/dist/agi/features/assistant.d.ts +2 -2
  32. package/dist/agi/features/assistants-manager.d.ts +1 -1
  33. package/dist/agi/features/autonomous-assistant.d.ts +1 -1
  34. package/dist/agi/features/browser-use.d.ts +1 -1
  35. package/dist/agi/features/claude-code.d.ts +1 -1
  36. package/dist/agi/features/conversation-history.d.ts +2 -2
  37. package/dist/agi/features/conversation.d.ts +1 -1
  38. package/dist/agi/features/docs-reader.d.ts +1 -1
  39. package/dist/agi/features/file-tools.d.ts +1 -1
  40. package/dist/agi/features/luca-coder.d.ts +1 -1
  41. package/dist/agi/features/openai-codex.d.ts +1 -1
  42. package/dist/agi/features/skills-library.d.ts +1 -1
  43. package/dist/clients/civitai/index.d.ts +4 -4
  44. package/dist/clients/client-template.d.ts +4 -4
  45. package/dist/clients/comfyui/index.d.ts +2 -2
  46. package/dist/clients/elevenlabs/index.d.ts +2 -2
  47. package/dist/clients/openai/index.d.ts +2 -2
  48. package/dist/clients/supabase/index.d.ts +3 -3
  49. package/dist/command.d.ts +1 -1
  50. package/dist/node/container.d.ts +1 -1
  51. package/dist/node/features/helpers.d.ts +3 -3
  52. package/dist/node/features/semantic-search.d.ts +1 -1
  53. package/dist/node/features/vm.d.ts +3 -3
  54. package/dist/node.d.ts +1 -1
  55. package/dist/scaffolds/generated.d.ts +1 -1
  56. package/dist/selector.d.ts +1 -1
  57. package/features/cipher-social.ts +493 -0
  58. package/index.html +217 -190
  59. package/luca.console.ts +1 -1
  60. package/package.json +7 -2
  61. package/public/index.html +217 -190
  62. package/public/slides-ai-native.html +1 -1
  63. package/public/slides-intro.html +2 -2
  64. package/scripts/curate-claude-sessions.ts +561 -0
  65. package/scripts/examples/ask-luca-expert.ts +1 -1
  66. package/scripts/examples/assistant-questions.ts +1 -1
  67. package/scripts/examples/excalidraw-expert.ts +1 -1
  68. package/scripts/examples/file-manager.ts +1 -1
  69. package/scripts/examples/ideas.ts +1 -1
  70. package/scripts/examples/interactive-chat.ts +1 -1
  71. package/scripts/examples/opening-a-web-browser.ts +1 -1
  72. package/scripts/examples/telegram-bot.ts +1 -1
  73. package/scripts/examples/using-assistant-with-mcp.ts +1 -1
  74. package/scripts/examples/using-claude-code.ts +1 -1
  75. package/scripts/examples/using-contentdb.ts +2 -2
  76. package/scripts/examples/using-conversations.ts +1 -1
  77. package/scripts/examples/using-disk-cache.ts +1 -1
  78. package/scripts/examples/using-docker-shell.ts +1 -1
  79. package/scripts/examples/using-elevenlabs.ts +1 -1
  80. package/scripts/examples/using-google-calendar.ts +1 -1
  81. package/scripts/examples/using-google-docs.ts +1 -1
  82. package/scripts/examples/using-google-drive.ts +1 -1
  83. package/scripts/examples/using-google-sheets.ts +1 -1
  84. package/scripts/examples/using-nlp.ts +1 -1
  85. package/scripts/examples/using-ollama.ts +1 -1
  86. package/scripts/examples/using-postgres.ts +1 -1
  87. package/scripts/examples/using-runpod.ts +1 -1
  88. package/scripts/examples/using-tts.ts +1 -1
  89. package/scripts/scaffold.ts +5 -5
  90. package/scripts/scratch.ts +1 -1
  91. package/scripts/test-assistant-hooks.ts +1 -1
  92. package/scripts/test-docs-reader.ts +1 -1
  93. package/src/agi/container.server.ts +6 -2
  94. package/src/agi/features/agent-memory.ts +25 -25
  95. package/src/agi/features/assistant.ts +34 -5
  96. package/src/agi/features/assistants-manager.ts +122 -6
  97. package/src/agi/features/autonomous-assistant.ts +1 -1
  98. package/src/agi/features/browser-use.ts +20 -1
  99. package/src/agi/features/claude-code.ts +51 -5
  100. package/src/agi/features/coding-tools.ts +1 -1
  101. package/src/agi/features/conversation-history.ts +181 -4
  102. package/src/agi/features/conversation.ts +186 -15
  103. package/src/agi/features/docs-reader.ts +2 -2
  104. package/src/agi/features/file-tools.ts +49 -2
  105. package/src/agi/features/luca-coder.ts +7 -5
  106. package/src/agi/features/mcp-bridge.ts +532 -0
  107. package/src/agi/features/openai-codex.ts +2 -2
  108. package/src/agi/features/skills-library.ts +131 -52
  109. package/src/agi/lib/token-counter.ts +80 -0
  110. package/src/bootstrap/generated.ts +56 -57
  111. package/src/browser.ts +1 -1
  112. package/src/cli/build-info.ts +2 -2
  113. package/src/cli/cli.ts +2 -2
  114. package/src/clients/civitai/index.ts +5 -5
  115. package/src/clients/client-template.ts +4 -4
  116. package/src/clients/comfyui/index.ts +4 -4
  117. package/src/clients/elevenlabs/index.ts +4 -4
  118. package/src/clients/openai/index.ts +7 -7
  119. package/src/clients/supabase/index.ts +4 -4
  120. package/src/clients/voicebox/index.ts +4 -4
  121. package/src/command.ts +2 -1
  122. package/src/commands/chat.ts +1 -0
  123. package/src/commands/eval.ts +2 -56
  124. package/src/commands/introspect.ts +1 -1
  125. package/src/commands/prompt.ts +41 -9
  126. package/src/container-describer.ts +8 -1
  127. package/src/container.ts +13 -0
  128. package/src/entity.ts +2 -2
  129. package/src/helper.ts +1 -1
  130. package/src/introspection/generated.agi.ts +29596 -27654
  131. package/src/introspection/generated.node.ts +20284 -19247
  132. package/src/introspection/generated.web.ts +605 -584
  133. package/src/introspection/scan.ts +11 -6
  134. package/src/node/container.ts +9 -1
  135. package/src/node/features/content-db.ts +39 -2
  136. package/src/node/features/display-result.ts +57 -0
  137. package/src/node/features/helpers.ts +46 -7
  138. package/src/node/features/python.ts +25 -19
  139. package/src/node/features/repl.ts +1 -1
  140. package/src/node/features/secure-shell.ts +11 -17
  141. package/src/node/features/semantic-search.ts +2 -2
  142. package/src/node/features/socket-repl.ts +336 -0
  143. package/src/node/features/telnyx-assistant-connector.ts +1206 -0
  144. package/src/node/features/transpiler.ts +2 -3
  145. package/src/node/features/ui.ts +5 -0
  146. package/src/node/features/vm.ts +20 -3
  147. package/src/node.ts +3 -3
  148. package/src/python/generated.ts +0 -1
  149. package/src/scaffolds/generated.ts +82 -83
  150. package/src/selector.ts +1 -1
  151. package/src/servers/express.ts +1 -1
  152. package/src/web/features/helpers.ts +22 -0
  153. package/tsconfig.json +12 -12
  154. package/docs/CLI.md +0 -335
  155. package/docs/CNAME +0 -1
  156. package/docs/README.md +0 -60
  157. package/docs/TABLE-OF-CONTENTS.md +0 -183
  158. package/docs/apis/clients/elevenlabs.md +0 -308
  159. package/docs/apis/clients/graph.md +0 -107
  160. package/docs/apis/clients/openai.md +0 -429
  161. package/docs/apis/clients/rest.md +0 -161
  162. package/docs/apis/clients/websocket.md +0 -174
  163. package/docs/apis/features/agi/assistant.md +0 -625
  164. package/docs/apis/features/agi/assistants-manager.md +0 -282
  165. package/docs/apis/features/agi/auto-assistant.md +0 -279
  166. package/docs/apis/features/agi/browser-use.md +0 -802
  167. package/docs/apis/features/agi/claude-code.md +0 -884
  168. package/docs/apis/features/agi/conversation-history.md +0 -364
  169. package/docs/apis/features/agi/conversation.md +0 -548
  170. package/docs/apis/features/agi/docs-reader.md +0 -99
  171. package/docs/apis/features/agi/file-tools.md +0 -163
  172. package/docs/apis/features/agi/luca-coder.md +0 -407
  173. package/docs/apis/features/agi/openai-codex.md +0 -396
  174. package/docs/apis/features/agi/openapi.md +0 -138
  175. package/docs/apis/features/agi/semantic-search.md +0 -387
  176. package/docs/apis/features/agi/skills-library.md +0 -239
  177. package/docs/apis/features/node/container-link.md +0 -192
  178. package/docs/apis/features/node/content-db.md +0 -450
  179. package/docs/apis/features/node/disk-cache.md +0 -379
  180. package/docs/apis/features/node/dns.md +0 -652
  181. package/docs/apis/features/node/docker.md +0 -706
  182. package/docs/apis/features/node/downloader.md +0 -81
  183. package/docs/apis/features/node/esbuild.md +0 -60
  184. package/docs/apis/features/node/file-manager.md +0 -191
  185. package/docs/apis/features/node/fs.md +0 -1217
  186. package/docs/apis/features/node/git.md +0 -371
  187. package/docs/apis/features/node/google-auth.md +0 -193
  188. package/docs/apis/features/node/google-calendar.md +0 -202
  189. package/docs/apis/features/node/google-docs.md +0 -173
  190. package/docs/apis/features/node/google-drive.md +0 -246
  191. package/docs/apis/features/node/google-mail.md +0 -214
  192. package/docs/apis/features/node/google-sheets.md +0 -194
  193. package/docs/apis/features/node/grep.md +0 -292
  194. package/docs/apis/features/node/helpers.md +0 -164
  195. package/docs/apis/features/node/ink.md +0 -334
  196. package/docs/apis/features/node/ipc-socket.md +0 -249
  197. package/docs/apis/features/node/json-tree.md +0 -86
  198. package/docs/apis/features/node/networking.md +0 -316
  199. package/docs/apis/features/node/nlp.md +0 -133
  200. package/docs/apis/features/node/opener.md +0 -97
  201. package/docs/apis/features/node/os.md +0 -146
  202. package/docs/apis/features/node/package-finder.md +0 -392
  203. package/docs/apis/features/node/postgres.md +0 -234
  204. package/docs/apis/features/node/proc.md +0 -399
  205. package/docs/apis/features/node/process-manager.md +0 -305
  206. package/docs/apis/features/node/python.md +0 -604
  207. package/docs/apis/features/node/redis.md +0 -380
  208. package/docs/apis/features/node/repl.md +0 -88
  209. package/docs/apis/features/node/runpod.md +0 -674
  210. package/docs/apis/features/node/secure-shell.md +0 -176
  211. package/docs/apis/features/node/semantic-search.md +0 -408
  212. package/docs/apis/features/node/sqlite.md +0 -233
  213. package/docs/apis/features/node/telegram.md +0 -279
  214. package/docs/apis/features/node/transpiler.md +0 -74
  215. package/docs/apis/features/node/tts.md +0 -133
  216. package/docs/apis/features/node/ui.md +0 -701
  217. package/docs/apis/features/node/vault.md +0 -59
  218. package/docs/apis/features/node/vm.md +0 -75
  219. package/docs/apis/features/node/yaml-tree.md +0 -85
  220. package/docs/apis/features/node/yaml.md +0 -176
  221. package/docs/apis/features/web/asset-loader.md +0 -59
  222. package/docs/apis/features/web/container-link.md +0 -192
  223. package/docs/apis/features/web/esbuild.md +0 -54
  224. package/docs/apis/features/web/helpers.md +0 -164
  225. package/docs/apis/features/web/network.md +0 -44
  226. package/docs/apis/features/web/speech.md +0 -69
  227. package/docs/apis/features/web/vault.md +0 -59
  228. package/docs/apis/features/web/vm.md +0 -75
  229. package/docs/apis/features/web/voice.md +0 -84
  230. package/docs/apis/servers/express.md +0 -171
  231. package/docs/apis/servers/mcp.md +0 -238
  232. package/docs/apis/servers/websocket.md +0 -170
  233. package/docs/bootstrap/CLAUDE.md +0 -101
  234. package/docs/bootstrap/SKILL.md +0 -341
  235. package/docs/bootstrap/templates/about-command.ts +0 -41
  236. package/docs/bootstrap/templates/docs-models.ts +0 -22
  237. package/docs/bootstrap/templates/docs-readme.md +0 -43
  238. package/docs/bootstrap/templates/example-feature.ts +0 -53
  239. package/docs/bootstrap/templates/health-endpoint.ts +0 -15
  240. package/docs/bootstrap/templates/luca-cli.ts +0 -30
  241. package/docs/bootstrap/templates/runme.md +0 -54
  242. package/docs/challenges/caching-proxy.md +0 -16
  243. package/docs/challenges/content-db-round-trip.md +0 -14
  244. package/docs/challenges/custom-command.md +0 -9
  245. package/docs/challenges/file-watcher-pipeline.md +0 -11
  246. package/docs/challenges/grep-audit-report.md +0 -15
  247. package/docs/challenges/multi-feature-dashboard.md +0 -14
  248. package/docs/challenges/process-orchestrator.md +0 -17
  249. package/docs/challenges/rest-api-server-with-client.md +0 -12
  250. package/docs/challenges/script-runner-with-vm.md +0 -11
  251. package/docs/challenges/simple-rest-api.md +0 -15
  252. package/docs/challenges/websocket-serve-and-client.md +0 -11
  253. package/docs/challenges/yaml-config-system.md +0 -14
  254. package/docs/command-system-overhaul.md +0 -94
  255. package/docs/documentation-audit.md +0 -134
  256. package/docs/examples/assistant/CORE.md +0 -18
  257. package/docs/examples/assistant/hooks.ts +0 -3
  258. package/docs/examples/assistant/tools.ts +0 -10
  259. package/docs/examples/assistant-hooks-reference.ts +0 -171
  260. package/docs/examples/assistant-with-process-manager.md +0 -84
  261. package/docs/examples/content-db.md +0 -77
  262. package/docs/examples/disk-cache.md +0 -83
  263. package/docs/examples/docker.md +0 -101
  264. package/docs/examples/downloader.md +0 -70
  265. package/docs/examples/entity.md +0 -124
  266. package/docs/examples/esbuild.md +0 -80
  267. package/docs/examples/feature-as-tool-provider.md +0 -143
  268. package/docs/examples/file-manager.md +0 -82
  269. package/docs/examples/fs.md +0 -83
  270. package/docs/examples/git.md +0 -85
  271. package/docs/examples/google-auth.md +0 -88
  272. package/docs/examples/google-calendar.md +0 -94
  273. package/docs/examples/google-docs.md +0 -82
  274. package/docs/examples/google-drive.md +0 -96
  275. package/docs/examples/google-sheets.md +0 -95
  276. package/docs/examples/grep.md +0 -85
  277. package/docs/examples/ink-blocks.md +0 -75
  278. package/docs/examples/ink-renderer.md +0 -41
  279. package/docs/examples/ink.md +0 -103
  280. package/docs/examples/ipc-socket.md +0 -103
  281. package/docs/examples/json-tree.md +0 -91
  282. package/docs/examples/networking.md +0 -58
  283. package/docs/examples/nlp.md +0 -91
  284. package/docs/examples/opener.md +0 -78
  285. package/docs/examples/os.md +0 -72
  286. package/docs/examples/package-finder.md +0 -89
  287. package/docs/examples/postgres.md +0 -91
  288. package/docs/examples/proc.md +0 -81
  289. package/docs/examples/process-manager.md +0 -79
  290. package/docs/examples/python.md +0 -132
  291. package/docs/examples/repl.md +0 -93
  292. package/docs/examples/runpod.md +0 -119
  293. package/docs/examples/secure-shell.md +0 -92
  294. package/docs/examples/sqlite.md +0 -86
  295. package/docs/examples/structured-output-with-assistants.md +0 -144
  296. package/docs/examples/telegram.md +0 -77
  297. package/docs/examples/tts.md +0 -86
  298. package/docs/examples/ui.md +0 -80
  299. package/docs/examples/vault.md +0 -70
  300. package/docs/examples/vm.md +0 -86
  301. package/docs/examples/websocket-ask-and-reply-example.md +0 -128
  302. package/docs/examples/yaml-tree.md +0 -93
  303. package/docs/examples/yaml.md +0 -104
  304. package/docs/ideas/assistant-factory-pattern.md +0 -142
  305. package/docs/in-memory-fs.md +0 -4
  306. package/docs/introspection-audit.md +0 -49
  307. package/docs/introspection.md +0 -164
  308. package/docs/mcp/readme.md +0 -162
  309. package/docs/models.ts +0 -41
  310. package/docs/philosophy.md +0 -86
  311. package/docs/principles.md +0 -7
  312. package/docs/prompts/audit-codebase-for-failures-to-use-the-container.md +0 -34
  313. package/docs/prompts/check-for-undocumented-features.md +0 -27
  314. package/docs/prompts/mcp-test-easy-command.md +0 -27
  315. package/docs/scaffolds/client.md +0 -149
  316. package/docs/scaffolds/command.md +0 -120
  317. package/docs/scaffolds/endpoint.md +0 -171
  318. package/docs/scaffolds/feature.md +0 -158
  319. package/docs/scaffolds/selector.md +0 -91
  320. package/docs/scaffolds/server.md +0 -196
  321. package/docs/selectors.md +0 -115
  322. package/docs/sessions/custom-command/attempt-log-2.md +0 -195
  323. package/docs/sessions/file-watcher-pipeline/attempt-log-1.md +0 -728
  324. package/docs/sessions/file-watcher-pipeline/attempt-log-2.md +0 -555
  325. package/docs/sessions/grep-audit-report/attempt-log-1.md +0 -289
  326. package/docs/sessions/multi-feature-dashboard/attempt-log-2.md +0 -679
  327. package/docs/sessions/rest-api-server-with-client/attempt-log-1.md +0 -1
  328. package/docs/sessions/rest-api-server-with-client/attempt-log-3.md +0 -920
  329. package/docs/sessions/simple-rest-api/attempt-log-1.md +0 -593
  330. package/docs/sessions/websocket-serve-and-client/attempt-log-2.md +0 -995
  331. package/docs/tutorials/00-bootstrap.md +0 -166
  332. package/docs/tutorials/01-getting-started.md +0 -106
  333. package/docs/tutorials/02-container.md +0 -210
  334. package/docs/tutorials/03-scripts.md +0 -194
  335. package/docs/tutorials/04-features-overview.md +0 -196
  336. package/docs/tutorials/05-state-and-events.md +0 -171
  337. package/docs/tutorials/06-servers.md +0 -157
  338. package/docs/tutorials/07-endpoints.md +0 -198
  339. package/docs/tutorials/08-commands.md +0 -252
  340. package/docs/tutorials/09-clients.md +0 -162
  341. package/docs/tutorials/10-creating-features.md +0 -203
  342. package/docs/tutorials/11-contentbase.md +0 -191
  343. package/docs/tutorials/12-assistants.md +0 -215
  344. package/docs/tutorials/13-introspection.md +0 -157
  345. package/docs/tutorials/14-type-system.md +0 -174
  346. package/docs/tutorials/15-project-patterns.md +0 -222
  347. package/docs/tutorials/16-google-features.md +0 -534
  348. package/docs/tutorials/17-tui-blocks.md +0 -530
  349. package/docs/tutorials/18-semantic-search.md +0 -334
  350. package/docs/tutorials/19-python-sessions.md +0 -401
  351. package/docs/tutorials/20-browser-esm.md +0 -234
  352. package/index.ts +0 -1
  353. package/src/agi/endpoints/ask.ts +0 -60
  354. package/src/agi/endpoints/conversations/[id].ts +0 -45
  355. package/src/agi/endpoints/conversations.ts +0 -31
  356. package/src/agi/endpoints/experts.ts +0 -37
  357. package/test/assistant-hooks.test.ts +0 -306
  358. package/test/assistant.test.ts +0 -81
  359. package/test/bus.test.ts +0 -134
  360. package/test/clients-servers.test.ts +0 -217
  361. package/test/command.test.ts +0 -267
  362. package/test/container-link.test.ts +0 -274
  363. package/test/conversation.test.ts +0 -220
  364. package/test/features.test.ts +0 -160
  365. package/test/fork-and-research.test.ts +0 -450
  366. package/test/integration.test.ts +0 -787
  367. package/test/interceptor-chain.test.ts +0 -61
  368. package/test/node-container.test.ts +0 -121
  369. package/test/python-session.test.ts +0 -105
  370. package/test/rate-limit.test.ts +0 -272
  371. package/test/semantic-search.test.ts +0 -550
  372. package/test/state.test.ts +0 -121
  373. package/test/vm-context.test.ts +0 -146
  374. package/test/vm-loadmodule.test.ts +0 -213
  375. package/test/websocket-ask.test.ts +0 -101
  376. package/test-integration/assistant.test.ts +0 -138
  377. package/test-integration/assistants-manager.test.ts +0 -113
  378. package/test-integration/claude-code.test.ts +0 -98
  379. package/test-integration/conversation-history.test.ts +0 -205
  380. package/test-integration/conversation.test.ts +0 -137
  381. package/test-integration/elevenlabs.test.ts +0 -55
  382. package/test-integration/google-services.test.ts +0 -80
  383. package/test-integration/helpers.ts +0 -89
  384. package/test-integration/memory.test.ts +0 -204
  385. package/test-integration/openai-codex.test.ts +0 -93
  386. package/test-integration/runpod.test.ts +0 -58
  387. package/test-integration/server-endpoints.test.ts +0 -97
  388. package/test-integration/telegram.test.ts +0 -46
@@ -1,401 +0,0 @@
1
- ---
2
- title: Working with Python Projects
3
- tags: [python, sessions, persistent, bridge, codebase, interop, data-science]
4
- ---
5
-
6
- # Working with Python Projects
7
-
8
- Luca's `python` feature has two modes: **stateless** execution (fire-and-forget, one process per call) and **persistent sessions** (a long-lived Python process that maintains state across calls). This tutorial focuses on sessions — the mode that lets you actually work inside a Python codebase.
9
-
10
- ## When to Use Sessions
11
-
12
- Stateless `execute()` is fine for one-off scripts. But if you need any of these, you want a session:
13
-
14
- - **Imports that persist** — load `pandas` once, use it across many calls
15
- - **State that builds up** — query a database, filter results, then export
16
- - **Working inside a real project** — import your own modules, call your own functions
17
- - **Expensive setup** — ML model loading, database connections, API client initialization
18
-
19
- ## Quick Start
20
-
21
- ```ts skip
22
- const python = container.feature('python', { dir: '/path/to/my-python-project' })
23
- await python.enable()
24
- await python.startSession()
25
-
26
- // Everything below runs in the same Python process.
27
- // Variables, imports, and state persist across calls.
28
-
29
- await python.run('import pandas as pd')
30
- await python.run('df = pd.read_csv("data/sales.csv")')
31
-
32
- const result = await python.run('print(df.shape)')
33
- console.log(result.stdout) // '(1000, 12)\n'
34
-
35
- const total = await python.eval('df["revenue"].sum()')
36
- console.log('Total revenue:', total)
37
-
38
- await python.stopSession()
39
- ```
40
-
41
- ## Project Directory
42
-
43
- The `dir` option tells Luca where the Python project lives. This determines:
44
-
45
- 1. **sys.path** — the bridge adds the project root (and `src/`, `lib/` if they exist) so your imports work
46
- 2. **Environment detection** — Luca looks for `uv.lock`, `pyproject.toml`, `venv/`, etc. in this directory
47
- 3. **Working directory** — the bridge process runs with `cwd` set to this path
48
-
49
- ```ts skip
50
- // Explicit project directory
51
- const python = container.feature('python', { dir: '/Users/me/projects/my-api' })
52
-
53
- // Or defaults to wherever luca was invoked from
54
- const python = container.feature('python')
55
- ```
56
-
57
- If your project uses a `src/` layout (common in modern Python), the bridge automatically adds it to `sys.path`:
58
-
59
- ```
60
- my-project/
61
- src/
62
- myapp/
63
- __init__.py
64
- models.py
65
- pyproject.toml
66
- ```
67
-
68
- ```ts skip
69
- await python.startSession()
70
- // This works because src/ was added to sys.path
71
- await python.importModule('myapp.models', 'models')
72
- ```
73
-
74
- ## Session Lifecycle
75
-
76
- ### Starting
77
-
78
- `startSession()` spawns a Python bridge process that talks to Luca over stdin/stdout using a JSON-line protocol. The bridge sets up `sys.path` and signals when it's ready.
79
-
80
- ```ts skip
81
- await python.enable()
82
- await python.startSession()
83
-
84
- console.log(python.state.get('sessionActive')) // true
85
- console.log(python.state.get('sessionId')) // uuid
86
- ```
87
-
88
- ### Stopping
89
-
90
- `stopSession()` kills the bridge process and cleans up. Any pending requests are rejected.
91
-
92
- ```ts skip
93
- await python.stopSession()
94
- console.log(python.state.get('sessionActive')) // false
95
- ```
96
-
97
- ### Crash Recovery
98
-
99
- If the Python process dies unexpectedly (segfault, killed externally), the feature:
100
- - Sets `sessionActive` to `false`
101
- - Rejects all pending requests
102
- - Emits a `sessionError` event
103
-
104
- ```ts skip
105
- python.on('sessionError', ({ error, sessionId }) => {
106
- console.error('Python session error:', error)
107
- // You could restart: await python.startSession()
108
- })
109
- ```
110
-
111
- ## The Session API
112
-
113
- ### run(code, variables?)
114
-
115
- Execute Python code in the persistent namespace. This is the workhorse method.
116
-
117
- ```ts skip
118
- // Simple execution
119
- const result = await python.run('print("hello")')
120
- // result.ok === true
121
- // result.stdout === 'hello\n'
122
-
123
- // With variable injection
124
- const result = await python.run('print(f"Processing {count} items")', { count: 42 })
125
-
126
- // Errors don't crash the session
127
- const bad = await python.run('raise ValueError("oops")')
128
- // bad.ok === false
129
- // bad.error === 'oops'
130
- // bad.traceback === 'Traceback (most recent call last):\n...'
131
-
132
- // Session still alive after error
133
- const good = await python.run('print("still here")')
134
- // good.ok === true
135
- ```
136
-
137
- ### eval(expression)
138
-
139
- Evaluate a Python expression and return its value to JavaScript.
140
-
141
- ```ts skip
142
- await python.run('x = [1, 2, 3]')
143
- const length = await python.eval('len(x)') // 3
144
- const doubled = await python.eval('[i*2 for i in x]') // [2, 4, 6]
145
- ```
146
-
147
- Values are JSON-serialized. Complex types that can't be serialized come back as their `repr()` string.
148
-
149
- ### importModule(name, alias?)
150
-
151
- Import a module into the session namespace. The alias defaults to the last segment of the module path.
152
-
153
- ```ts skip
154
- await python.importModule('json') // import json
155
- await python.importModule('myapp.models', 'models') // import myapp.models as models
156
- await python.importModule('os.path') // import os.path (available as "path")
157
- ```
158
-
159
- ### call(funcPath, args?, kwargs?)
160
-
161
- Call a function by its dotted path in the namespace.
162
-
163
- ```ts skip
164
- await python.importModule('json')
165
- const encoded = await python.call('json.dumps', [{ a: 1 }], { indent: 2 })
166
- // '{\n "a": 1\n}'
167
-
168
- // Works with your own functions too
169
- await python.run('def add(a, b): return a + b')
170
- const sum = await python.call('add', [3, 4]) // 7
171
- ```
172
-
173
- ### getLocals()
174
-
175
- Inspect everything in the session namespace.
176
-
177
- ```ts skip
178
- await python.run('x = 42')
179
- await python.importModule('json')
180
- const locals = await python.getLocals()
181
- // { x: 42, json: '<module ...>' }
182
- ```
183
-
184
- ### resetSession()
185
-
186
- Clear all variables and imports without restarting the process.
187
-
188
- ```ts skip
189
- await python.run('big_model = load_model()')
190
- await python.resetSession()
191
- // big_model is gone, but the session process is still running
192
- ```
193
-
194
- ## Real-World Patterns
195
-
196
- ### Data Analysis Pipeline
197
-
198
- ```ts skip
199
- const python = container.feature('python', { dir: '/path/to/analytics' })
200
- await python.enable()
201
- await python.startSession()
202
-
203
- // Setup
204
- await python.run('import pandas as pd')
205
- await python.run('import matplotlib')
206
- await python.run('matplotlib.use("Agg")') // headless
207
- await python.run('import matplotlib.pyplot as plt')
208
-
209
- // Load and analyze
210
- await python.run('df = pd.read_csv("data/events.csv")')
211
- const shape = await python.eval('list(df.shape)')
212
- console.log(`Loaded ${shape[0]} rows, ${shape[1]} columns`)
213
-
214
- const columns = await python.eval('list(df.columns)')
215
- console.log('Columns:', columns)
216
-
217
- // Filter and aggregate
218
- await python.run(`
219
- filtered = df[df["status"] == "completed"]
220
- summary = filtered.groupby("category")["amount"].agg(["sum", "mean", "count"])
221
- `)
222
-
223
- const summary = await python.eval('summary.to_dict()')
224
- console.log('Summary:', summary)
225
-
226
- // Generate a chart
227
- await python.run(`
228
- fig, ax = plt.subplots(figsize=(10, 6))
229
- summary["sum"].plot(kind="bar", ax=ax)
230
- ax.set_title("Revenue by Category")
231
- fig.savefig("output/revenue.png", dpi=150, bbox_inches="tight")
232
- plt.close(fig)
233
- `)
234
-
235
- await python.stopSession()
236
- ```
237
-
238
- ### Working with a Django Project
239
-
240
- ```ts skip
241
- const python = container.feature('python', { dir: '/path/to/django-project' })
242
- await python.enable()
243
- await python.startSession()
244
-
245
- // Django requires this before you can import models
246
- await python.run(`
247
- import os
248
- os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings")
249
-
250
- import django
251
- django.setup()
252
- `)
253
-
254
- // Now you can work with the ORM
255
- await python.run('from myapp.models import User, Order')
256
-
257
- const userCount = await python.eval('User.objects.count()')
258
- console.log(`${userCount} users in database`)
259
-
260
- const recentOrders = await python.eval(`
261
- list(Order.objects.filter(status="pending").values("id", "total", "created_at")[:10])
262
- `)
263
- console.log('Recent pending orders:', recentOrders)
264
-
265
- await python.stopSession()
266
- ```
267
-
268
- ### ML Model Interaction
269
-
270
- ```ts skip
271
- const python = container.feature('python', { dir: '/path/to/ml-project' })
272
- await python.enable()
273
- await python.startSession()
274
-
275
- // Expensive setup — only happens once
276
- await python.run(`
277
- from transformers import pipeline
278
- classifier = pipeline("sentiment-analysis")
279
- print("Model loaded")
280
- `)
281
-
282
- // Now you can call it cheaply many times
283
- async function classify(text: string) {
284
- return python.call('classifier', [text])
285
- }
286
-
287
- const results = await Promise.all([
288
- classify('I love this product!'),
289
- classify('Terrible experience.'),
290
- classify('It was okay, nothing special.'),
291
- ])
292
-
293
- console.log(results)
294
- // [
295
- // [{ label: 'POSITIVE', score: 0.9998 }],
296
- // [{ label: 'NEGATIVE', score: 0.9994 }],
297
- // [{ label: 'NEGATIVE', score: 0.7231 }],
298
- // ]
299
-
300
- await python.stopSession()
301
- ```
302
-
303
- ### Luca Command That Uses Python
304
-
305
- ```ts skip
306
- // commands/analyze.ts
307
- import { z } from 'zod'
308
- import type { ContainerContext } from '@soederpop/luca'
309
- import { CommandOptionsSchema } from '@soederpop/luca/schemas'
310
-
311
- export const positionals = ['target']
312
- export const argsSchema = CommandOptionsSchema.extend({
313
- target: z.string().describe('Path to CSV file to analyze'),
314
- })
315
-
316
- async function handler(options: z.infer<typeof argsSchema>, context: ContainerContext) {
317
- const container = context.container as any
318
- const python = container.feature('python')
319
- await python.enable()
320
- await python.startSession()
321
-
322
- try {
323
- await python.run('import pandas as pd')
324
- await python.run(`df = pd.read_csv("${options.target}")`)
325
-
326
- const shape = await python.eval('list(df.shape)')
327
- const dtypes = await python.eval('dict(df.dtypes.astype(str))')
328
- const nulls = await python.eval('dict(df.isnull().sum())')
329
-
330
- console.log(`Rows: ${shape[0]}, Columns: ${shape[1]}`)
331
- console.log('Column types:', dtypes)
332
- console.log('Null counts:', nulls)
333
- } finally {
334
- await python.stopSession()
335
- }
336
- }
337
-
338
- export default {
339
- description: 'Analyze a CSV file using pandas',
340
- argsSchema,
341
- handler,
342
- }
343
- ```
344
-
345
- ```bash
346
- luca analyze data/sales.csv
347
- ```
348
-
349
- ## Stateless vs. Session: Choosing the Right Mode
350
-
351
- | | `execute()` (stateless) | `run()` (session) |
352
- |---|---|---|
353
- | Process | Fresh per call | Shared, long-lived |
354
- | State | None — each call starts clean | Persists across calls |
355
- | Imports | Re-imported every time | Imported once, reused |
356
- | Startup cost | ~50-200ms per call | ~200ms once, then ~1ms per call |
357
- | Use case | One-off scripts, simple eval | Real projects, data pipelines, REPL-like |
358
- | Error isolation | Perfect — crash is contained | Errors caught, session survives |
359
-
360
- Both modes use the same environment detection (uv, conda, venv, system) and respect the same `dir` and `pythonPath` options.
361
-
362
- ## Environment Detection
363
-
364
- The feature detects Python environments in this order:
365
-
366
- 1. **Explicit** — `pythonPath` option overrides everything
367
- 2. **uv** — `uv.lock` or `pyproject.toml` present, `uv run python` works
368
- 3. **conda** — `environment.yml` or `conda.yml` present
369
- 4. **venv** — `venv/` or `.venv/` directory with a Python binary inside
370
- 5. **system** — falls back to `python3` or `python` on PATH
371
-
372
- ```ts skip
373
- const python = container.feature('python', { dir: '/path/to/project' })
374
- await python.enable()
375
- console.log(python.environmentType) // 'uv' | 'conda' | 'venv' | 'system'
376
- console.log(python.pythonPath) // e.g. '/Users/me/.local/bin/uv run python'
377
- ```
378
-
379
- ## Events
380
-
381
- The session emits events you can listen to for monitoring and debugging:
382
-
383
- ```ts skip
384
- python.on('sessionStarted', ({ sessionId }) => {
385
- console.log('Session started:', sessionId)
386
- })
387
-
388
- python.on('sessionStopped', ({ sessionId }) => {
389
- console.log('Session stopped:', sessionId)
390
- })
391
-
392
- python.on('sessionError', ({ error, sessionId }) => {
393
- console.error('Session error:', error)
394
- })
395
- ```
396
-
397
- ## What's Next
398
-
399
- - [Creating Features](./10-creating-features.md) — build your own feature that wraps a Python service
400
- - [Commands](./08-commands.md) — create CLI commands that leverage Python
401
- - [Servers and Endpoints](./06-servers.md) — expose Python-powered analysis via HTTP
@@ -1,234 +0,0 @@
1
- ---
2
- title: "Browser: Import Luca from esm.sh"
3
- tags:
4
- - browser
5
- - esm
6
- - web
7
- - quickstart
8
- - cdn
9
- ---
10
- # Browser: Import Luca from esm.sh
11
-
12
- You can use Luca in any browser environment — no bundler, no build step. Import it from [esm.sh](https://esm.sh) and you get the singleton container on `window.luca`, ready to go. All the same APIs apply.
13
-
14
- ## Basic Setup
15
-
16
- ```html
17
- <script type="module">
18
- import "https://esm.sh/@soederpop/luca/web"
19
-
20
- const container = window.luca
21
- console.log(container.uuid) // unique container ID
22
- console.log(container.features.available) // ['assetLoader', 'voice', 'speech', 'network', 'vault', 'vm', 'esbuild', 'helpers', 'containerLink']
23
- </script>
24
- ```
25
-
26
- The import triggers module evaluation, which creates the `WebContainer` singleton and attaches it to `window.luca`. That's it.
27
-
28
- If you prefer a named import:
29
-
30
- ```html
31
- <script type="module">
32
- import container from "https://esm.sh/@soederpop/luca/web"
33
- // container === window.luca
34
- </script>
35
- ```
36
-
37
- ## Using Features
38
-
39
- Once you have the container, features work exactly like they do on the server — lazy-loaded via `container.feature()`.
40
-
41
- ```html
42
- <script type="module">
43
- import "https://esm.sh/@soederpop/luca/web"
44
- const { luca: container } = window
45
-
46
- // Load a script from a CDN
47
- const assetLoader = container.feature('assetLoader')
48
- await assetLoader.loadScript('https://cdn.jsdelivr.net/npm/chart.js')
49
-
50
- // Load a stylesheet
51
- await assetLoader.loadStylesheet('https://cdn.jsdelivr.net/npm/water.css@2/out/water.css')
52
-
53
- // Text-to-speech
54
- const speech = container.feature('speech')
55
- speech.speak('Hello from Luca')
56
-
57
- // Voice recognition
58
- const voice = container.feature('voice')
59
- voice.on('transcript', ({ text }) => console.log('Heard:', text))
60
- voice.start()
61
- </script>
62
- ```
63
-
64
- ## State and Events
65
-
66
- The container is a state machine and event bus. This works identically to the server.
67
-
68
- ```html
69
- <script type="module">
70
- import container from "https://esm.sh/@soederpop/luca/web"
71
-
72
- // Listen for state changes
73
- container.on('stateChanged', ({ changes }) => {
74
- console.log('State changed:', changes)
75
- })
76
-
77
- // Feature-level state and events
78
- const voice = container.feature('voice')
79
- voice.on('stateChanged', ({ changes }) => {
80
- document.getElementById('status').textContent = changes.listening ? 'Listening...' : 'Idle'
81
- })
82
- </script>
83
- ```
84
-
85
- ## REST Client
86
-
87
- Make HTTP requests with the built-in REST client. Methods return parsed JSON directly.
88
-
89
- ```html
90
- <script type="module">
91
- import container from "https://esm.sh/@soederpop/luca/web"
92
-
93
- const api = container.client('rest', { baseURL: 'https://jsonplaceholder.typicode.com' })
94
- const posts = await api.get('/posts')
95
- console.log(posts) // array of post objects, not a Response wrapper
96
- </script>
97
- ```
98
-
99
- ## WebSocket Client
100
-
101
- Connect to a WebSocket server:
102
-
103
- ```html
104
- <script type="module">
105
- import container from "https://esm.sh/@soederpop/luca/web"
106
-
107
- const socket = container.client('socket', { url: 'ws://localhost:3000' })
108
- socket.on('message', (data) => console.log('Received:', data))
109
- socket.send({ type: 'hello' })
110
- </script>
111
- ```
112
-
113
- ## Extending: Custom Features
114
-
115
- The container exposes the `Feature` class directly, so you can create your own features without any additional imports.
116
-
117
- ```html
118
- <script type="module">
119
- import container from "https://esm.sh/@soederpop/luca/web"
120
-
121
- const { Feature } = container
122
-
123
- class Theme extends Feature {
124
- static shortcut = 'features.theme'
125
- static { Feature.register(this, 'theme') }
126
-
127
- get current() {
128
- return this.state.get('mode') || 'light'
129
- }
130
-
131
- toggle() {
132
- const next = this.current === 'light' ? 'dark' : 'light'
133
- this.state.set('mode', next)
134
- document.documentElement.setAttribute('data-theme', next)
135
- this.emit('themeChanged', { mode: next })
136
- }
137
- }
138
-
139
- const theme = container.feature('theme')
140
- theme.on('themeChanged', ({ mode }) => console.log('Theme:', mode))
141
- theme.toggle() // => Theme: dark
142
- </script>
143
- ```
144
-
145
- ## Utilities
146
-
147
- The container's built-in utilities are available in the browser too.
148
-
149
- ```html
150
- <script type="module">
151
- import container from "https://esm.sh/@soederpop/luca/web"
152
-
153
- // UUID generation
154
- const id = container.utils.uuid()
155
-
156
- // Lodash helpers
157
- const { groupBy, keyBy, pick } = container.utils.lodash
158
-
159
- // String utilities
160
- const { camelCase, kebabCase } = container.utils.stringUtils
161
- </script>
162
- ```
163
-
164
- ## Full Example: A Minimal App
165
-
166
- ```html
167
- <!DOCTYPE html>
168
- <html lang="en">
169
- <head>
170
- <meta charset="UTF-8">
171
- <title>Luca Browser Demo</title>
172
- </head>
173
- <body>
174
- <h1>Luca Browser Demo</h1>
175
- <button id="speak">Speak</button>
176
- <button id="theme">Toggle Theme</button>
177
- <pre id="output"></pre>
178
-
179
- <script type="module">
180
- import container from "https://esm.sh/@soederpop/luca/web"
181
-
182
- const log = (msg) => {
183
- document.getElementById('output').textContent += msg + '\n'
184
- }
185
-
186
- // Load a stylesheet
187
- const assets = container.feature('assetLoader')
188
- await assets.loadStylesheet('https://cdn.jsdelivr.net/npm/water.css@2/out/water.css')
189
-
190
- // Custom feature
191
- const { Feature } = container
192
-
193
- class Theme extends Feature {
194
- static shortcut = 'features.theme'
195
- static { Feature.register(this, 'theme') }
196
-
197
- toggle() {
198
- const next = (this.state.get('mode') || 'light') === 'light' ? 'dark' : 'light'
199
- this.state.set('mode', next)
200
- document.documentElement.style.colorScheme = next
201
- this.emit('themeChanged', { mode: next })
202
- }
203
- }
204
-
205
- const theme = container.feature('theme')
206
- theme.on('themeChanged', ({ mode }) => log(`Theme: ${mode}`))
207
-
208
- // Speech
209
- const speech = container.feature('speech')
210
-
211
- document.getElementById('speak').onclick = () => speech.speak('Hello from Luca')
212
- document.getElementById('theme').onclick = () => theme.toggle()
213
-
214
- log(`Container ID: ${container.uuid}`)
215
- log(`Features: ${container.features.available.join(', ')}`)
216
- </script>
217
- </body>
218
- </html>
219
- ```
220
-
221
- Save this as an HTML file, open it in a browser, and everything works — no npm, no bundler, no build step.
222
-
223
- ## Gotchas
224
-
225
- - **esm.sh caches aggressively.** Pin a version if you need stability: `https://esm.sh/@soederpop/luca@0.0.29/web`
226
- - **Browser features only.** The web container doesn't include node-specific features like `fs`, `git`, `proc`, or `docker`. If you need server features, run Luca on the server and connect via the REST or WebSocket clients.
227
- - **`window.luca` is the singleton.** Don't call `createContainer()` — it just warns and returns the same instance. If you need isolation, use `container.subcontainer()`.
228
- - **CORS applies.** REST client requests from the browser are subject to browser CORS rules. Your API must send the right headers.
229
-
230
- ## What's Next
231
-
232
- - [State and Events](./05-state-and-events.md) — deep dive into the state machine and event bus (works identically in the browser)
233
- - [Creating Features](./10-creating-features.md) — full anatomy of a feature with schemas, state, and events
234
- - [Clients](./09-clients.md) — REST and WebSocket client APIs
package/index.ts DELETED
@@ -1 +0,0 @@
1
- console.log("Hello via Bun!");
@@ -1,60 +0,0 @@
1
- import { z } from 'zod'
2
- import type { EndpointContext } from '../../endpoint.js'
3
-
4
- export const path = '/ask'
5
- export const description = 'Ask the AGI container a question'
6
- export const tags = ['agi']
7
-
8
- export const postSchema = z.object({
9
- question: z.string().describe('The question to ask'),
10
- context: z.string().optional().describe('Additional context for the question'),
11
- stream: z.boolean().optional().default(false).describe('Whether to stream the response'),
12
- })
13
-
14
- export async function post(
15
- parameters: z.infer<typeof postSchema>,
16
- ctx: EndpointContext
17
- ) {
18
- const { container } = ctx
19
- const { question, context: userContext, stream } = parameters
20
-
21
- const history: any[] = []
22
- if (userContext) {
23
- history.push({ role: 'system', content: userContext })
24
- }
25
-
26
- const conversation = container.feature('conversation' as any, {
27
- history,
28
- }) as any
29
-
30
- if (stream) {
31
- ctx.response.setHeader('Content-Type', 'text/event-stream')
32
- ctx.response.setHeader('Cache-Control', 'no-cache')
33
- ctx.response.setHeader('Connection', 'keep-alive')
34
-
35
- conversation.on('chunk', (chunk: string) => {
36
- ctx.response.write(`data: ${JSON.stringify({ chunk })}\n\n`)
37
- })
38
-
39
- const answer = await conversation.ask(question)
40
- ctx.response.write(`data: ${JSON.stringify({ done: true, answer })}\n\n`)
41
- ctx.response.end()
42
- return
43
- }
44
-
45
- const answer = await conversation.ask(question)
46
- return { answer }
47
- }
48
-
49
- export const getSchema = z.object({
50
- question: z.string().describe('The question to ask'),
51
- })
52
-
53
- export async function get(
54
- parameters: z.infer<typeof getSchema>,
55
- ctx: EndpointContext
56
- ) {
57
- const conversation = ctx.container.feature('conversation' as any) as any
58
- const answer = await conversation.ask(parameters.question)
59
- return { answer }
60
- }