@soederpop/luca 0.1.2 → 0.1.3
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/CLAUDE.md +2 -0
- package/assistants/codingAssistant/hooks.ts +1 -5
- package/assistants/inkbot/CORE.md +69 -0
- package/assistants/inkbot/hooks.ts +14 -0
- package/assistants/inkbot/tools.ts +47 -0
- package/commands/inkbot.ts +353 -0
- package/dist/agi/container.server.d.ts +63 -0
- package/dist/agi/container.server.d.ts.map +1 -0
- package/dist/agi/endpoints/ask.d.ts +20 -0
- package/dist/agi/endpoints/ask.d.ts.map +1 -0
- package/dist/agi/endpoints/conversations/[id].d.ts +27 -0
- package/dist/agi/endpoints/conversations/[id].d.ts.map +1 -0
- package/dist/agi/endpoints/conversations.d.ts +18 -0
- package/dist/agi/endpoints/conversations.d.ts.map +1 -0
- package/dist/agi/endpoints/experts.d.ts +8 -0
- package/dist/agi/endpoints/experts.d.ts.map +1 -0
- package/dist/agi/feature.d.ts +9 -0
- package/dist/agi/feature.d.ts.map +1 -0
- package/dist/agi/features/assistant.d.ts +509 -0
- package/dist/agi/features/assistant.d.ts.map +1 -0
- package/dist/agi/features/assistants-manager.d.ts +236 -0
- package/dist/agi/features/assistants-manager.d.ts.map +1 -0
- package/dist/agi/features/autonomous-assistant.d.ts +281 -0
- package/dist/agi/features/autonomous-assistant.d.ts.map +1 -0
- package/dist/agi/features/browser-use.d.ts +479 -0
- package/dist/agi/features/browser-use.d.ts.map +1 -0
- package/dist/agi/features/claude-code.d.ts +824 -0
- package/dist/agi/features/claude-code.d.ts.map +1 -0
- package/dist/agi/features/conversation-history.d.ts +245 -0
- package/dist/agi/features/conversation-history.d.ts.map +1 -0
- package/dist/agi/features/conversation.d.ts +464 -0
- package/dist/agi/features/conversation.d.ts.map +1 -0
- package/dist/agi/features/docs-reader.d.ts +72 -0
- package/dist/agi/features/docs-reader.d.ts.map +1 -0
- package/dist/agi/features/file-tools.d.ts +110 -0
- package/dist/agi/features/file-tools.d.ts.map +1 -0
- package/dist/agi/features/luca-coder.d.ts +323 -0
- package/dist/agi/features/luca-coder.d.ts.map +1 -0
- package/dist/agi/features/openai-codex.d.ts +381 -0
- package/dist/agi/features/openai-codex.d.ts.map +1 -0
- package/dist/agi/features/openapi.d.ts +200 -0
- package/dist/agi/features/openapi.d.ts.map +1 -0
- package/dist/agi/features/skills-library.d.ts +167 -0
- package/dist/agi/features/skills-library.d.ts.map +1 -0
- package/dist/agi/index.d.ts +5 -0
- package/dist/agi/index.d.ts.map +1 -0
- package/dist/agi/lib/interceptor-chain.d.ts +44 -0
- package/dist/agi/lib/interceptor-chain.d.ts.map +1 -0
- package/dist/agi/lib/token-counter.d.ts +13 -0
- package/dist/agi/lib/token-counter.d.ts.map +1 -0
- package/dist/bootstrap/generated.d.ts +5 -0
- package/dist/bootstrap/generated.d.ts.map +1 -0
- package/dist/browser.d.ts +12 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/bus.d.ts +29 -0
- package/dist/bus.d.ts.map +1 -0
- package/dist/cli/build-info.d.ts +4 -0
- package/dist/cli/build-info.d.ts.map +1 -0
- package/dist/cli/cli.d.ts +3 -0
- package/dist/cli/cli.d.ts.map +1 -0
- package/dist/client.d.ts +60 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/clients/civitai/index.d.ts +472 -0
- package/dist/clients/civitai/index.d.ts.map +1 -0
- package/dist/clients/client-template.d.ts +30 -0
- package/dist/clients/client-template.d.ts.map +1 -0
- package/dist/clients/comfyui/index.d.ts +281 -0
- package/dist/clients/comfyui/index.d.ts.map +1 -0
- package/dist/clients/elevenlabs/index.d.ts +197 -0
- package/dist/clients/elevenlabs/index.d.ts.map +1 -0
- package/dist/clients/graph.d.ts +64 -0
- package/dist/clients/graph.d.ts.map +1 -0
- package/dist/clients/openai/index.d.ts +247 -0
- package/dist/clients/openai/index.d.ts.map +1 -0
- package/dist/clients/rest.d.ts +92 -0
- package/dist/clients/rest.d.ts.map +1 -0
- package/dist/clients/supabase/index.d.ts +176 -0
- package/dist/clients/supabase/index.d.ts.map +1 -0
- package/dist/clients/websocket.d.ts +127 -0
- package/dist/clients/websocket.d.ts.map +1 -0
- package/dist/command.d.ts +163 -0
- package/dist/command.d.ts.map +1 -0
- package/dist/commands/bootstrap.d.ts +20 -0
- package/dist/commands/bootstrap.d.ts.map +1 -0
- package/dist/commands/chat.d.ts +37 -0
- package/dist/commands/chat.d.ts.map +1 -0
- package/dist/commands/code.d.ts +28 -0
- package/dist/commands/code.d.ts.map +1 -0
- package/dist/commands/console.d.ts +22 -0
- package/dist/commands/console.d.ts.map +1 -0
- package/dist/commands/describe.d.ts +50 -0
- package/dist/commands/describe.d.ts.map +1 -0
- package/dist/commands/eval.d.ts +23 -0
- package/dist/commands/eval.d.ts.map +1 -0
- package/dist/commands/help.d.ts +25 -0
- package/dist/commands/help.d.ts.map +1 -0
- package/dist/commands/index.d.ts +18 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/introspect.d.ts +24 -0
- package/dist/commands/introspect.d.ts.map +1 -0
- package/dist/commands/mcp.d.ts +35 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/prompt.d.ts +38 -0
- package/dist/commands/prompt.d.ts.map +1 -0
- package/dist/commands/run.d.ts +24 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/sandbox-mcp.d.ts +34 -0
- package/dist/commands/sandbox-mcp.d.ts.map +1 -0
- package/dist/commands/save-api-docs.d.ts +21 -0
- package/dist/commands/save-api-docs.d.ts.map +1 -0
- package/dist/commands/scaffold.d.ts +24 -0
- package/dist/commands/scaffold.d.ts.map +1 -0
- package/dist/commands/select.d.ts +22 -0
- package/dist/commands/select.d.ts.map +1 -0
- package/dist/commands/serve.d.ts +29 -0
- package/dist/commands/serve.d.ts.map +1 -0
- package/dist/container-describer.d.ts +144 -0
- package/dist/container-describer.d.ts.map +1 -0
- package/dist/container.d.ts +451 -0
- package/dist/container.d.ts.map +1 -0
- package/dist/endpoint.d.ts +113 -0
- package/dist/endpoint.d.ts.map +1 -0
- package/dist/feature.d.ts +47 -0
- package/dist/feature.d.ts.map +1 -0
- package/dist/graft.d.ts +29 -0
- package/dist/graft.d.ts.map +1 -0
- package/dist/hash-object.d.ts +8 -0
- package/dist/hash-object.d.ts.map +1 -0
- package/dist/helper.d.ts +209 -0
- package/dist/helper.d.ts.map +1 -0
- package/dist/introspection/generated.node.d.ts +44623 -0
- package/dist/introspection/generated.node.d.ts.map +1 -0
- package/dist/introspection/generated.web.d.ts +1412 -0
- package/dist/introspection/generated.web.d.ts.map +1 -0
- package/dist/introspection/index.d.ts +156 -0
- package/dist/introspection/index.d.ts.map +1 -0
- package/dist/introspection/scan.d.ts +147 -0
- package/dist/introspection/scan.d.ts.map +1 -0
- package/dist/node/container.d.ts +256 -0
- package/dist/node/container.d.ts.map +1 -0
- package/dist/node/feature.d.ts +9 -0
- package/dist/node/feature.d.ts.map +1 -0
- package/dist/node/features/container-link.d.ts +213 -0
- package/dist/node/features/container-link.d.ts.map +1 -0
- package/dist/node/features/content-db.d.ts +354 -0
- package/dist/node/features/content-db.d.ts.map +1 -0
- package/dist/node/features/disk-cache.d.ts +236 -0
- package/dist/node/features/disk-cache.d.ts.map +1 -0
- package/dist/node/features/dns.d.ts +511 -0
- package/dist/node/features/dns.d.ts.map +1 -0
- package/dist/node/features/docker.d.ts +485 -0
- package/dist/node/features/docker.d.ts.map +1 -0
- package/dist/node/features/downloader.d.ts +73 -0
- package/dist/node/features/downloader.d.ts.map +1 -0
- package/dist/node/features/figlet-fonts.d.ts +4 -0
- package/dist/node/features/figlet-fonts.d.ts.map +1 -0
- package/dist/node/features/file-manager.d.ts +177 -0
- package/dist/node/features/file-manager.d.ts.map +1 -0
- package/dist/node/features/fs.d.ts +635 -0
- package/dist/node/features/fs.d.ts.map +1 -0
- package/dist/node/features/git.d.ts +329 -0
- package/dist/node/features/git.d.ts.map +1 -0
- package/dist/node/features/google-auth.d.ts +200 -0
- package/dist/node/features/google-auth.d.ts.map +1 -0
- package/dist/node/features/google-calendar.d.ts +194 -0
- package/dist/node/features/google-calendar.d.ts.map +1 -0
- package/dist/node/features/google-docs.d.ts +138 -0
- package/dist/node/features/google-docs.d.ts.map +1 -0
- package/dist/node/features/google-drive.d.ts +202 -0
- package/dist/node/features/google-drive.d.ts.map +1 -0
- package/dist/node/features/google-mail.d.ts +221 -0
- package/dist/node/features/google-mail.d.ts.map +1 -0
- package/dist/node/features/google-sheets.d.ts +157 -0
- package/dist/node/features/google-sheets.d.ts.map +1 -0
- package/dist/node/features/grep.d.ts +207 -0
- package/dist/node/features/grep.d.ts.map +1 -0
- package/dist/node/features/helpers.d.ts +236 -0
- package/dist/node/features/helpers.d.ts.map +1 -0
- package/dist/node/features/ink.d.ts +332 -0
- package/dist/node/features/ink.d.ts.map +1 -0
- package/dist/node/features/ipc-socket.d.ts +298 -0
- package/dist/node/features/ipc-socket.d.ts.map +1 -0
- package/dist/node/features/json-tree.d.ts +140 -0
- package/dist/node/features/json-tree.d.ts.map +1 -0
- package/dist/node/features/networking.d.ts +373 -0
- package/dist/node/features/networking.d.ts.map +1 -0
- package/dist/node/features/nlp.d.ts +125 -0
- package/dist/node/features/nlp.d.ts.map +1 -0
- package/dist/node/features/opener.d.ts +93 -0
- package/dist/node/features/opener.d.ts.map +1 -0
- package/dist/node/features/os.d.ts +168 -0
- package/dist/node/features/os.d.ts.map +1 -0
- package/dist/node/features/package-finder.d.ts +419 -0
- package/dist/node/features/package-finder.d.ts.map +1 -0
- package/dist/node/features/postgres.d.ts +173 -0
- package/dist/node/features/postgres.d.ts.map +1 -0
- package/dist/node/features/proc.d.ts +285 -0
- package/dist/node/features/proc.d.ts.map +1 -0
- package/dist/node/features/process-manager.d.ts +427 -0
- package/dist/node/features/process-manager.d.ts.map +1 -0
- package/dist/node/features/python.d.ts +477 -0
- package/dist/node/features/python.d.ts.map +1 -0
- package/dist/node/features/redis.d.ts +247 -0
- package/dist/node/features/redis.d.ts.map +1 -0
- package/dist/node/features/repl.d.ts +84 -0
- package/dist/node/features/repl.d.ts.map +1 -0
- package/dist/node/features/runpod.d.ts +527 -0
- package/dist/node/features/runpod.d.ts.map +1 -0
- package/dist/node/features/secure-shell.d.ts +145 -0
- package/dist/node/features/secure-shell.d.ts.map +1 -0
- package/dist/node/features/semantic-search.d.ts +207 -0
- package/dist/node/features/semantic-search.d.ts.map +1 -0
- package/dist/node/features/sqlite.d.ts +180 -0
- package/dist/node/features/sqlite.d.ts.map +1 -0
- package/dist/node/features/telegram.d.ts +173 -0
- package/dist/node/features/telegram.d.ts.map +1 -0
- package/dist/node/features/transpiler.d.ts +51 -0
- package/dist/node/features/transpiler.d.ts.map +1 -0
- package/dist/node/features/tts.d.ts +108 -0
- package/dist/node/features/tts.d.ts.map +1 -0
- package/dist/node/features/ui.d.ts +562 -0
- package/dist/node/features/ui.d.ts.map +1 -0
- package/dist/node/features/vault.d.ts +90 -0
- package/dist/node/features/vault.d.ts.map +1 -0
- package/dist/node/features/vm.d.ts +285 -0
- package/dist/node/features/vm.d.ts.map +1 -0
- package/dist/node/features/yaml-tree.d.ts +118 -0
- package/dist/node/features/yaml-tree.d.ts.map +1 -0
- package/dist/node/features/yaml.d.ts +127 -0
- package/dist/node/features/yaml.d.ts.map +1 -0
- package/dist/node.d.ts +67 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/python/generated.d.ts +2 -0
- package/dist/python/generated.d.ts.map +1 -0
- package/dist/react/index.d.ts +36 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/registry.d.ts +97 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/scaffolds/generated.d.ts +13 -0
- package/dist/scaffolds/generated.d.ts.map +1 -0
- package/dist/scaffolds/template.d.ts +11 -0
- package/dist/scaffolds/template.d.ts.map +1 -0
- package/dist/schemas/base.d.ts +254 -0
- package/dist/schemas/base.d.ts.map +1 -0
- package/dist/selector.d.ts +130 -0
- package/dist/selector.d.ts.map +1 -0
- package/dist/server.d.ts +89 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/servers/express.d.ts +104 -0
- package/dist/servers/express.d.ts.map +1 -0
- package/dist/servers/mcp.d.ts +201 -0
- package/dist/servers/mcp.d.ts.map +1 -0
- package/dist/servers/socket.d.ts +121 -0
- package/dist/servers/socket.d.ts.map +1 -0
- package/dist/state.d.ts +24 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/web/clients/socket.d.ts +37 -0
- package/dist/web/clients/socket.d.ts.map +1 -0
- package/dist/web/container.d.ts +55 -0
- package/dist/web/container.d.ts.map +1 -0
- package/dist/web/extension.d.ts +4 -0
- package/dist/web/extension.d.ts.map +1 -0
- package/dist/web/feature.d.ts +8 -0
- package/dist/web/feature.d.ts.map +1 -0
- package/dist/web/features/asset-loader.d.ts +35 -0
- package/dist/web/features/asset-loader.d.ts.map +1 -0
- package/dist/web/features/container-link.d.ts +167 -0
- package/dist/web/features/container-link.d.ts.map +1 -0
- package/dist/web/features/esbuild.d.ts +51 -0
- package/dist/web/features/esbuild.d.ts.map +1 -0
- package/dist/web/features/helpers.d.ts +140 -0
- package/dist/web/features/helpers.d.ts.map +1 -0
- package/dist/web/features/network.d.ts +69 -0
- package/dist/web/features/network.d.ts.map +1 -0
- package/dist/web/features/speech.d.ts +71 -0
- package/dist/web/features/speech.d.ts.map +1 -0
- package/dist/web/features/vault.d.ts +62 -0
- package/dist/web/features/vault.d.ts.map +1 -0
- package/dist/web/features/vm.d.ts +48 -0
- package/dist/web/features/vm.d.ts.map +1 -0
- package/dist/web/features/voice-recognition.d.ts +96 -0
- package/dist/web/features/voice-recognition.d.ts.map +1 -0
- package/dist/web/shims/isomorphic-vm.d.ts +22 -0
- package/dist/web/shims/isomorphic-vm.d.ts.map +1 -0
- package/docs/apis/features/agi/assistant.md +1 -0
- package/docs/apis/features/agi/assistants-manager.md +62 -2
- package/docs/apis/features/agi/auto-assistant.md +11 -109
- package/docs/apis/features/agi/claude-code.md +138 -0
- package/docs/apis/features/agi/conversation.md +60 -31
- package/docs/apis/features/agi/luca-coder.md +407 -0
- package/docs/apis/features/agi/openapi.md +2 -2
- package/docs/apis/features/agi/skills-library.md +12 -0
- package/docs/apis/features/node/python.md +81 -11
- package/docs/apis/features/node/transpiler.md +74 -0
- package/docs/apis/features/web/esbuild.md +0 -6
- package/docs/apis/servers/mcp.md +2 -2
- package/docs/examples/entity.md +124 -0
- package/package.json +73 -21
- package/src/agi/feature.ts +13 -0
- package/src/agi/features/assistant.ts +36 -25
- package/src/agi/features/assistants-manager.ts +70 -5
- package/src/agi/features/autonomous-assistant.ts +1 -5
- package/src/agi/features/browser-use.ts +2 -2
- package/src/agi/features/claude-code.ts +165 -1
- package/src/agi/features/conversation-history.ts +2 -6
- package/src/agi/features/conversation.ts +95 -3
- package/src/agi/features/docs-reader.ts +2 -1
- package/src/agi/features/file-tools.ts +2 -2
- package/src/agi/features/luca-coder.ts +1 -5
- package/src/agi/features/openai-codex.ts +1 -1
- package/src/agi/features/openapi.ts +3 -3
- package/src/agi/features/skills-library.ts +87 -6
- package/src/agi/lib/interceptor-chain.ts +10 -0
- package/src/agi/lib/token-counter.ts +1 -1
- package/src/bootstrap/generated.ts +126 -1
- package/src/bus.ts +27 -5
- package/src/cli/build-info.ts +2 -2
- package/src/client.ts +2 -2
- package/src/clients/elevenlabs/index.ts +5 -0
- package/src/commands/bootstrap.ts +2 -1
- package/src/commands/chat.ts +1 -0
- package/src/commands/code.ts +4 -2
- package/src/commands/prompt.ts +34 -34
- package/src/commands/sandbox-mcp.ts +69 -163
- package/src/commands/save-api-docs.ts +10 -8
- package/src/commands/select.ts +8 -3
- package/src/container-describer.ts +70 -84
- package/src/container.ts +93 -3
- package/src/endpoint.ts +1 -1
- package/src/entity.ts +173 -0
- package/src/feature.ts +3 -3
- package/src/helper.ts +8 -4
- package/src/introspection/generated.agi.ts +1246 -798
- package/src/introspection/generated.node.ts +892 -798
- package/src/introspection/generated.web.ts +95 -3
- package/src/introspection/scan.ts +1 -1
- package/src/node/container.ts +1 -1
- package/src/node/features/content-db.ts +3 -3
- package/src/node/features/file-manager.ts +10 -9
- package/src/node/features/git.ts +5 -5
- package/src/node/features/helpers.ts +1 -1
- package/src/node/features/json-tree.ts +1 -1
- package/src/node/features/os.ts +3 -3
- package/src/node/features/package-finder.ts +1 -1
- package/src/node/features/process-manager.ts +1 -1
- package/src/node/features/python.ts +3 -3
- package/src/node/features/redis.ts +1 -1
- package/src/node/features/repl.ts +2 -2
- package/src/node/features/transpiler.ts +2 -2
- package/src/node/features/ui.ts +1 -1
- package/src/node/features/vm.ts +3 -3
- package/src/node/features/yaml-tree.ts +1 -1
- package/src/node.ts +1 -0
- package/src/python/generated.ts +1 -1
- package/src/scaffolds/generated.ts +1 -1
- package/src/selector.ts +74 -4
- package/src/server.ts +2 -2
- package/src/servers/mcp.ts +6 -6
- package/src/web/features/helpers.ts +1 -1
- package/src/web/features/network.ts +1 -0
- package/test/conversation.test.ts +220 -0
- package/tsconfig.build.json +12 -0
- package/tsconfig.json +1 -1
- package/scripts/examples/telegram-ink-ui.ts +0 -302
- package/scripts/examples/using-openai-codex.ts +0 -23
- package/scripts/examples/vm-loading-esm-modules.ts +0 -16
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Auto-generated bootstrap content
|
|
2
|
-
// Generated at: 2026-
|
|
2
|
+
// Generated at: 2026-04-03T01:24:53.975Z
|
|
3
3
|
// Source: docs/bootstrap/*.md, docs/bootstrap/templates/*, docs/examples/*.md, docs/tutorials/*.md
|
|
4
4
|
//
|
|
5
5
|
// Do not edit manually. Run: luca build-bootstrap
|
|
@@ -1253,6 +1253,131 @@ console.log('Running after killAll:', remaining.length)
|
|
|
1253
1253
|
## Summary
|
|
1254
1254
|
|
|
1255
1255
|
This demo covered the \`processManager\` feature: spawning processes that return handles immediately, tracking them by ID or tag, listing all tracked processes, and killing them individually or all at once. It is the right tool for orchestrating background services, dev servers, and any scenario where you need non-blocking process management with lifecycle events.
|
|
1256
|
+
`,
|
|
1257
|
+
"entity.md": `---
|
|
1258
|
+
title: "Entity"
|
|
1259
|
+
tags: [entity, state, events, tools, core]
|
|
1260
|
+
lastTested: null
|
|
1261
|
+
lastTestPassed: null
|
|
1262
|
+
---
|
|
1263
|
+
|
|
1264
|
+
# entity
|
|
1265
|
+
|
|
1266
|
+
Lightweight, composable objects with observable state, a typed event bus, and an optional tool interface.
|
|
1267
|
+
|
|
1268
|
+
## Overview
|
|
1269
|
+
|
|
1270
|
+
An entity is a plain object — not a class — created via \`container.entity(id, options?)\`. Same id + options always returns the same underlying state and bus instance. Entities are designed to be extended with methods and getters via \`.extend()\`, and can expose those methods as AI tools via \`.expose()\`.
|
|
1271
|
+
|
|
1272
|
+
## Basic Entity with Observable State
|
|
1273
|
+
|
|
1274
|
+
Create an entity and read/write state through the observable \`state\` property.
|
|
1275
|
+
|
|
1276
|
+
\`\`\`ts
|
|
1277
|
+
const counter = container.entity<{ count: number }>('counter')
|
|
1278
|
+
counter.setState({ count: 0 })
|
|
1279
|
+
|
|
1280
|
+
counter.state.observe((next) => {
|
|
1281
|
+
console.log('count changed to', next.count)
|
|
1282
|
+
})
|
|
1283
|
+
|
|
1284
|
+
counter.setState(s => ({ count: s.count + 1 }))
|
|
1285
|
+
counter.setState(s => ({ count: s.count + 1 }))
|
|
1286
|
+
console.log('final count:', counter.state.get('count'))
|
|
1287
|
+
\`\`\`
|
|
1288
|
+
|
|
1289
|
+
\`setState\` accepts either a partial object or a function that receives the current state. Observers fire synchronously after each change.
|
|
1290
|
+
|
|
1291
|
+
## Typed Event Bus
|
|
1292
|
+
|
|
1293
|
+
Every entity has a built-in event bus. Declare the event map as the third type parameter.
|
|
1294
|
+
|
|
1295
|
+
\`\`\`ts
|
|
1296
|
+
type TimerEvents = {
|
|
1297
|
+
tick: [elapsed: number]
|
|
1298
|
+
done: []
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
const timer = container.entity<{}, {}, TimerEvents>('timer')
|
|
1302
|
+
|
|
1303
|
+
timer.on('tick', (elapsed) => {
|
|
1304
|
+
console.log('tick at', elapsed, 'ms')
|
|
1305
|
+
})
|
|
1306
|
+
|
|
1307
|
+
timer.once('done', () => {
|
|
1308
|
+
console.log('timer finished')
|
|
1309
|
+
})
|
|
1310
|
+
|
|
1311
|
+
timer.emit('tick', 100)
|
|
1312
|
+
timer.emit('tick', 200)
|
|
1313
|
+
timer.emit('done')
|
|
1314
|
+
\`\`\`
|
|
1315
|
+
|
|
1316
|
+
\`once\` auto-detaches after the first fire. \`waitFor\` returns a promise that resolves on the next emit of that event.
|
|
1317
|
+
|
|
1318
|
+
## Extending with Methods
|
|
1319
|
+
|
|
1320
|
+
Use \`.extend()\` to graft methods and getters onto an entity. All base properties — \`state\`, \`options\`, \`container\`, and the event methods — are available via \`this\`.
|
|
1321
|
+
|
|
1322
|
+
\`\`\`ts
|
|
1323
|
+
const session = container.entity('session', { userId: '42' })
|
|
1324
|
+
.extend({
|
|
1325
|
+
greet() {
|
|
1326
|
+
return \`Hello user \${this.options.userId}\`
|
|
1327
|
+
},
|
|
1328
|
+
get label() {
|
|
1329
|
+
return \`Session \${this.id} (user \${this.options.userId})\`
|
|
1330
|
+
},
|
|
1331
|
+
bump() {
|
|
1332
|
+
const visits = (this.state.get('visits') ?? 0) + 1
|
|
1333
|
+
this.setState({ visits })
|
|
1334
|
+
this.emit('visited', visits)
|
|
1335
|
+
return visits
|
|
1336
|
+
},
|
|
1337
|
+
})
|
|
1338
|
+
|
|
1339
|
+
console.log(session.greet())
|
|
1340
|
+
console.log(session.label)
|
|
1341
|
+
console.log('visits:', session.bump())
|
|
1342
|
+
console.log('visits:', session.bump())
|
|
1343
|
+
\`\`\`
|
|
1344
|
+
|
|
1345
|
+
Extensions are chained via prototype delegation — each layer can see everything below it.
|
|
1346
|
+
|
|
1347
|
+
## Exposing Methods as AI Tools
|
|
1348
|
+
|
|
1349
|
+
Use \`.expose(methodName, zodSchema)\` to register methods as tools. \`.toTools()\` returns \`{ schemas, handlers }\` compatible with \`assistant.addTools()\`.
|
|
1350
|
+
|
|
1351
|
+
\`\`\`ts
|
|
1352
|
+
const search = container.entity('search', {})
|
|
1353
|
+
.extend({
|
|
1354
|
+
async lookup({ query }: { query: string }) {
|
|
1355
|
+
return \`Results for: \${query}\`
|
|
1356
|
+
},
|
|
1357
|
+
async summarize({ text, maxWords }: { text: string; maxWords: number }) {
|
|
1358
|
+
return text.split(' ').slice(0, maxWords).join(' ')
|
|
1359
|
+
},
|
|
1360
|
+
})
|
|
1361
|
+
.expose('lookup', z.object({
|
|
1362
|
+
query: z.string().describe('The search query'),
|
|
1363
|
+
}))
|
|
1364
|
+
.expose('summarize', z.object({
|
|
1365
|
+
text: z.string().describe('Text to summarize'),
|
|
1366
|
+
maxWords: z.number().describe('Maximum words in summary'),
|
|
1367
|
+
}))
|
|
1368
|
+
|
|
1369
|
+
const { schemas, handlers } = search.toTools()
|
|
1370
|
+
console.log('registered tools:', Object.keys(schemas))
|
|
1371
|
+
|
|
1372
|
+
// Pass directly to an assistant
|
|
1373
|
+
// assistant.addTools(search)
|
|
1374
|
+
\`\`\`
|
|
1375
|
+
|
|
1376
|
+
\`.expose()\` is chainable and returns \`this\`, so you can stack as many as you need.
|
|
1377
|
+
|
|
1378
|
+
## Summary
|
|
1379
|
+
|
|
1380
|
+
Entities give you observable state, a typed event bus, and prototype-safe method extension — all as a plain object with no class overhead. The \`.expose()\` / \`.toTools()\` interface makes it straightforward to surface entity methods as AI tools.
|
|
1256
1381
|
`,
|
|
1257
1382
|
"assistant-with-process-manager.md": `---
|
|
1258
1383
|
title: "Assistant with ProcessManager Tools"
|
package/src/bus.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export type EventMap = Record<string, any[]>;
|
|
2
2
|
|
|
3
3
|
type Listener<Args extends any[] = any[]> = (...args: Args) => void;
|
|
4
|
+
type WildcardListener = (event: string, ...args: any[]) => void;
|
|
4
5
|
|
|
5
6
|
export interface EventStats {
|
|
6
7
|
event: string;
|
|
@@ -12,10 +13,12 @@ export interface EventStats {
|
|
|
12
13
|
|
|
13
14
|
export class Bus<T extends EventMap = EventMap> {
|
|
14
15
|
private events: Map<string, Listener[]>;
|
|
16
|
+
private wildcardListeners: WildcardListener[];
|
|
15
17
|
private stats: Map<string, { fireCount: number; lastFiredAt: number | null; timestamps: number[] }>;
|
|
16
18
|
|
|
17
19
|
constructor() {
|
|
18
20
|
this.events = new Map();
|
|
21
|
+
this.wildcardListeners = [];
|
|
19
22
|
this.stats = new Map();
|
|
20
23
|
}
|
|
21
24
|
|
|
@@ -64,12 +67,19 @@ export class Bus<T extends EventMap = EventMap> {
|
|
|
64
67
|
emit<E extends string & keyof T>(event: E, ...args: T[E]): void {
|
|
65
68
|
this.recordEmit(event);
|
|
66
69
|
const listeners = this.events.get(event);
|
|
67
|
-
if (
|
|
68
|
-
|
|
69
|
-
|
|
70
|
+
if (listeners) {
|
|
71
|
+
listeners.forEach(listener => listener(...args));
|
|
72
|
+
}
|
|
73
|
+
this.wildcardListeners.forEach(listener => listener(event, ...args));
|
|
70
74
|
}
|
|
71
75
|
|
|
72
|
-
on
|
|
76
|
+
on(event: '*', listener: WildcardListener): void
|
|
77
|
+
on<E extends string & keyof T>(event: E, listener: (...args: T[E]) => void): void
|
|
78
|
+
on<E extends string & keyof T>(event: E | '*', listener: any): void {
|
|
79
|
+
if (event === '*') {
|
|
80
|
+
this.wildcardListeners.push(listener);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
73
83
|
const listeners = this.events.get(event) || [];
|
|
74
84
|
listeners.push(listener as Listener);
|
|
75
85
|
this.events.set(event, listeners);
|
|
@@ -83,7 +93,19 @@ export class Bus<T extends EventMap = EventMap> {
|
|
|
83
93
|
this.on(event, onceListener as any);
|
|
84
94
|
}
|
|
85
95
|
|
|
86
|
-
off
|
|
96
|
+
off(event: '*', listener?: WildcardListener): void
|
|
97
|
+
off<E extends string & keyof T>(event: E, listener?: (...args: T[E]) => void): void
|
|
98
|
+
off<E extends string & keyof T>(event: E | '*', listener?: any): void {
|
|
99
|
+
if (event === '*') {
|
|
100
|
+
if (!listener) {
|
|
101
|
+
this.wildcardListeners = [];
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const index = this.wildcardListeners.indexOf(listener);
|
|
105
|
+
if (index !== -1) this.wildcardListeners.splice(index, 1);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
87
109
|
const listeners = this.events.get(event);
|
|
88
110
|
if (!listeners) return;
|
|
89
111
|
|
package/src/cli/build-info.ts
CHANGED
package/src/client.ts
CHANGED
|
@@ -46,7 +46,7 @@ export class Client<
|
|
|
46
46
|
static override eventsSchema = ClientEventsSchema
|
|
47
47
|
|
|
48
48
|
/** Self-register a Client subclass from a static initialization block. */
|
|
49
|
-
static register: (SubClass:
|
|
49
|
+
static register: (SubClass: abstract new (options: any, context: any) => Client, id?: string) => abstract new (options: any, context: any) => Client
|
|
50
50
|
|
|
51
51
|
static attach(container: Container & ClientsInterface): any {
|
|
52
52
|
Object.assign(container, {
|
|
@@ -141,7 +141,7 @@ export const helperCache = new Map();
|
|
|
141
141
|
* ```
|
|
142
142
|
*/
|
|
143
143
|
Client.register = function registerClient(
|
|
144
|
-
SubClass:
|
|
144
|
+
SubClass: abstract new (options: any, context: any) => Client,
|
|
145
145
|
id?: string,
|
|
146
146
|
) {
|
|
147
147
|
const registryId = id ?? SubClass.name[0]!.toLowerCase() + SubClass.name.slice(1)
|
|
@@ -3,6 +3,7 @@ import { ClientStateSchema, ClientOptionsSchema, ClientEventsSchema } from '@soe
|
|
|
3
3
|
import { Client } from "@soederpop/luca/client";
|
|
4
4
|
import { RestClient } from "../rest";
|
|
5
5
|
import type { ContainerContext } from "@soederpop/luca/container";
|
|
6
|
+
import type { NodeContainer } from "../../node/container.js";
|
|
6
7
|
import type { AxiosRequestConfig } from 'axios'
|
|
7
8
|
|
|
8
9
|
declare module "@soederpop/luca/client" {
|
|
@@ -92,6 +93,10 @@ export class ElevenLabsClient extends RestClient<ElevenLabsClientState, ElevenLa
|
|
|
92
93
|
super(options, context)
|
|
93
94
|
}
|
|
94
95
|
|
|
96
|
+
override get container(): NodeContainer {
|
|
97
|
+
return super.container as unknown as NodeContainer
|
|
98
|
+
}
|
|
99
|
+
|
|
95
100
|
/** The resolved API key from options or environment. */
|
|
96
101
|
get apiKey(): string {
|
|
97
102
|
return this.options.apiKey || process.env.ELEVENLABS_API_KEY || ''
|
|
@@ -2,6 +2,7 @@ import { z } from 'zod'
|
|
|
2
2
|
import { commands } from '../command.js'
|
|
3
3
|
import { CommandOptionsSchema } from '../schemas/base.js'
|
|
4
4
|
import type { ContainerContext } from '../container.js'
|
|
5
|
+
import type { NodeContainer } from '../node/container.js'
|
|
5
6
|
import { bootstrapFiles, bootstrapTemplates, bootstrapExamples, bootstrapTutorials } from '../bootstrap/generated.js'
|
|
6
7
|
import { generateScaffold } from '../scaffolds/template.js'
|
|
7
8
|
|
|
@@ -17,7 +18,7 @@ export const argsSchema = CommandOptionsSchema.extend({
|
|
|
17
18
|
})
|
|
18
19
|
|
|
19
20
|
async function bootstrap(options: z.infer<typeof argsSchema>, context: ContainerContext) {
|
|
20
|
-
const
|
|
21
|
+
const container = context.container as unknown as NodeContainer
|
|
21
22
|
const args = container.argv._ as string[]
|
|
22
23
|
const fs = container.feature('fs')
|
|
23
24
|
const ui = container.feature('ui')
|
package/src/commands/chat.ts
CHANGED
|
@@ -186,6 +186,7 @@ export default async function chat(options: z.infer<typeof argsSchema>, context:
|
|
|
186
186
|
const items = Array.isArray(options.use) ? options.use : [options.use]
|
|
187
187
|
for (const item of items) {
|
|
188
188
|
const [namepart, optStr] = item.split(':')
|
|
189
|
+
if (!namepart) continue
|
|
189
190
|
const featureOpts: Record<string, any> = { enable: true }
|
|
190
191
|
if (optStr) {
|
|
191
192
|
for (const pair of optStr.split(';')) {
|
package/src/commands/code.ts
CHANGED
|
@@ -36,7 +36,7 @@ export default async function code(options: z.infer<typeof argsSchema>, context:
|
|
|
36
36
|
if (options.prompt) {
|
|
37
37
|
const resolved = container.paths.resolve(options.prompt)
|
|
38
38
|
if (fs.exists(resolved)) {
|
|
39
|
-
systemPrompt = fs.readFile(resolved)
|
|
39
|
+
systemPrompt = String(fs.readFile(resolved))
|
|
40
40
|
} else if (!options.prompt.endsWith('.md')) {
|
|
41
41
|
systemPrompt = options.prompt
|
|
42
42
|
} else {
|
|
@@ -81,6 +81,8 @@ export default async function code(options: z.infer<typeof argsSchema>, context:
|
|
|
81
81
|
model: options.model,
|
|
82
82
|
local: options.local,
|
|
83
83
|
skills: extraSkills,
|
|
84
|
+
maxTokens: 2048,
|
|
85
|
+
autoLoadLucaSkill: true,
|
|
84
86
|
})
|
|
85
87
|
|
|
86
88
|
// ── UI setup ───────────────────────────────────────────────────────────
|
|
@@ -319,7 +321,7 @@ export default async function code(options: z.infer<typeof argsSchema>, context:
|
|
|
319
321
|
|
|
320
322
|
const featureContext: Record<string, any> = {}
|
|
321
323
|
for (const fname of container.features.available) {
|
|
322
|
-
try { featureContext[fname] = container.feature(fname) } catch {}
|
|
324
|
+
try { featureContext[fname] = (container as any).feature(fname) } catch {}
|
|
323
325
|
}
|
|
324
326
|
|
|
325
327
|
const replPrompt = ui.colors.magenta('console') + ui.colors.dim(' > ')
|
package/src/commands/prompt.ts
CHANGED
|
@@ -257,16 +257,16 @@ async function runParallel(
|
|
|
257
257
|
|
|
258
258
|
function pushLines(idx: number, text: string) {
|
|
259
259
|
const newLines = text.split('\n')
|
|
260
|
-
promptStates[idx]
|
|
261
|
-
if (promptStates[idx]
|
|
262
|
-
promptStates[idx]
|
|
260
|
+
promptStates[idx]!.lines.push(...newLines)
|
|
261
|
+
if (promptStates[idx]!.lines.length > MAX_LINES) {
|
|
262
|
+
promptStates[idx]!.lines = promptStates[idx]!.lines.slice(-MAX_LINES)
|
|
263
263
|
}
|
|
264
264
|
}
|
|
265
265
|
|
|
266
266
|
function pushToolLine(idx: number, text: string) {
|
|
267
|
-
promptStates[idx]
|
|
268
|
-
if (promptStates[idx]
|
|
269
|
-
promptStates[idx]
|
|
267
|
+
promptStates[idx]!.lines.push(text)
|
|
268
|
+
if (promptStates[idx]!.lines.length > MAX_LINES) {
|
|
269
|
+
promptStates[idx]!.lines.splice(0, 1)
|
|
270
270
|
}
|
|
271
271
|
}
|
|
272
272
|
|
|
@@ -304,7 +304,7 @@ async function runParallel(
|
|
|
304
304
|
if (!Array.isArray(content)) return
|
|
305
305
|
|
|
306
306
|
const usage = message?.message?.usage ?? message?.usage
|
|
307
|
-
if (usage?.output_tokens) promptStates[idx]
|
|
307
|
+
if (usage?.output_tokens) promptStates[idx]!.outputTokens += usage.output_tokens
|
|
308
308
|
|
|
309
309
|
for (const block of content) {
|
|
310
310
|
if (block.type === 'text' && block.text) {
|
|
@@ -321,33 +321,33 @@ async function runParallel(
|
|
|
321
321
|
const idx = sessionMap.get(sessionId)
|
|
322
322
|
if (idx === undefined) return
|
|
323
323
|
if (event.type === 'assistant' || event.type === 'tool_result' || event.type === 'message' || event.type === 'function_call_output') {
|
|
324
|
-
promptStates[idx]
|
|
324
|
+
promptStates[idx]!.collectedEvents.push(event)
|
|
325
325
|
}
|
|
326
326
|
})
|
|
327
327
|
}
|
|
328
328
|
|
|
329
329
|
// Start all sessions — merge per-prompt agentOptions with shared runOptions
|
|
330
330
|
for (let i = 0; i < prepared.length; i++) {
|
|
331
|
-
const perPromptOptions = { ...prepared[i]
|
|
331
|
+
const perPromptOptions = { ...prepared[i]!.agentOptions, ...runOptions }
|
|
332
332
|
if (options.model) perPromptOptions.model = options.model
|
|
333
|
-
const id = await feature.start(prepared[i]
|
|
333
|
+
const id = await feature.start(prepared[i]!.promptContent, perPromptOptions)
|
|
334
334
|
sessionMap.set(id, i)
|
|
335
335
|
}
|
|
336
336
|
|
|
337
337
|
const ids = [...sessionMap.keys()]
|
|
338
338
|
sessionPromise = Promise.allSettled(ids.map((id) => feature.waitForSession(id))).then((results) => {
|
|
339
339
|
results.forEach((r, ri) => {
|
|
340
|
-
const id = ids[ri]
|
|
340
|
+
const id = ids[ri]!
|
|
341
341
|
const idx = sessionMap.get(id)!
|
|
342
|
-
promptStates[idx]
|
|
342
|
+
promptStates[idx]!.durationMs = Date.now() - promptStates[idx]!.startTime
|
|
343
343
|
if (r.status === 'fulfilled' && r.value?.status === 'error') {
|
|
344
|
-
promptStates[idx]
|
|
345
|
-
promptStates[idx]
|
|
344
|
+
promptStates[idx]!.status = 'error'
|
|
345
|
+
promptStates[idx]!.error = r.value?.error || 'Session failed'
|
|
346
346
|
} else if (r.status === 'rejected') {
|
|
347
|
-
promptStates[idx]
|
|
348
|
-
promptStates[idx]
|
|
347
|
+
promptStates[idx]!.status = 'error'
|
|
348
|
+
promptStates[idx]!.error = String(r.reason)
|
|
349
349
|
} else {
|
|
350
|
-
promptStates[idx]
|
|
350
|
+
promptStates[idx]!.status = 'done'
|
|
351
351
|
}
|
|
352
352
|
})
|
|
353
353
|
allDone = true
|
|
@@ -375,16 +375,16 @@ async function runParallel(
|
|
|
375
375
|
|
|
376
376
|
assistant.on('chunk', (text: string) => {
|
|
377
377
|
lineBuffers[i] += text
|
|
378
|
-
const parts = lineBuffers[i]
|
|
378
|
+
const parts = lineBuffers[i]!.split('\n')
|
|
379
379
|
lineBuffers[i] = parts.pop() || ''
|
|
380
380
|
if (parts.length) {
|
|
381
|
-
promptStates[i]
|
|
382
|
-
if (promptStates[i]
|
|
383
|
-
promptStates[i]
|
|
381
|
+
promptStates[i]!.lines.push(...parts)
|
|
382
|
+
if (promptStates[i]!.lines.length > MAX_LINES) {
|
|
383
|
+
promptStates[i]!.lines = promptStates[i]!.lines.slice(-MAX_LINES)
|
|
384
384
|
}
|
|
385
385
|
}
|
|
386
386
|
if (options['out-file']) {
|
|
387
|
-
promptStates[i]
|
|
387
|
+
promptStates[i]!.collectedEvents.push({ type: 'assistant', message: { content: [{ type: 'text', text }] } })
|
|
388
388
|
}
|
|
389
389
|
})
|
|
390
390
|
|
|
@@ -392,7 +392,7 @@ async function runParallel(
|
|
|
392
392
|
const argsStr = JSON.stringify(args).slice(0, 80)
|
|
393
393
|
pushToolLine(i, ` > ${toolName}(${argsStr})`)
|
|
394
394
|
if (options['out-file']) {
|
|
395
|
-
promptStates[i]
|
|
395
|
+
promptStates[i]!.collectedEvents.push({
|
|
396
396
|
type: 'assistant',
|
|
397
397
|
message: { content: [{ type: 'tool_use', name: toolName, input: args }] },
|
|
398
398
|
})
|
|
@@ -403,7 +403,7 @@ async function runParallel(
|
|
|
403
403
|
const preview = typeof result === 'string' ? result.slice(0, 60) : JSON.stringify(result).slice(0, 60)
|
|
404
404
|
pushToolLine(i, ` ✓ ${toolName} → ${preview}`)
|
|
405
405
|
if (options['out-file']) {
|
|
406
|
-
promptStates[i]
|
|
406
|
+
promptStates[i]!.collectedEvents.push({
|
|
407
407
|
type: 'tool_result',
|
|
408
408
|
content: typeof result === 'string' ? result : JSON.stringify(result, null, 2),
|
|
409
409
|
})
|
|
@@ -418,20 +418,20 @@ async function runParallel(
|
|
|
418
418
|
return assistant
|
|
419
419
|
})
|
|
420
420
|
|
|
421
|
-
sessionPromise = Promise.allSettled(assistants.map((a, i) => a.ask(prepared[i]
|
|
421
|
+
sessionPromise = Promise.allSettled(assistants.map((a, i) => a.ask(prepared[i]!.promptContent))).then(
|
|
422
422
|
(results) => {
|
|
423
423
|
results.forEach((r, i) => {
|
|
424
|
-
promptStates[i]
|
|
424
|
+
promptStates[i]!.durationMs = Date.now() - promptStates[i]!.startTime
|
|
425
425
|
// Flush remaining line buffer
|
|
426
426
|
if (lineBuffers[i]) {
|
|
427
|
-
promptStates[i]
|
|
427
|
+
promptStates[i]!.lines.push(lineBuffers[i]!)
|
|
428
428
|
lineBuffers[i] = ''
|
|
429
429
|
}
|
|
430
430
|
if (r.status === 'rejected') {
|
|
431
|
-
promptStates[i]
|
|
432
|
-
promptStates[i]
|
|
431
|
+
promptStates[i]!.status = 'error'
|
|
432
|
+
promptStates[i]!.error = String(r.reason)
|
|
433
433
|
} else {
|
|
434
|
-
promptStates[i]
|
|
434
|
+
promptStates[i]!.status = 'done'
|
|
435
435
|
}
|
|
436
436
|
})
|
|
437
437
|
allDone = true
|
|
@@ -551,9 +551,9 @@ async function runParallel(
|
|
|
551
551
|
const stem = dotIdx > 0 ? base.slice(0, dotIdx) : base
|
|
552
552
|
|
|
553
553
|
for (let i = 0; i < promptStates.length; i++) {
|
|
554
|
-
const ps = promptStates[i]
|
|
554
|
+
const ps = promptStates[i]!
|
|
555
555
|
if (!ps.collectedEvents.length) continue
|
|
556
|
-
const promptBasename = paths.basename(prepared[i]
|
|
556
|
+
const promptBasename = paths.basename(prepared[i]!.resolvedPath)
|
|
557
557
|
const promptStem = promptBasename.lastIndexOf('.') > 0 ? promptBasename.slice(0, promptBasename.lastIndexOf('.')) : promptBasename
|
|
558
558
|
const outPath = paths.resolve(`${stem}-${promptStem}${ext}`)
|
|
559
559
|
const markdown = formatSessionMarkdown(ps.collectedEvents, options['include-output'])
|
|
@@ -655,7 +655,7 @@ async function resolveInputs(
|
|
|
655
655
|
|
|
656
656
|
// Build wizard questions for missing inputs
|
|
657
657
|
const questions = missing.map((key) => {
|
|
658
|
-
const def = inputDefs[key]
|
|
658
|
+
const def = inputDefs[key]!
|
|
659
659
|
const q: Record<string, any> = {
|
|
660
660
|
name: key,
|
|
661
661
|
message: def.description || key,
|
|
@@ -920,7 +920,7 @@ export default async function prompt(options: z.infer<typeof argsSchema>, contex
|
|
|
920
920
|
}
|
|
921
921
|
|
|
922
922
|
// --- Single prompt mode ---
|
|
923
|
-
const promptPath = allPaths[0]
|
|
923
|
+
const promptPath = allPaths[0]!
|
|
924
924
|
const p = await preparePrompt(promptPath, options, container)
|
|
925
925
|
|
|
926
926
|
if (!p) {
|