@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
|
@@ -136,7 +136,7 @@ export class Helpers extends Feature<HelpersState, HelpersOptions> {
|
|
|
136
136
|
return {}
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
-
const manifest
|
|
139
|
+
const manifest = await response.json() as Manifest
|
|
140
140
|
this._manifest = manifest
|
|
141
141
|
this.state.set('manifestLoaded', true)
|
|
142
142
|
this.emit('manifestLoaded' as any, manifest)
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from 'bun:test'
|
|
2
|
+
import { AGIContainer } from '../src/agi/container.server'
|
|
3
|
+
import type { Conversation } from '../src/agi/features/conversation'
|
|
4
|
+
|
|
5
|
+
function makeConversation(opts: Record<string, any> = {}): Conversation {
|
|
6
|
+
const container = new AGIContainer()
|
|
7
|
+
return container.feature('conversation', { model: 'gpt-5', ...opts }) as Conversation
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
describe('Conversation', () => {
|
|
11
|
+
describe('state', () => {
|
|
12
|
+
it('initializes with empty messages when no history provided', () => {
|
|
13
|
+
const conv = makeConversation()
|
|
14
|
+
expect(conv.messages).toEqual([])
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
it('seeds message history from options', () => {
|
|
18
|
+
const history = [{ role: 'system', content: 'You are helpful.' }]
|
|
19
|
+
const conv = makeConversation({ history })
|
|
20
|
+
expect(conv.messages).toHaveLength(1)
|
|
21
|
+
expect(conv.messages[0]).toEqual(history[0])
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
it('uses provided model', () => {
|
|
25
|
+
const conv = makeConversation({ model: 'gpt-4.1' })
|
|
26
|
+
expect(conv.model).toBe('gpt-4.1')
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
it('isStreaming is false initially', () => {
|
|
30
|
+
const conv = makeConversation()
|
|
31
|
+
expect(conv.isStreaming).toBe(false)
|
|
32
|
+
})
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
describe('pushMessage', () => {
|
|
36
|
+
it('appends to messages', () => {
|
|
37
|
+
const conv = makeConversation()
|
|
38
|
+
conv.pushMessage({ role: 'user', content: 'hello' })
|
|
39
|
+
expect(conv.messages).toHaveLength(1)
|
|
40
|
+
expect(conv.messages[0]!.role).toBe('user')
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
it('does not mutate prior messages array', () => {
|
|
44
|
+
const conv = makeConversation()
|
|
45
|
+
const before = conv.messages
|
|
46
|
+
conv.pushMessage({ role: 'user', content: 'hi' })
|
|
47
|
+
expect(conv.messages).not.toBe(before)
|
|
48
|
+
})
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
describe('tools', () => {
|
|
52
|
+
it('starts with no tools', () => {
|
|
53
|
+
const conv = makeConversation()
|
|
54
|
+
expect(conv.availableTools).toHaveLength(0)
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
it('addTool registers a tool', () => {
|
|
58
|
+
const conv = makeConversation()
|
|
59
|
+
conv.addTool('greet', {
|
|
60
|
+
description: 'Says hello',
|
|
61
|
+
parameters: { type: 'object', properties: {} },
|
|
62
|
+
handler: async () => 'hello',
|
|
63
|
+
})
|
|
64
|
+
expect(conv.availableTools).toContain('greet')
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
it('removeTool deregisters a tool', () => {
|
|
68
|
+
const conv = makeConversation()
|
|
69
|
+
conv.addTool('greet', {
|
|
70
|
+
description: 'Says hello',
|
|
71
|
+
parameters: { type: 'object', properties: {} },
|
|
72
|
+
handler: async () => 'hello',
|
|
73
|
+
})
|
|
74
|
+
conv.removeTool('greet')
|
|
75
|
+
expect(conv.availableTools).not.toContain('greet')
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
it('updateTools merges without replacing unrelated tools', () => {
|
|
79
|
+
const conv = makeConversation()
|
|
80
|
+
conv.addTool('a', { description: 'A', parameters: { type: 'object', properties: {} }, handler: async () => 'a' })
|
|
81
|
+
conv.updateTools({ b: { description: 'B', parameters: { type: 'object', properties: {} }, handler: async () => 'b' } })
|
|
82
|
+
expect(conv.availableTools).toContain('a')
|
|
83
|
+
expect(conv.availableTools).toContain('b')
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it('construction-time tools are available immediately', () => {
|
|
87
|
+
const conv = makeConversation({
|
|
88
|
+
tools: {
|
|
89
|
+
ping: { description: 'Ping', parameters: { type: 'object', properties: {} }, handler: async () => 'pong' }
|
|
90
|
+
}
|
|
91
|
+
})
|
|
92
|
+
expect(conv.availableTools).toContain('ping')
|
|
93
|
+
})
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
describe('estimateTokens', () => {
|
|
97
|
+
it('returns a near-zero baseline for empty messages', () => {
|
|
98
|
+
const conv = makeConversation()
|
|
99
|
+
expect(conv.estimateTokens()).toBeLessThan(10)
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
it('returns a positive number when messages exist', () => {
|
|
103
|
+
const conv = makeConversation({
|
|
104
|
+
history: [{ role: 'user', content: 'What is the capital of France?' }]
|
|
105
|
+
})
|
|
106
|
+
expect(conv.estimateTokens()).toBeGreaterThan(0)
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
it('increases as more messages are added', () => {
|
|
110
|
+
const conv = makeConversation()
|
|
111
|
+
conv.pushMessage({ role: 'user', content: 'Hello' })
|
|
112
|
+
const first = conv.estimateTokens()
|
|
113
|
+
conv.pushMessage({ role: 'assistant', content: 'Hi there, how can I help you today?' })
|
|
114
|
+
const second = conv.estimateTokens()
|
|
115
|
+
expect(second).toBeGreaterThan(first)
|
|
116
|
+
})
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
describe('stub()', () => {
|
|
120
|
+
it('exact string match returns the stub response', async () => {
|
|
121
|
+
const conv = makeConversation()
|
|
122
|
+
conv.stub('ping', 'pong')
|
|
123
|
+
const result = await conv.ask('ping')
|
|
124
|
+
expect(result).toBe('pong')
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
it('substring match triggers the stub', async () => {
|
|
128
|
+
const conv = makeConversation()
|
|
129
|
+
conv.stub('weather', 'Sunny and 72°F.')
|
|
130
|
+
const result = await conv.ask('what is the weather today?')
|
|
131
|
+
expect(result).toBe('Sunny and 72°F.')
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
it('regex match triggers the stub', async () => {
|
|
135
|
+
const conv = makeConversation()
|
|
136
|
+
conv.stub(/hello/i, 'Hey there!')
|
|
137
|
+
const result = await conv.ask('HELLO')
|
|
138
|
+
expect(result).toBe('Hey there!')
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
it('function response is called on each match', async () => {
|
|
142
|
+
const conv = makeConversation()
|
|
143
|
+
let callCount = 0
|
|
144
|
+
conv.stub('count', () => `call ${++callCount}`)
|
|
145
|
+
expect(await conv.ask('count')).toBe('call 1')
|
|
146
|
+
expect(await conv.ask('count')).toBe('call 2')
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
it('first matching stub wins', async () => {
|
|
150
|
+
const conv = makeConversation()
|
|
151
|
+
conv.stub('hello', 'first')
|
|
152
|
+
conv.stub('hello', 'second')
|
|
153
|
+
expect(await conv.ask('hello')).toBe('first')
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
it('appends user and assistant messages to history', async () => {
|
|
157
|
+
const conv = makeConversation()
|
|
158
|
+
conv.stub('hi', 'hello back')
|
|
159
|
+
await conv.ask('hi')
|
|
160
|
+
expect(conv.messages).toHaveLength(2)
|
|
161
|
+
expect(conv.messages[0]).toMatchObject({ role: 'user', content: 'hi' })
|
|
162
|
+
expect(conv.messages[1]).toMatchObject({ role: 'assistant', content: 'hello back' })
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
it('isStreaming is false after the call resolves', async () => {
|
|
166
|
+
const conv = makeConversation()
|
|
167
|
+
conv.stub('test', 'response')
|
|
168
|
+
await conv.ask('test')
|
|
169
|
+
expect(conv.isStreaming).toBe(false)
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
it('emits chunk events for each word', async () => {
|
|
173
|
+
const conv = makeConversation()
|
|
174
|
+
conv.stub('go', 'one two three')
|
|
175
|
+
const chunks: string[] = []
|
|
176
|
+
conv.on('chunk', (delta: string) => chunks.push(delta))
|
|
177
|
+
await conv.ask('go')
|
|
178
|
+
expect(chunks.join('')).toBe('one two three')
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
it('emits preview events with accumulating text', async () => {
|
|
182
|
+
const conv = makeConversation()
|
|
183
|
+
conv.stub('go', 'alpha beta')
|
|
184
|
+
const previews: string[] = []
|
|
185
|
+
conv.on('preview', (text: string) => previews.push(text))
|
|
186
|
+
await conv.ask('go')
|
|
187
|
+
expect(previews.at(-1)).toBe('alpha beta')
|
|
188
|
+
// Each preview should be longer than or equal to the previous
|
|
189
|
+
for (let i = 1; i < previews.length; i++) {
|
|
190
|
+
expect(previews[i]!.length).toBeGreaterThanOrEqual(previews[i - 1]!.length)
|
|
191
|
+
}
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
it('emits turnStart and turnEnd events', async () => {
|
|
195
|
+
const conv = makeConversation()
|
|
196
|
+
conv.stub('x', 'y')
|
|
197
|
+
const events: string[] = []
|
|
198
|
+
conv.on('turnStart', () => events.push('turnStart'))
|
|
199
|
+
conv.on('turnEnd', () => events.push('turnEnd'))
|
|
200
|
+
await conv.ask('x')
|
|
201
|
+
expect(events).toEqual(['turnStart', 'turnEnd'])
|
|
202
|
+
})
|
|
203
|
+
|
|
204
|
+
it('emits response event with the full text', async () => {
|
|
205
|
+
const conv = makeConversation()
|
|
206
|
+
conv.stub('question', 'the answer')
|
|
207
|
+
let emitted = ''
|
|
208
|
+
conv.on('response', (text: string) => { emitted = text })
|
|
209
|
+
await conv.ask('question')
|
|
210
|
+
expect(emitted).toBe('the answer')
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
it('stub is chainable', () => {
|
|
214
|
+
const conv = makeConversation()
|
|
215
|
+
const result = conv.stub('a', 'A').stub('b', 'B')
|
|
216
|
+
expect(result).toBe(conv)
|
|
217
|
+
expect(conv.availableTools).toHaveLength(0) // stubs don't affect tools
|
|
218
|
+
})
|
|
219
|
+
})
|
|
220
|
+
})
|
package/tsconfig.json
CHANGED
|
@@ -1,302 +0,0 @@
|
|
|
1
|
-
import { spawn, type ChildProcessByStdio } from 'node:child_process'
|
|
2
|
-
import type { Readable } from 'node:stream'
|
|
3
|
-
import path from 'node:path'
|
|
4
|
-
import { existsSync } from 'node:fs'
|
|
5
|
-
import container from '@soederpop/luca/node'
|
|
6
|
-
import { resolveAnimation } from './animations'
|
|
7
|
-
|
|
8
|
-
type ProcessStatus = 'idle' | 'running' | 'exited' | 'error'
|
|
9
|
-
|
|
10
|
-
const MAX_OUTPUT_LINES = 220
|
|
11
|
-
const DEFAULT_ANIMATION = process.env.LUCA_BOT_ANIMATION || 'neonPulse'
|
|
12
|
-
|
|
13
|
-
function splitLines(input: string): string[] {
|
|
14
|
-
return input.replace(/\r\n/g, '\n').replace(/\r/g, '\n').split('\n')
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function pushChunk(target: string[], chunk: string, label?: string) {
|
|
18
|
-
const lines = splitLines(chunk).filter((line) => line.length > 0)
|
|
19
|
-
for (const line of lines) {
|
|
20
|
-
target.push(label ? `[${label}] ${line}` : line)
|
|
21
|
-
}
|
|
22
|
-
if (target.length > MAX_OUTPUT_LINES) {
|
|
23
|
-
target.splice(0, target.length - MAX_OUTPUT_LINES)
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function resolveTelegramScriptPath(): string | null {
|
|
28
|
-
const fromEnv = process.env.LUCA_TELEGRAM_SCRIPT?.trim()
|
|
29
|
-
const candidates = [
|
|
30
|
-
fromEnv,
|
|
31
|
-
'scripts/examples/telegram.ts',
|
|
32
|
-
'scripts/examples/telegram-bot.ts',
|
|
33
|
-
'scripts/telegram.ts',
|
|
34
|
-
'scripts/telegram-bot.ts',
|
|
35
|
-
].filter(Boolean) as string[]
|
|
36
|
-
|
|
37
|
-
for (const candidate of candidates) {
|
|
38
|
-
const resolved = path.isAbsolute(candidate) ? candidate : path.resolve(process.cwd(), candidate)
|
|
39
|
-
if (existsSync(resolved)) return resolved
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return null
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function createBotCommand(): { command: string; args: string[]; source: string } {
|
|
46
|
-
const explicitCommand = process.env.LUCA_TELEGRAM_COMMAND?.trim()
|
|
47
|
-
if (explicitCommand) {
|
|
48
|
-
return {
|
|
49
|
-
command: '/bin/sh',
|
|
50
|
-
args: ['-lc', explicitCommand],
|
|
51
|
-
source: explicitCommand,
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const scriptPath = resolveTelegramScriptPath()
|
|
56
|
-
if (!scriptPath) {
|
|
57
|
-
const helpLines = [
|
|
58
|
-
'No telegram script found.',
|
|
59
|
-
'Set LUCA_TELEGRAM_SCRIPT to your script path, e.g.:',
|
|
60
|
-
' LUCA_TELEGRAM_SCRIPT=scripts/my-telegram.ts',
|
|
61
|
-
'Or set LUCA_TELEGRAM_COMMAND for a custom run command.',
|
|
62
|
-
]
|
|
63
|
-
const helpCommand = `${helpLines.map((line) => `echo "${line.replace(/"/g, '\\"')}"`).join('; ')}; sleep 9999`
|
|
64
|
-
|
|
65
|
-
return {
|
|
66
|
-
command: '/bin/sh',
|
|
67
|
-
args: ['-lc', helpCommand],
|
|
68
|
-
source: 'waiting-for-config',
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return {
|
|
73
|
-
command: 'bun',
|
|
74
|
-
args: ['run', scriptPath],
|
|
75
|
-
source: scriptPath,
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
async function main() {
|
|
80
|
-
const ink = container.feature('ink', { enable: true, patchConsole: true })
|
|
81
|
-
await ink.loadModules()
|
|
82
|
-
|
|
83
|
-
const React = ink.React
|
|
84
|
-
const h = React.createElement
|
|
85
|
-
const { useEffect, useMemo, useRef, useState } = React
|
|
86
|
-
|
|
87
|
-
const { Box, Text } = ink.components
|
|
88
|
-
const { useApp, useInput, useStdout, useStdin } = ink.hooks
|
|
89
|
-
|
|
90
|
-
const animation = resolveAnimation(DEFAULT_ANIMATION)
|
|
91
|
-
const botProcess = createBotCommand()
|
|
92
|
-
|
|
93
|
-
function useAnimationFrame(frames: string[], fps: number): string {
|
|
94
|
-
const [index, setIndex] = useState(0)
|
|
95
|
-
|
|
96
|
-
useEffect(() => {
|
|
97
|
-
const safeFps = Math.max(1, fps)
|
|
98
|
-
const interval = setInterval(() => {
|
|
99
|
-
setIndex((prev: number) => (prev + 1) % frames.length)
|
|
100
|
-
}, Math.floor(1000 / safeFps))
|
|
101
|
-
return () => clearInterval(interval)
|
|
102
|
-
}, [fps, frames.length])
|
|
103
|
-
|
|
104
|
-
return frames[index] || ''
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
function frameLines(frame: string, maxWidth: number): string[] {
|
|
108
|
-
return splitLines(frame).map((line) => (line.length > maxWidth ? line.slice(0, maxWidth - 1) + '.' : line))
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function App() {
|
|
112
|
-
const { stdout } = useStdout()
|
|
113
|
-
const { isRawModeSupported } = useStdin()
|
|
114
|
-
const { exit } = useApp()
|
|
115
|
-
|
|
116
|
-
const [status, setStatus] = useState<ProcessStatus>('idle')
|
|
117
|
-
const [exitCode, setExitCode] = useState<number | null>(null)
|
|
118
|
-
const [startedAt, setStartedAt] = useState<number | null>(null)
|
|
119
|
-
const [outputLines, setOutputLines] = useState<string[]>([])
|
|
120
|
-
|
|
121
|
-
const processRef = useRef<ChildProcessByStdio<null, Readable, Readable> | null>(null)
|
|
122
|
-
const bufferRef = useRef({ stdout: '', stderr: '' })
|
|
123
|
-
|
|
124
|
-
const cols = stdout.columns || 120
|
|
125
|
-
const leftWidth = Math.max(38, Math.floor(cols * 0.42))
|
|
126
|
-
const rightWidth = Math.max(42, cols - leftWidth - 5)
|
|
127
|
-
|
|
128
|
-
const currentFrame = useAnimationFrame(animation.frames, animation.fps)
|
|
129
|
-
|
|
130
|
-
const uptime = useMemo(() => {
|
|
131
|
-
if (!startedAt || status === 'idle') return '00:00'
|
|
132
|
-
const secs = Math.floor((Date.now() - startedAt) / 1000)
|
|
133
|
-
const mm = Math.floor(secs / 60)
|
|
134
|
-
const ss = secs % 60
|
|
135
|
-
return `${String(mm).padStart(2, '0')}:${String(ss).padStart(2, '0')}`
|
|
136
|
-
}, [startedAt, status, outputLines.length])
|
|
137
|
-
|
|
138
|
-
useEffect(() => {
|
|
139
|
-
const run = () => {
|
|
140
|
-
setStatus('running')
|
|
141
|
-
setStartedAt(Date.now())
|
|
142
|
-
|
|
143
|
-
const child = spawn(botProcess.command, botProcess.args, {
|
|
144
|
-
cwd: process.cwd(),
|
|
145
|
-
env: process.env,
|
|
146
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
147
|
-
})
|
|
148
|
-
|
|
149
|
-
processRef.current = child
|
|
150
|
-
|
|
151
|
-
const flushOutput = (kind: 'stdout' | 'stderr', chunk: Buffer) => {
|
|
152
|
-
const key = kind
|
|
153
|
-
const prior = bufferRef.current[key]
|
|
154
|
-
const merged = prior + chunk.toString('utf8')
|
|
155
|
-
const lines = merged.split(/\r?\n/)
|
|
156
|
-
bufferRef.current[key] = lines.pop() || ''
|
|
157
|
-
|
|
158
|
-
if (lines.length) {
|
|
159
|
-
setOutputLines((prev) => {
|
|
160
|
-
const next = [...prev]
|
|
161
|
-
for (const line of lines) {
|
|
162
|
-
if (!line) continue
|
|
163
|
-
next.push(kind === 'stderr' ? `[err] ${line}` : line)
|
|
164
|
-
}
|
|
165
|
-
return next.slice(-MAX_OUTPUT_LINES)
|
|
166
|
-
})
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
child.stdout.on('data', (buf) => flushOutput('stdout', buf))
|
|
171
|
-
child.stderr.on('data', (buf) => flushOutput('stderr', buf))
|
|
172
|
-
|
|
173
|
-
child.on('error', (err) => {
|
|
174
|
-
setStatus('error')
|
|
175
|
-
setOutputLines((prev) => [...prev.slice(-MAX_OUTPUT_LINES + 1), `[launcher-error] ${err.message}`])
|
|
176
|
-
})
|
|
177
|
-
|
|
178
|
-
child.on('close', (code) => {
|
|
179
|
-
const lastOut = bufferRef.current.stdout
|
|
180
|
-
const lastErr = bufferRef.current.stderr
|
|
181
|
-
|
|
182
|
-
setOutputLines((prev) => {
|
|
183
|
-
const next = [...prev]
|
|
184
|
-
if (lastOut) pushChunk(next, lastOut)
|
|
185
|
-
if (lastErr) pushChunk(next, lastErr, 'err')
|
|
186
|
-
next.push(`[system] telegram process exited${typeof code === 'number' ? ` with code ${code}` : ''}`)
|
|
187
|
-
return next.slice(-MAX_OUTPUT_LINES)
|
|
188
|
-
})
|
|
189
|
-
|
|
190
|
-
setExitCode(typeof code === 'number' ? code : null)
|
|
191
|
-
setStatus(code === 0 ? 'exited' : 'error')
|
|
192
|
-
processRef.current = null
|
|
193
|
-
bufferRef.current = { stdout: '', stderr: '' }
|
|
194
|
-
})
|
|
195
|
-
|
|
196
|
-
setOutputLines((prev) => [...prev.slice(-MAX_OUTPUT_LINES + 1), `[system] spawned: ${botProcess.command} ${botProcess.args.join(' ')}`])
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
run()
|
|
200
|
-
|
|
201
|
-
return () => {
|
|
202
|
-
const proc = processRef.current
|
|
203
|
-
if (proc && !proc.killed) {
|
|
204
|
-
try {
|
|
205
|
-
proc.kill('SIGTERM')
|
|
206
|
-
} catch {
|
|
207
|
-
// no-op: process already gone
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
}, [])
|
|
212
|
-
|
|
213
|
-
useInput(
|
|
214
|
-
(input: string, key: any) => {
|
|
215
|
-
if (input === 'q' || (key.ctrl && input === 'c')) {
|
|
216
|
-
const proc = processRef.current
|
|
217
|
-
if (proc && !proc.killed) {
|
|
218
|
-
try {
|
|
219
|
-
proc.kill('SIGTERM')
|
|
220
|
-
} catch {
|
|
221
|
-
// no-op
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
exit()
|
|
225
|
-
}
|
|
226
|
-
},
|
|
227
|
-
{ isActive: !!isRawModeSupported },
|
|
228
|
-
)
|
|
229
|
-
|
|
230
|
-
const statusColor = status === 'running' ? 'green' : status === 'exited' ? 'cyan' : status === 'error' ? 'red' : 'yellow'
|
|
231
|
-
const statusLabel = status === 'running' ? 'LIVE' : status === 'exited' ? `EXIT ${exitCode ?? 0}` : status === 'error' ? `ERR ${exitCode ?? '?'}` : 'BOOT'
|
|
232
|
-
|
|
233
|
-
const visibleOutputLines = outputLines.slice(-Math.max(14, (stdout.rows || 32) - 10))
|
|
234
|
-
const artLines = frameLines(currentFrame, leftWidth - 4)
|
|
235
|
-
|
|
236
|
-
return h(
|
|
237
|
-
Box,
|
|
238
|
-
{ flexDirection: 'column', width: cols, paddingX: 1 },
|
|
239
|
-
h(
|
|
240
|
-
Box,
|
|
241
|
-
{ justifyContent: 'space-between', marginBottom: 1 },
|
|
242
|
-
h(Text, { bold: true, color: '#61dafb' }, 'LUCA TELEGRAM // ART CONSOLE'),
|
|
243
|
-
h(Text, { color: statusColor }, `[${statusLabel}] uptime ${uptime}`),
|
|
244
|
-
),
|
|
245
|
-
h(
|
|
246
|
-
Box,
|
|
247
|
-
{ flexDirection: 'row' },
|
|
248
|
-
h(
|
|
249
|
-
Box,
|
|
250
|
-
{
|
|
251
|
-
width: leftWidth,
|
|
252
|
-
flexDirection: 'column',
|
|
253
|
-
borderStyle: 'round',
|
|
254
|
-
borderColor: '#e879f9',
|
|
255
|
-
paddingX: 1,
|
|
256
|
-
minHeight: Math.max(16, (stdout.rows || 30) - 6),
|
|
257
|
-
},
|
|
258
|
-
h(Text, { color: '#f472b6', bold: true }, `${animation.name} (${animation.id})`),
|
|
259
|
-
h(Text, { dimColor: true }, 'bot avatar loop // modular animation script'),
|
|
260
|
-
h(Text, { dimColor: true }, '-'.repeat(Math.max(10, leftWidth - 4))),
|
|
261
|
-
...artLines.map((line, idx) => h(Text, { key: `frame-${idx}`, color: '#fbcfe8' }, line)),
|
|
262
|
-
),
|
|
263
|
-
h(Box, { width: 1 }, h(Text, { dimColor: true }, '|')),
|
|
264
|
-
h(
|
|
265
|
-
Box,
|
|
266
|
-
{
|
|
267
|
-
width: rightWidth,
|
|
268
|
-
flexDirection: 'column',
|
|
269
|
-
borderStyle: 'round',
|
|
270
|
-
borderColor: '#22d3ee',
|
|
271
|
-
paddingX: 1,
|
|
272
|
-
minHeight: Math.max(16, (stdout.rows || 30) - 6),
|
|
273
|
-
},
|
|
274
|
-
h(Text, { color: '#67e8f9', bold: true }, 'Telegram Bot Stream'),
|
|
275
|
-
h(Text, { dimColor: true, wrap: 'truncate' }, `source: ${botProcess.source}`),
|
|
276
|
-
h(Text, { dimColor: true }, '-'.repeat(Math.max(10, rightWidth - 4))),
|
|
277
|
-
...visibleOutputLines.map((line, idx) =>
|
|
278
|
-
h(
|
|
279
|
-
Text,
|
|
280
|
-
{
|
|
281
|
-
key: `line-${idx}`,
|
|
282
|
-
wrap: 'truncate-middle',
|
|
283
|
-
color: line.startsWith('[err]') || line.startsWith('[launcher-error]') ? '#f87171' : undefined,
|
|
284
|
-
},
|
|
285
|
-
line,
|
|
286
|
-
),
|
|
287
|
-
),
|
|
288
|
-
),
|
|
289
|
-
),
|
|
290
|
-
h(Text, null, ''),
|
|
291
|
-
h(Text, { dimColor: true }, 'q: quit ctrl+c: quit env: LUCA_TELEGRAM_SCRIPT | LUCA_TELEGRAM_COMMAND | LUCA_BOT_ANIMATION'),
|
|
292
|
-
!isRawModeSupported
|
|
293
|
-
? h(Text, { dimColor: true }, 'note: raw stdin unavailable; keyboard shortcuts disabled in this terminal')
|
|
294
|
-
: null,
|
|
295
|
-
)
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
await ink.render(h(App))
|
|
299
|
-
await ink.waitUntilExit()
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
await main()
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import container from '@soederpop/luca/agi'
|
|
2
|
-
|
|
3
|
-
const codex = container.feature('openaiCodex')
|
|
4
|
-
|
|
5
|
-
// Stream deltas as they come in
|
|
6
|
-
codex.on('session:delta', ({ text }: any) => process.stdout.write(text))
|
|
7
|
-
codex.on('session:exec', ({ exec }: any) => console.log(`\n[exec] ${exec.command?.join(' ')}`))
|
|
8
|
-
codex.on('session:patch', ({ patch }: any) => console.log(`\n[patch] ${patch.path}`))
|
|
9
|
-
|
|
10
|
-
async function main() {
|
|
11
|
-
const session = await codex.run('Explain the purpose of this project in a few sentences.', {
|
|
12
|
-
fullAuto: true,
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
console.log('\n---')
|
|
16
|
-
console.log('Status:', session.status)
|
|
17
|
-
console.log('Result:', session.result)
|
|
18
|
-
console.log('Turns:', session.turns)
|
|
19
|
-
console.log('Patches:', session.patches.length)
|
|
20
|
-
console.log('Execs:', session.executions.length)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
main()
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import container from '@soederpop/luca/agi'
|
|
2
|
-
|
|
3
|
-
async function main() {
|
|
4
|
-
const vm = container.feature('vm')
|
|
5
|
-
const skillsFile = container.paths.resolve('experts/luca-core-framework/skills.ts')
|
|
6
|
-
const skills = await container.fs.readFile(skillsFile)
|
|
7
|
-
const transformedSkills = await container.feature('esbuild').transform(skills.toString(), { format: 'cjs' })
|
|
8
|
-
|
|
9
|
-
const mod = { exports: {} as Record<string, any> }
|
|
10
|
-
await vm.run(transformedSkills.code, { container, module: mod, exports: mod.exports })
|
|
11
|
-
|
|
12
|
-
console.log('Loaded skills:', Object.keys(mod.exports))
|
|
13
|
-
console.log(mod.exports)
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
main()
|