@soederpop/luca 0.0.2
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 +71 -0
- package/README.md +78 -0
- package/bun.lock +2928 -0
- package/bunfig.toml +3 -0
- package/commands/audit-docs.ts +740 -0
- package/commands/build-scaffolds.ts +154 -0
- package/commands/generate-api-docs.ts +114 -0
- package/commands/update-introspection.ts +67 -0
- package/docs/CLI.md +335 -0
- package/docs/README.md +88 -0
- package/docs/TABLE-OF-CONTENTS.md +157 -0
- package/docs/apis/clients/elevenlabs.md +84 -0
- package/docs/apis/clients/graph.md +56 -0
- package/docs/apis/clients/openai.md +69 -0
- package/docs/apis/clients/rest.md +41 -0
- package/docs/apis/clients/websocket.md +107 -0
- package/docs/apis/features/agi/assistant.md +471 -0
- package/docs/apis/features/agi/assistants-manager.md +154 -0
- package/docs/apis/features/agi/claude-code.md +602 -0
- package/docs/apis/features/agi/conversation-history.md +352 -0
- package/docs/apis/features/agi/conversation.md +333 -0
- package/docs/apis/features/agi/docs-reader.md +121 -0
- package/docs/apis/features/agi/openai-codex.md +318 -0
- package/docs/apis/features/agi/openapi.md +138 -0
- package/docs/apis/features/agi/semantic-search.md +387 -0
- package/docs/apis/features/agi/skills-library.md +216 -0
- package/docs/apis/features/node/container-link.md +133 -0
- package/docs/apis/features/node/content-db.md +313 -0
- package/docs/apis/features/node/disk-cache.md +379 -0
- package/docs/apis/features/node/dns.md +651 -0
- package/docs/apis/features/node/docker.md +705 -0
- package/docs/apis/features/node/downloader.md +81 -0
- package/docs/apis/features/node/esbuild.md +59 -0
- package/docs/apis/features/node/file-manager.md +182 -0
- package/docs/apis/features/node/fs.md +581 -0
- package/docs/apis/features/node/git.md +330 -0
- package/docs/apis/features/node/google-auth.md +174 -0
- package/docs/apis/features/node/google-calendar.md +187 -0
- package/docs/apis/features/node/google-docs.md +151 -0
- package/docs/apis/features/node/google-drive.md +225 -0
- package/docs/apis/features/node/google-sheets.md +179 -0
- package/docs/apis/features/node/grep.md +290 -0
- package/docs/apis/features/node/helpers.md +135 -0
- package/docs/apis/features/node/ink.md +334 -0
- package/docs/apis/features/node/ipc-socket.md +260 -0
- package/docs/apis/features/node/json-tree.md +86 -0
- package/docs/apis/features/node/launcher-app-command-listener.md +145 -0
- package/docs/apis/features/node/networking.md +281 -0
- package/docs/apis/features/node/nlp.md +133 -0
- package/docs/apis/features/node/opener.md +97 -0
- package/docs/apis/features/node/os.md +118 -0
- package/docs/apis/features/node/package-finder.md +402 -0
- package/docs/apis/features/node/postgres.md +212 -0
- package/docs/apis/features/node/proc.md +430 -0
- package/docs/apis/features/node/process-manager.md +210 -0
- package/docs/apis/features/node/python.md +278 -0
- package/docs/apis/features/node/repl.md +88 -0
- package/docs/apis/features/node/runpod.md +673 -0
- package/docs/apis/features/node/secure-shell.md +169 -0
- package/docs/apis/features/node/semantic-search.md +401 -0
- package/docs/apis/features/node/sqlite.md +211 -0
- package/docs/apis/features/node/telegram.md +254 -0
- package/docs/apis/features/node/tts.md +118 -0
- package/docs/apis/features/node/ui.md +703 -0
- package/docs/apis/features/node/vault.md +64 -0
- package/docs/apis/features/node/vm.md +84 -0
- package/docs/apis/features/node/window-manager.md +337 -0
- package/docs/apis/features/node/yaml-tree.md +85 -0
- package/docs/apis/features/node/yaml.md +176 -0
- package/docs/apis/features/web/asset-loader.md +47 -0
- package/docs/apis/features/web/container-link.md +133 -0
- package/docs/apis/features/web/esbuild.md +59 -0
- package/docs/apis/features/web/helpers.md +135 -0
- package/docs/apis/features/web/network.md +30 -0
- package/docs/apis/features/web/speech.md +55 -0
- package/docs/apis/features/web/vault.md +64 -0
- package/docs/apis/features/web/vm.md +84 -0
- package/docs/apis/features/web/voice.md +67 -0
- package/docs/apis/servers/express.md +127 -0
- package/docs/apis/servers/mcp.md +213 -0
- package/docs/apis/servers/websocket.md +99 -0
- package/docs/documentation-audit.md +134 -0
- package/docs/examples/content-db.md +77 -0
- package/docs/examples/disk-cache.md +83 -0
- package/docs/examples/docker.md +101 -0
- package/docs/examples/downloader.md +70 -0
- package/docs/examples/esbuild.md +80 -0
- package/docs/examples/file-manager.md +82 -0
- package/docs/examples/fs.md +83 -0
- package/docs/examples/git.md +85 -0
- package/docs/examples/google-auth.md +88 -0
- package/docs/examples/google-calendar.md +94 -0
- package/docs/examples/google-docs.md +82 -0
- package/docs/examples/google-drive.md +96 -0
- package/docs/examples/google-sheets.md +95 -0
- package/docs/examples/grep.md +85 -0
- package/docs/examples/ink-blocks.md +75 -0
- package/docs/examples/ink-renderer.md +41 -0
- package/docs/examples/ink.md +103 -0
- package/docs/examples/ipc-socket.md +103 -0
- package/docs/examples/json-tree.md +91 -0
- package/docs/examples/launcher-app-command-listener.md +120 -0
- package/docs/examples/networking.md +58 -0
- package/docs/examples/nlp.md +91 -0
- package/docs/examples/opener.md +78 -0
- package/docs/examples/os.md +72 -0
- package/docs/examples/package-finder.md +89 -0
- package/docs/examples/port-exposer.md +89 -0
- package/docs/examples/postgres.md +91 -0
- package/docs/examples/proc.md +81 -0
- package/docs/examples/process-manager.md +79 -0
- package/docs/examples/python.md +91 -0
- package/docs/examples/repl.md +93 -0
- package/docs/examples/runpod.md +119 -0
- package/docs/examples/secure-shell.md +92 -0
- package/docs/examples/sqlite.md +86 -0
- package/docs/examples/telegram.md +77 -0
- package/docs/examples/tts.md +86 -0
- package/docs/examples/ui.md +80 -0
- package/docs/examples/vault.md +70 -0
- package/docs/examples/vm.md +86 -0
- package/docs/examples/window-manager.md +125 -0
- package/docs/examples/yaml-tree.md +93 -0
- package/docs/examples/yaml.md +104 -0
- package/docs/ideas/class-registration-refactor-possibilities.md +197 -0
- package/docs/ideas/container-use-api.md +9 -0
- package/docs/ideas/easy-auth-for-express-servers-and-luca-serve.md +0 -0
- package/docs/ideas/feature-stacks.md +22 -0
- package/docs/ideas/luca-cli-self-sufficiency-demo.md +23 -0
- package/docs/ideas/mcp-design.md +9 -0
- package/docs/ideas/web-container-debugging-feature.md +13 -0
- package/docs/introspection-audit.md +49 -0
- package/docs/introspection.md +154 -0
- package/docs/mcp/readme.md +162 -0
- package/docs/models.ts +38 -0
- package/docs/philosophy.md +85 -0
- package/docs/principles.md +7 -0
- package/docs/prompts/audit-codebase-for-failures-to-use-the-container.md +34 -0
- package/docs/prompts/mcp-test-easy-command.md +27 -0
- package/docs/reports/assistant-bugs.md +38 -0
- package/docs/reports/attach-pattern-usage.md +18 -0
- package/docs/reports/code-audit-results.md +391 -0
- package/docs/reports/introspection-audit-tasks.md +378 -0
- package/docs/reports/luca-mcp-improvements.md +128 -0
- package/docs/scaffolds/client.md +140 -0
- package/docs/scaffolds/command.md +106 -0
- package/docs/scaffolds/endpoint.md +176 -0
- package/docs/scaffolds/feature.md +148 -0
- package/docs/scaffolds/server.md +187 -0
- package/docs/tasks/web-container-helper-discovery.md +71 -0
- package/docs/todos.md +1 -0
- package/docs/tutorials/01-getting-started.md +106 -0
- package/docs/tutorials/02-container.md +210 -0
- package/docs/tutorials/03-scripts.md +194 -0
- package/docs/tutorials/04-features-overview.md +196 -0
- package/docs/tutorials/05-state-and-events.md +171 -0
- package/docs/tutorials/06-servers.md +157 -0
- package/docs/tutorials/07-endpoints.md +198 -0
- package/docs/tutorials/08-commands.md +171 -0
- package/docs/tutorials/09-clients.md +162 -0
- package/docs/tutorials/10-creating-features.md +198 -0
- package/docs/tutorials/11-contentbase.md +191 -0
- package/docs/tutorials/12-assistants.md +215 -0
- package/docs/tutorials/13-introspection.md +147 -0
- package/docs/tutorials/14-type-system.md +174 -0
- package/docs/tutorials/15-project-patterns.md +222 -0
- package/docs/tutorials/16-google-features.md +534 -0
- package/docs/tutorials/17-tui-blocks.md +530 -0
- package/docs/tutorials/18-semantic-search.md +334 -0
- package/index.ts +1 -0
- package/luca.console.ts +9 -0
- package/main.py +6 -0
- package/package.json +154 -0
- package/pyproject.toml +7 -0
- package/scripts/animations/chrome-glitch.ts +55 -0
- package/scripts/animations/index.ts +16 -0
- package/scripts/animations/neon-pulse.ts +64 -0
- package/scripts/animations/types.ts +6 -0
- package/scripts/build-web.ts +28 -0
- package/scripts/examples/ask-luca-expert.ts +42 -0
- package/scripts/examples/assistant-questions.ts +12 -0
- package/scripts/examples/excalidraw-expert.ts +75 -0
- package/scripts/examples/expert-chat.ts +0 -0
- package/scripts/examples/file-manager.ts +14 -0
- package/scripts/examples/ideas.ts +12 -0
- package/scripts/examples/interactive-chat.ts +20 -0
- package/scripts/examples/openai-tool-calls.ts +113 -0
- package/scripts/examples/opening-a-web-browser.ts +5 -0
- package/scripts/examples/telegram-bot.ts +79 -0
- package/scripts/examples/telegram-ink-ui.ts +302 -0
- package/scripts/examples/using-assistant-with-mcp.ts +560 -0
- package/scripts/examples/using-claude-code.ts +10 -0
- package/scripts/examples/using-contentdb.ts +35 -0
- package/scripts/examples/using-conversations.ts +35 -0
- package/scripts/examples/using-disk-cache.ts +10 -0
- package/scripts/examples/using-docker-shell.ts +75 -0
- package/scripts/examples/using-elevenlabs.ts +25 -0
- package/scripts/examples/using-google-calendar.ts +57 -0
- package/scripts/examples/using-google-docs.ts +74 -0
- package/scripts/examples/using-google-drive.ts +74 -0
- package/scripts/examples/using-google-sheets.ts +89 -0
- package/scripts/examples/using-nlp.ts +55 -0
- package/scripts/examples/using-ollama.ts +10 -0
- package/scripts/examples/using-openai-codex.ts +23 -0
- package/scripts/examples/using-postgres.ts +55 -0
- package/scripts/examples/using-runpod.ts +32 -0
- package/scripts/examples/using-tts.ts +40 -0
- package/scripts/examples/vm-loading-esm-modules.ts +16 -0
- package/scripts/scaffold.ts +391 -0
- package/scripts/scratch.ts +15 -0
- package/scripts/test-command-listener.ts +123 -0
- package/scripts/test-window-manager-lifecycle.ts +86 -0
- package/scripts/test-window-manager.ts +43 -0
- package/scripts/update-introspection-data.ts +58 -0
- package/src/agi/README.md +14 -0
- package/src/agi/container.server.ts +114 -0
- package/src/agi/endpoints/ask.ts +60 -0
- package/src/agi/endpoints/conversations/[id].ts +45 -0
- package/src/agi/endpoints/conversations.ts +31 -0
- package/src/agi/endpoints/experts.ts +37 -0
- package/src/agi/features/assistant.ts +767 -0
- package/src/agi/features/assistants-manager.ts +260 -0
- package/src/agi/features/claude-code.ts +1111 -0
- package/src/agi/features/conversation-history.ts +497 -0
- package/src/agi/features/conversation.ts +799 -0
- package/src/agi/features/openai-codex.ts +631 -0
- package/src/agi/features/openapi.ts +438 -0
- package/src/agi/features/skills-library.ts +425 -0
- package/src/agi/index.ts +6 -0
- package/src/agi/lib/token-counter.ts +122 -0
- package/src/browser.ts +25 -0
- package/src/bus.ts +100 -0
- package/src/cli/cli.ts +70 -0
- package/src/client.ts +461 -0
- package/src/clients/civitai/index.ts +541 -0
- package/src/clients/client-template.ts +41 -0
- package/src/clients/comfyui/index.ts +597 -0
- package/src/clients/elevenlabs/index.ts +291 -0
- package/src/clients/openai/index.ts +451 -0
- package/src/clients/supabase/index.ts +366 -0
- package/src/command.ts +164 -0
- package/src/commands/chat.ts +182 -0
- package/src/commands/console.ts +192 -0
- package/src/commands/describe.ts +433 -0
- package/src/commands/eval.ts +116 -0
- package/src/commands/help.ts +214 -0
- package/src/commands/index.ts +14 -0
- package/src/commands/mcp.ts +64 -0
- package/src/commands/prompt.ts +807 -0
- package/src/commands/run.ts +257 -0
- package/src/commands/sandbox-mcp.ts +439 -0
- package/src/commands/scaffold.ts +79 -0
- package/src/commands/serve.ts +172 -0
- package/src/container.ts +781 -0
- package/src/endpoint.ts +340 -0
- package/src/feature.ts +75 -0
- package/src/hash-object.ts +97 -0
- package/src/helper.ts +543 -0
- package/src/introspection/generated.agi.ts +23388 -0
- package/src/introspection/generated.node.ts +18899 -0
- package/src/introspection/generated.web.ts +2021 -0
- package/src/introspection/index.ts +256 -0
- package/src/introspection/scan.ts +912 -0
- package/src/node/container.ts +354 -0
- package/src/node/feature.ts +13 -0
- package/src/node/features/container-link.ts +558 -0
- package/src/node/features/content-db.ts +475 -0
- package/src/node/features/disk-cache.ts +382 -0
- package/src/node/features/dns.ts +655 -0
- package/src/node/features/docker.ts +912 -0
- package/src/node/features/downloader.ts +92 -0
- package/src/node/features/esbuild.ts +68 -0
- package/src/node/features/file-manager.ts +357 -0
- package/src/node/features/fs.ts +534 -0
- package/src/node/features/git.ts +492 -0
- package/src/node/features/google-auth.ts +502 -0
- package/src/node/features/google-calendar.ts +300 -0
- package/src/node/features/google-docs.ts +404 -0
- package/src/node/features/google-drive.ts +339 -0
- package/src/node/features/google-sheets.ts +279 -0
- package/src/node/features/grep.ts +406 -0
- package/src/node/features/helpers.ts +374 -0
- package/src/node/features/ink.ts +490 -0
- package/src/node/features/ipc-socket.ts +459 -0
- package/src/node/features/json-tree.ts +188 -0
- package/src/node/features/launcher-app-command-listener.ts +388 -0
- package/src/node/features/networking.ts +925 -0
- package/src/node/features/nlp.ts +211 -0
- package/src/node/features/opener.ts +166 -0
- package/src/node/features/os.ts +157 -0
- package/src/node/features/package-finder.ts +539 -0
- package/src/node/features/port-exposer.ts +342 -0
- package/src/node/features/postgres.ts +273 -0
- package/src/node/features/proc.ts +502 -0
- package/src/node/features/process-manager.ts +542 -0
- package/src/node/features/python.ts +444 -0
- package/src/node/features/repl.ts +194 -0
- package/src/node/features/runpod.ts +802 -0
- package/src/node/features/secure-shell.ts +248 -0
- package/src/node/features/semantic-search.ts +924 -0
- package/src/node/features/sqlite.ts +289 -0
- package/src/node/features/telegram.ts +342 -0
- package/src/node/features/tts.ts +184 -0
- package/src/node/features/ui.ts +857 -0
- package/src/node/features/vault.ts +164 -0
- package/src/node/features/vm.ts +312 -0
- package/src/node/features/window-manager.ts +804 -0
- package/src/node/features/yaml-tree.ts +149 -0
- package/src/node/features/yaml.ts +132 -0
- package/src/node.ts +70 -0
- package/src/react/index.ts +175 -0
- package/src/registry.ts +199 -0
- package/src/scaffolds/generated.ts +1613 -0
- package/src/scaffolds/template.ts +37 -0
- package/src/schemas/base.ts +255 -0
- package/src/server.ts +135 -0
- package/src/servers/express.ts +209 -0
- package/src/servers/mcp.ts +805 -0
- package/src/servers/socket.ts +120 -0
- package/src/state.ts +101 -0
- package/src/web/clients/socket.ts +82 -0
- package/src/web/container.ts +74 -0
- package/src/web/extension.ts +30 -0
- package/src/web/feature.ts +12 -0
- package/src/web/features/asset-loader.ts +64 -0
- package/src/web/features/container-link.ts +385 -0
- package/src/web/features/esbuild.ts +79 -0
- package/src/web/features/helpers.ts +267 -0
- package/src/web/features/network.ts +61 -0
- package/src/web/features/speech.ts +87 -0
- package/src/web/features/vault.ts +189 -0
- package/src/web/features/vm.ts +78 -0
- package/src/web/features/voice-recognition.ts +129 -0
- package/src/web/shims/isomorphic-vm.ts +149 -0
- package/test/bus.test.ts +134 -0
- package/test/clients-servers.test.ts +216 -0
- package/test/container-link.test.ts +274 -0
- package/test/features.test.ts +160 -0
- package/test/integration.test.ts +787 -0
- package/test/node-container.test.ts +121 -0
- package/test/rate-limit.test.ts +272 -0
- package/test/semantic-search.test.ts +550 -0
- package/test/state.test.ts +121 -0
- package/test-integration/assistant.test.ts +138 -0
- package/test-integration/assistants-manager.test.ts +123 -0
- package/test-integration/claude-code.test.ts +98 -0
- package/test-integration/conversation-history.test.ts +205 -0
- package/test-integration/conversation.test.ts +137 -0
- package/test-integration/elevenlabs.test.ts +55 -0
- package/test-integration/google-services.test.ts +80 -0
- package/test-integration/helpers.ts +89 -0
- package/test-integration/openai-codex.test.ts +93 -0
- package/test-integration/runpod.test.ts +58 -0
- package/test-integration/server-endpoints.test.ts +97 -0
- package/test-integration/skills-library.test.ts +157 -0
- package/test-integration/telegram.test.ts +46 -0
- package/tsconfig.json +58 -0
- package/uv.lock +8 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import container from '@soederpop/luca/node'
|
|
2
|
+
|
|
3
|
+
async function main() {
|
|
4
|
+
const docker = container.feature('docker', { enable: true, autoRefresh: true })
|
|
5
|
+
|
|
6
|
+
// List running containers so we can pick one
|
|
7
|
+
const containers = await docker.listContainers()
|
|
8
|
+
console.log('Running containers:', containers.map((c) => `${c.name} (${c.image})`).join(', ') || 'none')
|
|
9
|
+
|
|
10
|
+
if (!containers.length) {
|
|
11
|
+
console.log('\nNo running containers. Starting an alpine container for the demo...')
|
|
12
|
+
await docker.runContainer('alpine:latest', {
|
|
13
|
+
name: 'luca-shell-demo',
|
|
14
|
+
detach: true,
|
|
15
|
+
command: ['sleep', 'infinity'],
|
|
16
|
+
})
|
|
17
|
+
console.log('Started luca-shell-demo')
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const target = containers[0]?.name || 'luca-shell-demo'
|
|
21
|
+
|
|
22
|
+
// --- Basic shell (no volumes) ---
|
|
23
|
+
console.log(`\n--- Basic shell against "${target}" ---`)
|
|
24
|
+
const shell = await docker.createShell(target)
|
|
25
|
+
|
|
26
|
+
await shell.run('echo "Hello from inside the container"')
|
|
27
|
+
console.log('stdout:', shell.last!.stdout.trim())
|
|
28
|
+
|
|
29
|
+
await shell.run('uname -a')
|
|
30
|
+
console.log('uname:', shell.last!.stdout.trim())
|
|
31
|
+
|
|
32
|
+
await shell.run('ls /')
|
|
33
|
+
console.log('root listing:', shell.last!.stdout.trim())
|
|
34
|
+
|
|
35
|
+
// --- Shell with volume mounts ---
|
|
36
|
+
// This creates a new helper container from the same image with the mounts applied
|
|
37
|
+
console.log(`\n--- Shell with volume mount ---`)
|
|
38
|
+
const mounted = await docker.createShell(target, {
|
|
39
|
+
volumes: [`${process.cwd()}:/workspace`],
|
|
40
|
+
workdir: '/workspace',
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
console.log('Helper container:', mounted.containerId)
|
|
44
|
+
|
|
45
|
+
await mounted.run('ls -la')
|
|
46
|
+
console.log('workspace files:\n', mounted.last!.stdout)
|
|
47
|
+
|
|
48
|
+
await mounted.run('wc -l package.json')
|
|
49
|
+
console.log('package.json lines:', mounted.last!.stdout.trim())
|
|
50
|
+
|
|
51
|
+
// Write a file from inside the container, visible on the host
|
|
52
|
+
await mounted.run('echo "written by docker shell" > /workspace/.docker-shell-test')
|
|
53
|
+
console.log('Wrote .docker-shell-test (exit code:', mounted.last!.exitCode, ')')
|
|
54
|
+
|
|
55
|
+
// Clean up the helper container
|
|
56
|
+
await mounted.destroy()
|
|
57
|
+
console.log('Helper container destroyed')
|
|
58
|
+
|
|
59
|
+
// --- Using execCommand directly with volumes (one-shot) ---
|
|
60
|
+
console.log(`\n--- One-shot execCommand with volumes ---`)
|
|
61
|
+
const result = await docker.execCommand(target, ['cat', '/data/package.json'], {
|
|
62
|
+
volumes: [`${process.cwd()}/package.json:/data/package.json:ro`],
|
|
63
|
+
})
|
|
64
|
+
console.log('package.json name:', JSON.parse(result.stdout).name)
|
|
65
|
+
|
|
66
|
+
// Clean up demo container if we created it
|
|
67
|
+
if (!containers.length) {
|
|
68
|
+
await docker.removeContainer('luca-shell-demo', { force: true })
|
|
69
|
+
console.log('\nCleaned up luca-shell-demo')
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
console.log('\nDone!')
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
main().catch(console.error)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import container from '@soederpop/luca/node'
|
|
2
|
+
import '../../src/clients/elevenlabs'
|
|
3
|
+
|
|
4
|
+
async function main() {
|
|
5
|
+
const phrase = container.argv.phrase || 'Hello! This is a test of the ElevenLabs text to speech client.'
|
|
6
|
+
const voiceId = container.argv.voice || 'D3LWHMMgiK6AHC5Bl7dE'
|
|
7
|
+
const outputPath = `/tmp/elevenlabs-${Date.now()}.mp3`
|
|
8
|
+
|
|
9
|
+
const el = container.client('elevenlabs')
|
|
10
|
+
await el.connect()
|
|
11
|
+
|
|
12
|
+
console.log('Synthesizing:', phrase)
|
|
13
|
+
const audio = await el.synthesize(phrase, { voiceId })
|
|
14
|
+
console.log(`Audio size: ${(audio.length / 1024).toFixed(1)} KB`)
|
|
15
|
+
|
|
16
|
+
await container.fs.writeFileAsync(outputPath, audio)
|
|
17
|
+
console.log(`Saved to: ${outputPath}`)
|
|
18
|
+
|
|
19
|
+
console.log('Playing...')
|
|
20
|
+
const proc = container.feature('proc')
|
|
21
|
+
await proc.spawnAndCapture('afplay', [outputPath])
|
|
22
|
+
console.log('Done!')
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
main().catch(console.error)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import container from '@soederpop/luca/node'
|
|
2
|
+
|
|
3
|
+
async function main() {
|
|
4
|
+
// GoogleAuth reads GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET from env.
|
|
5
|
+
// On first run it opens your browser for OAuth2 consent.
|
|
6
|
+
// The refresh token is saved in diskCache so subsequent runs skip the browser.
|
|
7
|
+
const auth = container.feature('googleAuth', {
|
|
8
|
+
scopes: ['https://www.googleapis.com/auth/calendar.readonly'],
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
const restored = await auth.tryRestoreTokens()
|
|
12
|
+
|
|
13
|
+
if (restored) {
|
|
14
|
+
console.log(`Restored session for ${auth.state.get('email')}`)
|
|
15
|
+
} else {
|
|
16
|
+
console.log('No cached credentials found — opening browser for authorization...')
|
|
17
|
+
await auth.authorize()
|
|
18
|
+
console.log(`Authorized as ${auth.state.get('email')}`)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const calendar = container.feature('googleCalendar', {
|
|
22
|
+
timeZone: 'America/Chicago',
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
// List accessible calendars
|
|
26
|
+
const calendars = await calendar.listCalendars()
|
|
27
|
+
console.log(`\nYou have access to ${calendars.length} calendars:`)
|
|
28
|
+
for (const cal of calendars) {
|
|
29
|
+
const tag = cal.primary ? ' (primary)' : ''
|
|
30
|
+
console.log(` - ${cal.summary}${tag}`)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Today's events
|
|
34
|
+
const today = await calendar.getToday()
|
|
35
|
+
console.log(`\nToday's events (${today.length}):`)
|
|
36
|
+
for (const event of today) {
|
|
37
|
+
const time = event.start.dateTime
|
|
38
|
+
? new Date(event.start.dateTime).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
|
|
39
|
+
: 'All day'
|
|
40
|
+
console.log(` ${time} ${event.summary}`)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Upcoming 7 days
|
|
44
|
+
const upcoming = await calendar.getUpcoming(7)
|
|
45
|
+
console.log(`\nNext 7 days (${upcoming.length} events):`)
|
|
46
|
+
for (const event of upcoming) {
|
|
47
|
+
const date = event.start.dateTime
|
|
48
|
+
? new Date(event.start.dateTime).toLocaleDateString([], { weekday: 'short', month: 'short', day: 'numeric' })
|
|
49
|
+
: event.start.date || ''
|
|
50
|
+
const time = event.start.dateTime
|
|
51
|
+
? new Date(event.start.dateTime).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
|
|
52
|
+
: 'All day'
|
|
53
|
+
console.log(` ${date} ${time} ${event.summary}`)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
main().catch(console.error)
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import container from '@soederpop/luca/node'
|
|
2
|
+
|
|
3
|
+
// Pass a document ID as the first argument, or omit to list available docs.
|
|
4
|
+
// You can find the ID in a Google Docs URL:
|
|
5
|
+
// https://docs.google.com/document/d/DOCUMENT_ID/edit
|
|
6
|
+
const documentId = process.argv[2]
|
|
7
|
+
|
|
8
|
+
async function main() {
|
|
9
|
+
// GoogleAuth reads GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET from env.
|
|
10
|
+
// On first run it opens your browser for OAuth2 consent.
|
|
11
|
+
// The refresh token is saved in diskCache so subsequent runs skip the browser.
|
|
12
|
+
const auth = container.feature('googleAuth', {
|
|
13
|
+
scopes: [
|
|
14
|
+
'https://www.googleapis.com/auth/documents.readonly',
|
|
15
|
+
'https://www.googleapis.com/auth/drive.readonly',
|
|
16
|
+
],
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
const restored = await auth.tryRestoreTokens()
|
|
20
|
+
|
|
21
|
+
if (restored) {
|
|
22
|
+
console.log(`Restored session for ${auth.state.get('email')}`)
|
|
23
|
+
} else {
|
|
24
|
+
console.log('No cached credentials found — opening browser for authorization...')
|
|
25
|
+
await auth.authorize()
|
|
26
|
+
console.log(`Authorized as ${auth.state.get('email')}`)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const docs = container.feature('googleDocs')
|
|
30
|
+
|
|
31
|
+
// List recent Google Docs
|
|
32
|
+
const allDocs = await docs.listDocs()
|
|
33
|
+
console.log(`\n--- Your Google Docs (${allDocs.length}) ---`)
|
|
34
|
+
for (const doc of allDocs.slice(0, 15)) {
|
|
35
|
+
const modified = doc.modifiedTime
|
|
36
|
+
? new Date(doc.modifiedTime).toLocaleDateString()
|
|
37
|
+
: ''
|
|
38
|
+
console.log(` ${doc.name} ${modified}`)
|
|
39
|
+
console.log(` id: ${doc.id}`)
|
|
40
|
+
}
|
|
41
|
+
if (allDocs.length > 15) {
|
|
42
|
+
console.log(` ... and ${allDocs.length - 15} more`)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// If a document ID was provided, read it
|
|
46
|
+
if (documentId) {
|
|
47
|
+
// Plain text
|
|
48
|
+
const text = await docs.getAsText(documentId)
|
|
49
|
+
const lines = text.split('\n')
|
|
50
|
+
console.log(`\n--- Document as Plain Text (first 20 lines) ---`)
|
|
51
|
+
for (const line of lines.slice(0, 20)) {
|
|
52
|
+
console.log(` ${line}`)
|
|
53
|
+
}
|
|
54
|
+
if (lines.length > 20) {
|
|
55
|
+
console.log(` ... and ${lines.length - 20} more lines`)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Markdown
|
|
59
|
+
const markdown = await docs.getAsMarkdown(documentId)
|
|
60
|
+
const mdLines = markdown.split('\n')
|
|
61
|
+
console.log(`\n--- Document as Markdown (first 30 lines) ---`)
|
|
62
|
+
for (const line of mdLines.slice(0, 30)) {
|
|
63
|
+
console.log(` ${line}`)
|
|
64
|
+
}
|
|
65
|
+
if (mdLines.length > 30) {
|
|
66
|
+
console.log(` ... and ${mdLines.length - 30} more lines`)
|
|
67
|
+
}
|
|
68
|
+
} else {
|
|
69
|
+
console.log('\nTip: pass a document ID to read its contents:')
|
|
70
|
+
console.log(' bun run scripts/examples/using-google-docs.ts <document-id>')
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
main().catch(console.error)
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import container from '@soederpop/luca/node'
|
|
2
|
+
|
|
3
|
+
async function main() {
|
|
4
|
+
// GoogleAuth reads GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET from env.
|
|
5
|
+
// On first run it opens your browser for OAuth2 consent.
|
|
6
|
+
// The refresh token is saved in diskCache so subsequent runs skip the browser.
|
|
7
|
+
const auth = container.feature('googleAuth', {
|
|
8
|
+
scopes: ['https://www.googleapis.com/auth/drive.readonly'],
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
const restored = await auth.tryRestoreTokens()
|
|
12
|
+
|
|
13
|
+
if (restored) {
|
|
14
|
+
console.log(`Restored session for ${auth.state.get('email')}`)
|
|
15
|
+
} else {
|
|
16
|
+
console.log('No cached credentials found — opening browser for authorization...')
|
|
17
|
+
await auth.authorize()
|
|
18
|
+
console.log(`Authorized as ${auth.state.get('email')}`)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const drive = container.feature('googleDrive')
|
|
22
|
+
|
|
23
|
+
// List recent files
|
|
24
|
+
const { files: recent } = await drive.listFiles(undefined, { pageSize: 10 })
|
|
25
|
+
console.log(`\n--- 10 Most Recently Modified Files ---`)
|
|
26
|
+
for (const file of recent) {
|
|
27
|
+
const modified = file.modifiedTime
|
|
28
|
+
? new Date(file.modifiedTime).toLocaleDateString()
|
|
29
|
+
: ''
|
|
30
|
+
const size = file.size ? `${(parseInt(file.size) / 1024).toFixed(1)} KB` : ''
|
|
31
|
+
console.log(` ${file.name} ${modified} ${size}`)
|
|
32
|
+
console.log(` type: ${file.mimeType}`)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Browse root folder
|
|
36
|
+
const root = await drive.browse('root')
|
|
37
|
+
console.log(`\n--- Root Folder ---`)
|
|
38
|
+
console.log(`Folders (${root.folders.length}):`)
|
|
39
|
+
for (const folder of root.folders.slice(0, 10)) {
|
|
40
|
+
console.log(` 📁 ${folder.name}`)
|
|
41
|
+
}
|
|
42
|
+
console.log(`Files (${root.files.length}):`)
|
|
43
|
+
for (const file of root.files.slice(0, 10)) {
|
|
44
|
+
console.log(` 📄 ${file.name} (${file.mimeType})`)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Search for documents
|
|
48
|
+
const { files: docs } = await drive.search('report', {
|
|
49
|
+
mimeType: 'application/vnd.google-apps.document',
|
|
50
|
+
pageSize: 5,
|
|
51
|
+
})
|
|
52
|
+
console.log(`\n--- Search: "report" (Google Docs only) ---`)
|
|
53
|
+
if (docs.length === 0) {
|
|
54
|
+
console.log(' No matching documents found.')
|
|
55
|
+
} else {
|
|
56
|
+
for (const doc of docs) {
|
|
57
|
+
console.log(` ${doc.name}`)
|
|
58
|
+
if (doc.webViewLink) console.log(` ${doc.webViewLink}`)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// List shared drives
|
|
63
|
+
const sharedDrives = await drive.listDrives()
|
|
64
|
+
console.log(`\n--- Shared Drives (${sharedDrives.length}) ---`)
|
|
65
|
+
if (sharedDrives.length === 0) {
|
|
66
|
+
console.log(' No shared drives found.')
|
|
67
|
+
} else {
|
|
68
|
+
for (const sd of sharedDrives) {
|
|
69
|
+
console.log(` ${sd.name} (${sd.id})`)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
main().catch(console.error)
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import container from '@soederpop/luca/node'
|
|
2
|
+
|
|
3
|
+
// Pass a spreadsheet ID as the first argument, or set DEFAULT_SPREADSHEET_ID env var.
|
|
4
|
+
// You can find the ID in a Google Sheets URL:
|
|
5
|
+
// https://docs.google.com/spreadsheets/d/SPREADSHEET_ID/edit
|
|
6
|
+
const spreadsheetId = process.argv[2] || process.env.DEFAULT_SPREADSHEET_ID
|
|
7
|
+
|
|
8
|
+
async function main() {
|
|
9
|
+
if (!spreadsheetId) {
|
|
10
|
+
console.error('Usage: bun run scripts/examples/using-google-sheets.ts <spreadsheet-id>')
|
|
11
|
+
console.error(' or set DEFAULT_SPREADSHEET_ID env var')
|
|
12
|
+
process.exit(1)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// GoogleAuth reads GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET from env.
|
|
16
|
+
// On first run it opens your browser for OAuth2 consent.
|
|
17
|
+
// The refresh token is saved in diskCache so subsequent runs skip the browser.
|
|
18
|
+
const auth = container.feature('googleAuth', {
|
|
19
|
+
scopes: ['https://www.googleapis.com/auth/spreadsheets.readonly'],
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
const restored = await auth.tryRestoreTokens()
|
|
23
|
+
|
|
24
|
+
if (restored) {
|
|
25
|
+
console.log(`Restored session for ${auth.state.get('email')}`)
|
|
26
|
+
} else {
|
|
27
|
+
console.log('No cached credentials found — opening browser for authorization...')
|
|
28
|
+
await auth.authorize()
|
|
29
|
+
console.log(`Authorized as ${auth.state.get('email')}`)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const sheets = container.feature('googleSheets', {
|
|
33
|
+
defaultSpreadsheetId: spreadsheetId,
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
// Get spreadsheet metadata
|
|
37
|
+
const meta = await sheets.getSpreadsheet()
|
|
38
|
+
console.log(`\n--- Spreadsheet: "${meta.title}" ---`)
|
|
39
|
+
console.log(`Locale: ${meta.locale}`)
|
|
40
|
+
console.log(`Sheets (${meta.sheets.length}):`)
|
|
41
|
+
for (const sheet of meta.sheets) {
|
|
42
|
+
console.log(` ${sheet.title} (${sheet.rowCount} rows × ${sheet.columnCount} cols)`)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Read first sheet as JSON (first row = headers)
|
|
46
|
+
const firstSheet = meta.sheets[0]
|
|
47
|
+
if (!firstSheet) {
|
|
48
|
+
console.log('\nNo sheets found in this spreadsheet.')
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const data = await sheets.getAsJson(firstSheet.title)
|
|
53
|
+
console.log(`\n--- "${firstSheet.title}" as JSON (first 5 rows) ---`)
|
|
54
|
+
if (data.length === 0) {
|
|
55
|
+
console.log(' (empty or header-only sheet)')
|
|
56
|
+
} else {
|
|
57
|
+
const headers = Object.keys(data[0]!)
|
|
58
|
+
console.log(` Columns: ${headers.join(', ')}`)
|
|
59
|
+
for (const row of data.slice(0, 5)) {
|
|
60
|
+
console.log(` ${JSON.stringify(row)}`)
|
|
61
|
+
}
|
|
62
|
+
if (data.length > 5) {
|
|
63
|
+
console.log(` ... and ${data.length - 5} more rows`)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Read as CSV
|
|
68
|
+
const csv = await sheets.getAsCsv(firstSheet.title)
|
|
69
|
+
const csvLines = csv.split('\n')
|
|
70
|
+
console.log(`\n--- "${firstSheet.title}" as CSV (first 5 lines) ---`)
|
|
71
|
+
for (const line of csvLines.slice(0, 5)) {
|
|
72
|
+
console.log(` ${line}`)
|
|
73
|
+
}
|
|
74
|
+
if (csvLines.length > 5) {
|
|
75
|
+
console.log(` ... and ${csvLines.length - 5} more lines`)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Read a specific range if there are enough rows
|
|
79
|
+
if (firstSheet.rowCount >= 2 && firstSheet.columnCount >= 2) {
|
|
80
|
+
const range = `${firstSheet.title}!A1:B5`
|
|
81
|
+
const values = await sheets.getRange(range)
|
|
82
|
+
console.log(`\n--- Range: ${range} ---`)
|
|
83
|
+
for (const row of values) {
|
|
84
|
+
console.log(` ${row.join('\t')}`)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
main().catch(console.error)
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import container from '@soederpop/luca/node'
|
|
2
|
+
|
|
3
|
+
const nlp = container.feature('nlp', { enable: true })
|
|
4
|
+
|
|
5
|
+
// --- parse(): compromise-powered verb normalization + structure extraction ---
|
|
6
|
+
console.log('=== parse() ===\n')
|
|
7
|
+
|
|
8
|
+
const commands = [
|
|
9
|
+
'open the terminal',
|
|
10
|
+
'draw a diagram of the auth flow',
|
|
11
|
+
'write something about baseball',
|
|
12
|
+
'quickly search for recent logs',
|
|
13
|
+
'deploy the new build to staging',
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
for (const cmd of commands) {
|
|
17
|
+
const result = nlp.parse(cmd)
|
|
18
|
+
console.log(`"${cmd}"`)
|
|
19
|
+
console.log(` intent: ${result.intent}, target: ${result.target}, subject: ${result.subject}`)
|
|
20
|
+
if (result.modifiers.length) console.log(` modifiers: ${result.modifiers.join(', ')}`)
|
|
21
|
+
console.log()
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// --- analyze(): wink-nlp POS tagging + named entity recognition ---
|
|
25
|
+
console.log('=== analyze() ===\n')
|
|
26
|
+
|
|
27
|
+
const sentences = [
|
|
28
|
+
'meet john at 3pm about the deployment',
|
|
29
|
+
'send the report to sarah by friday',
|
|
30
|
+
'there are 42 open issues in the repo',
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
for (const sentence of sentences) {
|
|
34
|
+
const result = nlp.analyze(sentence)
|
|
35
|
+
console.log(`"${sentence}"`)
|
|
36
|
+
console.log(` tokens: ${result.tokens.map(t => `${t.value}/${t.pos}`).join(' ')}`)
|
|
37
|
+
if (result.entities.length) {
|
|
38
|
+
console.log(` entities: ${result.entities.map(e => `${e.value} (${e.type})`).join(', ')}`)
|
|
39
|
+
}
|
|
40
|
+
console.log()
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// --- understand(): combined parse + analyze ---
|
|
44
|
+
console.log('=== understand() ===\n')
|
|
45
|
+
|
|
46
|
+
const utterance = 'create a new project for the dashboard'
|
|
47
|
+
const full = nlp.understand(utterance)
|
|
48
|
+
console.log(`"${utterance}"`)
|
|
49
|
+
console.log(` intent: ${full.intent}`)
|
|
50
|
+
console.log(` target: ${full.target}`)
|
|
51
|
+
console.log(` subject: ${full.subject}`)
|
|
52
|
+
console.log(` tokens: ${full.tokens.map(t => `${t.value}/${t.pos}`).join(' ')}`)
|
|
53
|
+
if (full.entities.length) {
|
|
54
|
+
console.log(` entities: ${full.entities.map(e => `${e.value} (${e.type})`).join(', ')}`)
|
|
55
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
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()
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import container from '@soederpop/luca/node'
|
|
2
|
+
|
|
3
|
+
const DEFAULT_DATABASE_URL = 'postgresql://postgres:postgres@127.0.0.1:54322/postgres'
|
|
4
|
+
|
|
5
|
+
type TableRow = {
|
|
6
|
+
table_schema: string
|
|
7
|
+
table_name: string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async function main() {
|
|
11
|
+
const url = process.env.DATABASE_URL || DEFAULT_DATABASE_URL
|
|
12
|
+
const postgres = container.feature('postgres', { url })
|
|
13
|
+
|
|
14
|
+
try {
|
|
15
|
+
const tables = await withTimeout(
|
|
16
|
+
postgres.query<TableRow>(
|
|
17
|
+
`
|
|
18
|
+
select table_schema, table_name
|
|
19
|
+
from information_schema.tables
|
|
20
|
+
where table_type = 'BASE TABLE'
|
|
21
|
+
and table_schema not in ('pg_catalog', 'information_schema')
|
|
22
|
+
order by table_schema, table_name
|
|
23
|
+
`
|
|
24
|
+
),
|
|
25
|
+
8000,
|
|
26
|
+
`Timed out connecting/querying ${url}`
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
if (tables.length === 0) {
|
|
30
|
+
console.log('No user tables found.')
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
console.log(`Found ${tables.length} table(s):`)
|
|
35
|
+
for (const table of tables) {
|
|
36
|
+
console.log(`- ${table.table_schema}.${table.table_name}`)
|
|
37
|
+
}
|
|
38
|
+
} finally {
|
|
39
|
+
await withTimeout(postgres.close(), 1000, 'Timed out while closing Postgres connection').catch(() => {})
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
main().catch((error) => {
|
|
44
|
+
console.error('Failed to list Postgres tables:', error)
|
|
45
|
+
process.exit(1)
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
function withTimeout<T>(promise: Promise<T>, timeoutMs: number, message: string): Promise<T> {
|
|
49
|
+
return Promise.race([
|
|
50
|
+
promise,
|
|
51
|
+
new Promise<T>((_, reject) => {
|
|
52
|
+
setTimeout(() => reject(new Error(message)), timeoutMs)
|
|
53
|
+
}),
|
|
54
|
+
])
|
|
55
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import container from '@soederpop/luca/node'
|
|
2
|
+
|
|
3
|
+
async function main() {
|
|
4
|
+
const runpod = container.feature('runpod')
|
|
5
|
+
|
|
6
|
+
// List available GPUs with pricing
|
|
7
|
+
const gpus = await runpod.listSecureGPUs()
|
|
8
|
+
console.log('Available GPUs:')
|
|
9
|
+
console.table(gpus)
|
|
10
|
+
|
|
11
|
+
// List RunPod's official templates
|
|
12
|
+
const templates = await runpod.listTemplates({ includeRunpod: true })
|
|
13
|
+
console.log('\nAvailable Templates:')
|
|
14
|
+
for (const t of templates) {
|
|
15
|
+
console.log(` ${t.id} - ${t.name} (${t.imageName})`)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Launch a pod from a template on an RTX 4090
|
|
19
|
+
// const pod = await runpod.createPod({
|
|
20
|
+
// name: 'my-workspace',
|
|
21
|
+
// templateId: templates[0].id,
|
|
22
|
+
// gpuTypeId: 'NVIDIA GeForce RTX 4090',
|
|
23
|
+
// })
|
|
24
|
+
// console.log('Created pod:', pod.id)
|
|
25
|
+
|
|
26
|
+
// List running pods
|
|
27
|
+
const pods = await runpod.listPods()
|
|
28
|
+
console.log('\nRunning Pods:')
|
|
29
|
+
console.table(pods.map(p => ({ id: p.id, name: p.name, gpu: p.gpu, status: p.status })))
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
main()
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import container from '@soederpop/luca/node'
|
|
2
|
+
|
|
3
|
+
async function main() {
|
|
4
|
+
const tts = container.feature('tts', { enable: true })
|
|
5
|
+
|
|
6
|
+
console.log('Available voices:', tts.voices.join(', '))
|
|
7
|
+
console.log('Output directory:', tts.outputDir)
|
|
8
|
+
console.log()
|
|
9
|
+
|
|
10
|
+
// Synthesize a simple phrase
|
|
11
|
+
console.log('Synthesizing with default voice (lucy)...')
|
|
12
|
+
const path1 = await tts.synthesize('Hello! This is a test of the Chatterbox text to speech system.')
|
|
13
|
+
console.log(` Saved to: ${path1}`)
|
|
14
|
+
|
|
15
|
+
// Try a different voice
|
|
16
|
+
console.log('\nSynthesizing with voice "ethan"...')
|
|
17
|
+
const path2 = await tts.synthesize('Good morning. How can I help you today?', { voice: 'ethan' })
|
|
18
|
+
console.log(` Saved to: ${path2}`)
|
|
19
|
+
|
|
20
|
+
// Listen for events
|
|
21
|
+
tts.on('synthesized', (text, path, voice, durationMs) => {
|
|
22
|
+
console.log(`\n[event] synthesized "${text.slice(0, 40)}..." voice=${voice} took=${durationMs}ms`)
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
// Synthesize a longer passage
|
|
26
|
+
console.log('\nSynthesizing a longer passage with voice "evelyn"...')
|
|
27
|
+
const path3 = await tts.synthesize(
|
|
28
|
+
'The quick brown fox jumps over the lazy dog. This sentence contains every letter of the English alphabet, making it a perfect pangram for testing.',
|
|
29
|
+
{ voice: 'evelyn' }
|
|
30
|
+
)
|
|
31
|
+
console.log(` Saved to: ${path3}`)
|
|
32
|
+
|
|
33
|
+
// Play the last file with the system player (macOS)
|
|
34
|
+
console.log('\nPlaying last generated audio...')
|
|
35
|
+
const proc = container.feature('proc')
|
|
36
|
+
await proc.spawnAndCapture('afplay', [path3])
|
|
37
|
+
console.log('Done!')
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
main().catch(console.error)
|
|
@@ -0,0 +1,16 @@
|
|
|
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()
|