luca 3.0.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/release.yaml +1 -0
- package/CLAUDE.md +10 -2
- package/README.md +130 -112
- package/assistants/codingAssistant/CORE.md +6 -1
- package/assistants/codingAssistant/hooks.ts +1 -1
- package/assistants/inkbot/hooks.ts +1 -1
- package/assistants/inkbot/tools.ts +1 -1
- package/bun.lock +264 -321
- package/commands/audit-docs.ts +2 -2
- package/commands/build-bootstrap.ts +2 -3
- package/commands/build-python-bridge.ts +2 -3
- package/commands/build-scaffolds.ts +2 -3
- package/commands/bundle-consumer-project.ts +521 -0
- package/commands/generate-api-docs.ts +2 -2
- package/commands/inkbot.ts +2 -2
- package/commands/release.ts +2 -2
- package/commands/social.ts +137 -0
- package/commands/try-all-challenges.ts +3 -3
- package/commands/try-challenge.ts +3 -3
- package/datasets/lora/agentic-loop-session-candidates.jsonl +91 -0
- package/datasets/lora/agentic-loop-session-curation-summary.json +123 -0
- package/datasets/lora/luca-session-candidates.jsonl +29 -0
- package/datasets/lora/luca-session-curation-summary.json +121 -0
- package/datasets/lora/review-batch-1.jsonl +30 -0
- package/datasets/lora/review-manifest.json +41 -0
- package/datasets/lora/review-queue.jsonl +120 -0
- package/datasets/lora/review-schema.json +134 -0
- package/datasets/lora/review-template.jsonl +2 -0
- package/datasets/lora/review-ui.html +725 -0
- package/dist/agi/container.server.d.ts +2 -2
- package/dist/agi/features/assistant.d.ts +2 -2
- package/dist/agi/features/assistants-manager.d.ts +1 -1
- package/dist/agi/features/autonomous-assistant.d.ts +1 -1
- package/dist/agi/features/browser-use.d.ts +1 -1
- package/dist/agi/features/claude-code.d.ts +1 -1
- package/dist/agi/features/conversation-history.d.ts +2 -2
- package/dist/agi/features/conversation.d.ts +1 -1
- package/dist/agi/features/docs-reader.d.ts +1 -1
- package/dist/agi/features/file-tools.d.ts +1 -1
- package/dist/agi/features/luca-coder.d.ts +1 -1
- package/dist/agi/features/openai-codex.d.ts +1 -1
- package/dist/agi/features/skills-library.d.ts +1 -1
- package/dist/clients/civitai/index.d.ts +4 -4
- package/dist/clients/client-template.d.ts +4 -4
- package/dist/clients/comfyui/index.d.ts +2 -2
- package/dist/clients/elevenlabs/index.d.ts +2 -2
- package/dist/clients/openai/index.d.ts +2 -2
- package/dist/clients/supabase/index.d.ts +3 -3
- package/dist/command.d.ts +1 -1
- package/dist/node/container.d.ts +1 -1
- package/dist/node/features/helpers.d.ts +3 -3
- package/dist/node/features/semantic-search.d.ts +1 -1
- package/dist/node/features/vm.d.ts +3 -3
- package/dist/node.d.ts +1 -1
- package/dist/scaffolds/generated.d.ts +1 -1
- package/dist/selector.d.ts +1 -1
- package/features/cipher-social.ts +493 -0
- package/index.html +217 -190
- package/luca.console.ts +1 -1
- package/package.json +7 -2
- package/public/index.html +217 -190
- package/public/slides-ai-native.html +1 -1
- package/public/slides-intro.html +2 -2
- package/scripts/curate-claude-sessions.ts +561 -0
- package/scripts/examples/ask-luca-expert.ts +1 -1
- package/scripts/examples/assistant-questions.ts +1 -1
- package/scripts/examples/excalidraw-expert.ts +1 -1
- package/scripts/examples/file-manager.ts +1 -1
- package/scripts/examples/ideas.ts +1 -1
- package/scripts/examples/interactive-chat.ts +1 -1
- package/scripts/examples/opening-a-web-browser.ts +1 -1
- package/scripts/examples/telegram-bot.ts +1 -1
- package/scripts/examples/using-assistant-with-mcp.ts +1 -1
- package/scripts/examples/using-claude-code.ts +1 -1
- package/scripts/examples/using-contentdb.ts +2 -2
- package/scripts/examples/using-conversations.ts +1 -1
- package/scripts/examples/using-disk-cache.ts +1 -1
- package/scripts/examples/using-docker-shell.ts +1 -1
- package/scripts/examples/using-elevenlabs.ts +1 -1
- package/scripts/examples/using-google-calendar.ts +1 -1
- package/scripts/examples/using-google-docs.ts +1 -1
- package/scripts/examples/using-google-drive.ts +1 -1
- package/scripts/examples/using-google-sheets.ts +1 -1
- package/scripts/examples/using-nlp.ts +1 -1
- package/scripts/examples/using-ollama.ts +1 -1
- package/scripts/examples/using-postgres.ts +1 -1
- package/scripts/examples/using-runpod.ts +1 -1
- package/scripts/examples/using-tts.ts +1 -1
- package/scripts/scaffold.ts +5 -5
- package/scripts/scratch.ts +1 -1
- package/scripts/test-assistant-hooks.ts +1 -1
- package/scripts/test-docs-reader.ts +1 -1
- package/src/agi/container.server.ts +6 -2
- package/src/agi/features/agent-memory.ts +25 -25
- package/src/agi/features/assistant.ts +34 -5
- package/src/agi/features/assistants-manager.ts +122 -6
- package/src/agi/features/autonomous-assistant.ts +1 -1
- package/src/agi/features/browser-use.ts +20 -1
- package/src/agi/features/claude-code.ts +51 -5
- package/src/agi/features/coding-tools.ts +1 -1
- package/src/agi/features/conversation-history.ts +181 -4
- package/src/agi/features/conversation.ts +186 -15
- package/src/agi/features/docs-reader.ts +2 -2
- package/src/agi/features/file-tools.ts +49 -2
- package/src/agi/features/luca-coder.ts +7 -5
- package/src/agi/features/mcp-bridge.ts +532 -0
- package/src/agi/features/openai-codex.ts +2 -2
- package/src/agi/features/skills-library.ts +131 -52
- package/src/agi/lib/token-counter.ts +80 -0
- package/src/bootstrap/generated.ts +56 -57
- package/src/browser.ts +1 -1
- package/src/cli/build-info.ts +2 -2
- package/src/cli/cli.ts +2 -2
- package/src/clients/civitai/index.ts +5 -5
- package/src/clients/client-template.ts +4 -4
- package/src/clients/comfyui/index.ts +4 -4
- package/src/clients/elevenlabs/index.ts +4 -4
- package/src/clients/openai/index.ts +7 -7
- package/src/clients/supabase/index.ts +4 -4
- package/src/clients/voicebox/index.ts +4 -4
- package/src/command.ts +2 -1
- package/src/commands/chat.ts +1 -0
- package/src/commands/eval.ts +2 -56
- package/src/commands/introspect.ts +1 -1
- package/src/commands/prompt.ts +41 -9
- package/src/container-describer.ts +8 -1
- package/src/container.ts +13 -0
- package/src/entity.ts +2 -2
- package/src/helper.ts +1 -1
- package/src/introspection/generated.agi.ts +29596 -27654
- package/src/introspection/generated.node.ts +20284 -19247
- package/src/introspection/generated.web.ts +605 -584
- package/src/introspection/scan.ts +11 -6
- package/src/node/container.ts +9 -1
- package/src/node/features/content-db.ts +39 -2
- package/src/node/features/display-result.ts +57 -0
- package/src/node/features/helpers.ts +46 -7
- package/src/node/features/python.ts +25 -19
- package/src/node/features/repl.ts +1 -1
- package/src/node/features/secure-shell.ts +11 -17
- package/src/node/features/semantic-search.ts +2 -2
- package/src/node/features/socket-repl.ts +336 -0
- package/src/node/features/telnyx-assistant-connector.ts +1206 -0
- package/src/node/features/transpiler.ts +2 -3
- package/src/node/features/ui.ts +5 -0
- package/src/node/features/vm.ts +20 -3
- package/src/node.ts +3 -3
- package/src/python/generated.ts +0 -1
- package/src/scaffolds/generated.ts +82 -83
- package/src/selector.ts +1 -1
- package/src/servers/express.ts +1 -1
- package/src/web/features/helpers.ts +22 -0
- package/tsconfig.json +12 -12
- package/docs/CLI.md +0 -335
- package/docs/CNAME +0 -1
- package/docs/README.md +0 -60
- package/docs/TABLE-OF-CONTENTS.md +0 -183
- package/docs/apis/clients/elevenlabs.md +0 -308
- package/docs/apis/clients/graph.md +0 -107
- package/docs/apis/clients/openai.md +0 -429
- package/docs/apis/clients/rest.md +0 -161
- package/docs/apis/clients/websocket.md +0 -174
- package/docs/apis/features/agi/assistant.md +0 -625
- package/docs/apis/features/agi/assistants-manager.md +0 -282
- package/docs/apis/features/agi/auto-assistant.md +0 -279
- package/docs/apis/features/agi/browser-use.md +0 -802
- package/docs/apis/features/agi/claude-code.md +0 -884
- package/docs/apis/features/agi/conversation-history.md +0 -364
- package/docs/apis/features/agi/conversation.md +0 -548
- package/docs/apis/features/agi/docs-reader.md +0 -99
- package/docs/apis/features/agi/file-tools.md +0 -163
- package/docs/apis/features/agi/luca-coder.md +0 -407
- package/docs/apis/features/agi/openai-codex.md +0 -396
- package/docs/apis/features/agi/openapi.md +0 -138
- package/docs/apis/features/agi/semantic-search.md +0 -387
- package/docs/apis/features/agi/skills-library.md +0 -239
- package/docs/apis/features/node/container-link.md +0 -192
- package/docs/apis/features/node/content-db.md +0 -450
- package/docs/apis/features/node/disk-cache.md +0 -379
- package/docs/apis/features/node/dns.md +0 -652
- package/docs/apis/features/node/docker.md +0 -706
- package/docs/apis/features/node/downloader.md +0 -81
- package/docs/apis/features/node/esbuild.md +0 -60
- package/docs/apis/features/node/file-manager.md +0 -191
- package/docs/apis/features/node/fs.md +0 -1217
- package/docs/apis/features/node/git.md +0 -371
- package/docs/apis/features/node/google-auth.md +0 -193
- package/docs/apis/features/node/google-calendar.md +0 -202
- package/docs/apis/features/node/google-docs.md +0 -173
- package/docs/apis/features/node/google-drive.md +0 -246
- package/docs/apis/features/node/google-mail.md +0 -214
- package/docs/apis/features/node/google-sheets.md +0 -194
- package/docs/apis/features/node/grep.md +0 -292
- package/docs/apis/features/node/helpers.md +0 -164
- package/docs/apis/features/node/ink.md +0 -334
- package/docs/apis/features/node/ipc-socket.md +0 -249
- package/docs/apis/features/node/json-tree.md +0 -86
- package/docs/apis/features/node/networking.md +0 -316
- package/docs/apis/features/node/nlp.md +0 -133
- package/docs/apis/features/node/opener.md +0 -97
- package/docs/apis/features/node/os.md +0 -146
- package/docs/apis/features/node/package-finder.md +0 -392
- package/docs/apis/features/node/postgres.md +0 -234
- package/docs/apis/features/node/proc.md +0 -399
- package/docs/apis/features/node/process-manager.md +0 -305
- package/docs/apis/features/node/python.md +0 -604
- package/docs/apis/features/node/redis.md +0 -380
- package/docs/apis/features/node/repl.md +0 -88
- package/docs/apis/features/node/runpod.md +0 -674
- package/docs/apis/features/node/secure-shell.md +0 -176
- package/docs/apis/features/node/semantic-search.md +0 -408
- package/docs/apis/features/node/sqlite.md +0 -233
- package/docs/apis/features/node/telegram.md +0 -279
- package/docs/apis/features/node/transpiler.md +0 -74
- package/docs/apis/features/node/tts.md +0 -133
- package/docs/apis/features/node/ui.md +0 -701
- package/docs/apis/features/node/vault.md +0 -59
- package/docs/apis/features/node/vm.md +0 -75
- package/docs/apis/features/node/yaml-tree.md +0 -85
- package/docs/apis/features/node/yaml.md +0 -176
- package/docs/apis/features/web/asset-loader.md +0 -59
- package/docs/apis/features/web/container-link.md +0 -192
- package/docs/apis/features/web/esbuild.md +0 -54
- package/docs/apis/features/web/helpers.md +0 -164
- package/docs/apis/features/web/network.md +0 -44
- package/docs/apis/features/web/speech.md +0 -69
- package/docs/apis/features/web/vault.md +0 -59
- package/docs/apis/features/web/vm.md +0 -75
- package/docs/apis/features/web/voice.md +0 -84
- package/docs/apis/servers/express.md +0 -171
- package/docs/apis/servers/mcp.md +0 -238
- package/docs/apis/servers/websocket.md +0 -170
- package/docs/bootstrap/CLAUDE.md +0 -101
- package/docs/bootstrap/SKILL.md +0 -341
- package/docs/bootstrap/templates/about-command.ts +0 -41
- package/docs/bootstrap/templates/docs-models.ts +0 -22
- package/docs/bootstrap/templates/docs-readme.md +0 -43
- package/docs/bootstrap/templates/example-feature.ts +0 -53
- package/docs/bootstrap/templates/health-endpoint.ts +0 -15
- package/docs/bootstrap/templates/luca-cli.ts +0 -30
- package/docs/bootstrap/templates/runme.md +0 -54
- package/docs/challenges/caching-proxy.md +0 -16
- package/docs/challenges/content-db-round-trip.md +0 -14
- package/docs/challenges/custom-command.md +0 -9
- package/docs/challenges/file-watcher-pipeline.md +0 -11
- package/docs/challenges/grep-audit-report.md +0 -15
- package/docs/challenges/multi-feature-dashboard.md +0 -14
- package/docs/challenges/process-orchestrator.md +0 -17
- package/docs/challenges/rest-api-server-with-client.md +0 -12
- package/docs/challenges/script-runner-with-vm.md +0 -11
- package/docs/challenges/simple-rest-api.md +0 -15
- package/docs/challenges/websocket-serve-and-client.md +0 -11
- package/docs/challenges/yaml-config-system.md +0 -14
- package/docs/command-system-overhaul.md +0 -94
- package/docs/documentation-audit.md +0 -134
- package/docs/examples/assistant/CORE.md +0 -18
- package/docs/examples/assistant/hooks.ts +0 -3
- package/docs/examples/assistant/tools.ts +0 -10
- package/docs/examples/assistant-hooks-reference.ts +0 -171
- package/docs/examples/assistant-with-process-manager.md +0 -84
- package/docs/examples/content-db.md +0 -77
- package/docs/examples/disk-cache.md +0 -83
- package/docs/examples/docker.md +0 -101
- package/docs/examples/downloader.md +0 -70
- package/docs/examples/entity.md +0 -124
- package/docs/examples/esbuild.md +0 -80
- package/docs/examples/feature-as-tool-provider.md +0 -143
- package/docs/examples/file-manager.md +0 -82
- package/docs/examples/fs.md +0 -83
- package/docs/examples/git.md +0 -85
- package/docs/examples/google-auth.md +0 -88
- package/docs/examples/google-calendar.md +0 -94
- package/docs/examples/google-docs.md +0 -82
- package/docs/examples/google-drive.md +0 -96
- package/docs/examples/google-sheets.md +0 -95
- package/docs/examples/grep.md +0 -85
- package/docs/examples/ink-blocks.md +0 -75
- package/docs/examples/ink-renderer.md +0 -41
- package/docs/examples/ink.md +0 -103
- package/docs/examples/ipc-socket.md +0 -103
- package/docs/examples/json-tree.md +0 -91
- package/docs/examples/networking.md +0 -58
- package/docs/examples/nlp.md +0 -91
- package/docs/examples/opener.md +0 -78
- package/docs/examples/os.md +0 -72
- package/docs/examples/package-finder.md +0 -89
- package/docs/examples/postgres.md +0 -91
- package/docs/examples/proc.md +0 -81
- package/docs/examples/process-manager.md +0 -79
- package/docs/examples/python.md +0 -132
- package/docs/examples/repl.md +0 -93
- package/docs/examples/runpod.md +0 -119
- package/docs/examples/secure-shell.md +0 -92
- package/docs/examples/sqlite.md +0 -86
- package/docs/examples/structured-output-with-assistants.md +0 -144
- package/docs/examples/telegram.md +0 -77
- package/docs/examples/tts.md +0 -86
- package/docs/examples/ui.md +0 -80
- package/docs/examples/vault.md +0 -70
- package/docs/examples/vm.md +0 -86
- package/docs/examples/websocket-ask-and-reply-example.md +0 -128
- package/docs/examples/yaml-tree.md +0 -93
- package/docs/examples/yaml.md +0 -104
- package/docs/ideas/assistant-factory-pattern.md +0 -142
- package/docs/in-memory-fs.md +0 -4
- package/docs/introspection-audit.md +0 -49
- package/docs/introspection.md +0 -164
- package/docs/mcp/readme.md +0 -162
- package/docs/models.ts +0 -41
- package/docs/philosophy.md +0 -86
- package/docs/principles.md +0 -7
- package/docs/prompts/audit-codebase-for-failures-to-use-the-container.md +0 -34
- package/docs/prompts/check-for-undocumented-features.md +0 -27
- package/docs/prompts/mcp-test-easy-command.md +0 -27
- package/docs/scaffolds/client.md +0 -149
- package/docs/scaffolds/command.md +0 -120
- package/docs/scaffolds/endpoint.md +0 -171
- package/docs/scaffolds/feature.md +0 -158
- package/docs/scaffolds/selector.md +0 -91
- package/docs/scaffolds/server.md +0 -196
- package/docs/selectors.md +0 -115
- package/docs/sessions/custom-command/attempt-log-2.md +0 -195
- package/docs/sessions/file-watcher-pipeline/attempt-log-1.md +0 -728
- package/docs/sessions/file-watcher-pipeline/attempt-log-2.md +0 -555
- package/docs/sessions/grep-audit-report/attempt-log-1.md +0 -289
- package/docs/sessions/multi-feature-dashboard/attempt-log-2.md +0 -679
- package/docs/sessions/rest-api-server-with-client/attempt-log-1.md +0 -1
- package/docs/sessions/rest-api-server-with-client/attempt-log-3.md +0 -920
- package/docs/sessions/simple-rest-api/attempt-log-1.md +0 -593
- package/docs/sessions/websocket-serve-and-client/attempt-log-2.md +0 -995
- package/docs/tutorials/00-bootstrap.md +0 -166
- package/docs/tutorials/01-getting-started.md +0 -106
- package/docs/tutorials/02-container.md +0 -210
- package/docs/tutorials/03-scripts.md +0 -194
- package/docs/tutorials/04-features-overview.md +0 -196
- package/docs/tutorials/05-state-and-events.md +0 -171
- package/docs/tutorials/06-servers.md +0 -157
- package/docs/tutorials/07-endpoints.md +0 -198
- package/docs/tutorials/08-commands.md +0 -252
- package/docs/tutorials/09-clients.md +0 -162
- package/docs/tutorials/10-creating-features.md +0 -203
- package/docs/tutorials/11-contentbase.md +0 -191
- package/docs/tutorials/12-assistants.md +0 -215
- package/docs/tutorials/13-introspection.md +0 -157
- package/docs/tutorials/14-type-system.md +0 -174
- package/docs/tutorials/15-project-patterns.md +0 -222
- package/docs/tutorials/16-google-features.md +0 -534
- package/docs/tutorials/17-tui-blocks.md +0 -530
- package/docs/tutorials/18-semantic-search.md +0 -334
- package/docs/tutorials/19-python-sessions.md +0 -401
- package/docs/tutorials/20-browser-esm.md +0 -234
- package/index.ts +0 -1
- package/src/agi/endpoints/ask.ts +0 -60
- package/src/agi/endpoints/conversations/[id].ts +0 -45
- package/src/agi/endpoints/conversations.ts +0 -31
- package/src/agi/endpoints/experts.ts +0 -37
- package/test/assistant-hooks.test.ts +0 -306
- package/test/assistant.test.ts +0 -81
- package/test/bus.test.ts +0 -134
- package/test/clients-servers.test.ts +0 -217
- package/test/command.test.ts +0 -267
- package/test/container-link.test.ts +0 -274
- package/test/conversation.test.ts +0 -220
- package/test/features.test.ts +0 -160
- package/test/fork-and-research.test.ts +0 -450
- package/test/integration.test.ts +0 -787
- package/test/interceptor-chain.test.ts +0 -61
- package/test/node-container.test.ts +0 -121
- package/test/python-session.test.ts +0 -105
- package/test/rate-limit.test.ts +0 -272
- package/test/semantic-search.test.ts +0 -550
- package/test/state.test.ts +0 -121
- package/test/vm-context.test.ts +0 -146
- package/test/vm-loadmodule.test.ts +0 -213
- package/test/websocket-ask.test.ts +0 -101
- package/test-integration/assistant.test.ts +0 -138
- package/test-integration/assistants-manager.test.ts +0 -113
- package/test-integration/claude-code.test.ts +0 -98
- package/test-integration/conversation-history.test.ts +0 -205
- package/test-integration/conversation.test.ts +0 -137
- package/test-integration/elevenlabs.test.ts +0 -55
- package/test-integration/google-services.test.ts +0 -80
- package/test-integration/helpers.ts +0 -89
- package/test-integration/memory.test.ts +0 -204
- package/test-integration/openai-codex.test.ts +0 -93
- package/test-integration/runpod.test.ts +0 -58
- package/test-integration/server-endpoints.test.ts +0 -97
- package/test-integration/telegram.test.ts +0 -46
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: "Content Database"
|
|
3
|
-
tags: [contentDb, markdown, content, database]
|
|
4
|
-
lastTested: null
|
|
5
|
-
lastTestPassed: null
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# contentDb
|
|
9
|
-
|
|
10
|
-
Treat folders of structured markdown files as queryable databases. Each markdown file is a document with frontmatter metadata and content.
|
|
11
|
-
|
|
12
|
-
## Overview
|
|
13
|
-
|
|
14
|
-
The `contentDb` feature is on-demand. Enable it with a `rootPath` pointing to a directory that contains a `models.ts` file and subfolders of markdown documents. It is perfect for documentation sites, knowledge bases, or any content-driven application where markdown is the source of truth.
|
|
15
|
-
|
|
16
|
-
## Loading a Collection
|
|
17
|
-
|
|
18
|
-
We point the feature at the project's docs directory, which already has models and content.
|
|
19
|
-
|
|
20
|
-
```ts
|
|
21
|
-
const contentDb = container.feature('contentDb', { rootPath: '.' })
|
|
22
|
-
await contentDb.load()
|
|
23
|
-
console.log('Loaded:', contentDb.isLoaded)
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
The `load()` call discovers the models defined in `models.ts` and parses every markdown file in the matching prefix directories.
|
|
27
|
-
|
|
28
|
-
## Discovering Models
|
|
29
|
-
|
|
30
|
-
Each collection has named models. Let us see what is available.
|
|
31
|
-
|
|
32
|
-
```ts
|
|
33
|
-
const names = contentDb.modelNames
|
|
34
|
-
console.log('Available models:', names)
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
Models correspond to subdirectories. Each model defines a schema for the frontmatter metadata its documents must conform to.
|
|
38
|
-
|
|
39
|
-
## Querying Documents
|
|
40
|
-
|
|
41
|
-
Use `query()` to fetch documents belonging to a model. Here we query the Tutorial model.
|
|
42
|
-
|
|
43
|
-
```ts
|
|
44
|
-
const tutorials = await contentDb.query(contentDb.models.Tutorial).fetchAll()
|
|
45
|
-
console.log('Tutorial count:', tutorials.length)
|
|
46
|
-
tutorials.slice(0, 3).forEach(doc => {
|
|
47
|
-
console.log('-', doc.id, '|', doc.meta?.title)
|
|
48
|
-
})
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
Documents come back with their parsed frontmatter, content, and a unique id derived from the file path.
|
|
52
|
-
|
|
53
|
-
## Parsing a Single File
|
|
54
|
-
|
|
55
|
-
You can also parse any markdown file directly without going through the query system.
|
|
56
|
-
|
|
57
|
-
```ts
|
|
58
|
-
const doc = contentDb.parseMarkdownAtPath('./docs/tutorials/01-getting-started.md')
|
|
59
|
-
console.log('Title:', doc.meta?.title)
|
|
60
|
-
console.log('Tags:', doc.meta?.tags)
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
This is useful when you know exactly which file you want and do not need to iterate over a collection.
|
|
64
|
-
|
|
65
|
-
## Collection Summary
|
|
66
|
-
|
|
67
|
-
The feature tracks a model summary in its state, giving you a quick overview of the entire collection.
|
|
68
|
-
|
|
69
|
-
```ts
|
|
70
|
-
console.log(contentDb.state.get('modelSummary'))
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
This summary shows each model and how many documents belong to it.
|
|
74
|
-
|
|
75
|
-
## Summary
|
|
76
|
-
|
|
77
|
-
This demo covered loading a contentbase collection, listing models, querying documents by model, parsing individual markdown files, and inspecting the collection summary. The `contentDb` feature turns your markdown files into a lightweight, schema-validated content database.
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: "Disk Cache"
|
|
3
|
-
tags: [diskCache, storage, caching]
|
|
4
|
-
lastTested: null
|
|
5
|
-
lastTestPassed: null
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# diskCache
|
|
9
|
-
|
|
10
|
-
A file-backed key-value cache powered by cacache (the same store behind npm). Persist arbitrary data to disk with a simple get/set interface.
|
|
11
|
-
|
|
12
|
-
## Overview
|
|
13
|
-
|
|
14
|
-
The `diskCache` feature is on-demand. Enable it with a `path` option pointing to a cache directory. It is ideal for persisting computed results, downloaded assets, or any data you want to survive across process restarts without setting up a full database.
|
|
15
|
-
|
|
16
|
-
## Creating a Cache
|
|
17
|
-
|
|
18
|
-
We start by enabling the feature and pointing it at a temporary directory.
|
|
19
|
-
|
|
20
|
-
```ts
|
|
21
|
-
const cache = container.feature('diskCache', { path: '/tmp/luca-example-cache' })
|
|
22
|
-
console.log('diskCache enabled:', cache.state.get('enabled'))
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
The cache directory is created automatically when the first entry is written.
|
|
26
|
-
|
|
27
|
-
## Storing and Retrieving Values
|
|
28
|
-
|
|
29
|
-
Use `set()` to write a key and `get()` to read it back.
|
|
30
|
-
|
|
31
|
-
```ts
|
|
32
|
-
await cache.set('greeting', 'Hello from Luca!')
|
|
33
|
-
const value = await cache.get('greeting')
|
|
34
|
-
console.log('Retrieved:', value)
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
The value comes back exactly as stored.
|
|
38
|
-
|
|
39
|
-
## Checking for Keys
|
|
40
|
-
|
|
41
|
-
Use `has()` to check whether a key exists without reading it.
|
|
42
|
-
|
|
43
|
-
```ts
|
|
44
|
-
const exists = await cache.has('greeting')
|
|
45
|
-
console.log('Has greeting?', exists)
|
|
46
|
-
const missing = await cache.has('nonexistent')
|
|
47
|
-
console.log('Has nonexistent?', missing)
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
This is useful for conditional caching patterns where you want to skip expensive work if a result is already stored.
|
|
51
|
-
|
|
52
|
-
## Listing All Keys
|
|
53
|
-
|
|
54
|
-
Use `keys()` to enumerate everything in the cache.
|
|
55
|
-
|
|
56
|
-
```ts
|
|
57
|
-
await cache.set('user:1', JSON.stringify({ name: 'Alice' }))
|
|
58
|
-
await cache.set('user:2', JSON.stringify({ name: 'Bob' }))
|
|
59
|
-
const allKeys = await cache.keys()
|
|
60
|
-
console.log('All keys:', allKeys)
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
Keys are plain strings, so you can use naming conventions like prefixes to organize entries.
|
|
64
|
-
|
|
65
|
-
## Removing Entries
|
|
66
|
-
|
|
67
|
-
Use `rm()` to delete a single key, or `clearAll(true)` to wipe the entire cache.
|
|
68
|
-
|
|
69
|
-
```ts
|
|
70
|
-
await cache.rm('user:2')
|
|
71
|
-
const afterRemove = await cache.keys()
|
|
72
|
-
console.log('After removing user:2:', afterRemove)
|
|
73
|
-
|
|
74
|
-
await cache.clearAll(true)
|
|
75
|
-
const afterClear = await cache.keys()
|
|
76
|
-
console.log('After clearAll:', afterClear)
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
Note that `clearAll` requires passing `true` as a confirmation safeguard.
|
|
80
|
-
|
|
81
|
-
## Summary
|
|
82
|
-
|
|
83
|
-
This demo covered creating a disk cache, storing and retrieving values, checking key existence, listing keys, and removing entries. The `diskCache` feature provides a lightweight persistence layer without any external dependencies.
|
package/docs/examples/docker.md
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: "Docker"
|
|
3
|
-
tags: [docker, containers, images, devops]
|
|
4
|
-
lastTested: null
|
|
5
|
-
lastTestPassed: null
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# docker
|
|
9
|
-
|
|
10
|
-
Docker CLI interface for managing containers, images, and executing commands inside running containers. Provides comprehensive Docker operations including build, run, exec, logs, and system pruning.
|
|
11
|
-
|
|
12
|
-
## Overview
|
|
13
|
-
|
|
14
|
-
The `docker` feature wraps the Docker CLI to give you programmatic control over containers and images. It requires Docker to be installed and the Docker daemon to be running on the host machine. All methods return structured data rather than raw CLI output.
|
|
15
|
-
|
|
16
|
-
## Enabling the Feature
|
|
17
|
-
|
|
18
|
-
```ts
|
|
19
|
-
const docker = container.feature('docker', { enable: true })
|
|
20
|
-
console.log('Docker feature enabled:', docker.state.get('enabled'))
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## Exploring the API
|
|
24
|
-
|
|
25
|
-
```ts
|
|
26
|
-
const docs = container.features.describe('docker')
|
|
27
|
-
console.log(docs)
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## Checking Availability
|
|
31
|
-
|
|
32
|
-
```ts
|
|
33
|
-
const docker = container.feature('docker')
|
|
34
|
-
const available = await docker.checkDockerAvailability()
|
|
35
|
-
console.log('Docker available:', available)
|
|
36
|
-
console.log('State:', docker.state.get('isDockerAvailable'))
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
## Building an Image
|
|
40
|
-
|
|
41
|
-
Build a Docker image from a Dockerfile in a project directory.
|
|
42
|
-
|
|
43
|
-
```ts skip
|
|
44
|
-
await docker.buildImage('./my-project', {
|
|
45
|
-
tag: 'my-app:latest',
|
|
46
|
-
buildArgs: { NODE_ENV: 'production' },
|
|
47
|
-
nocache: true
|
|
48
|
-
})
|
|
49
|
-
console.log('Image built successfully')
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
If the build succeeds, the image appears in `docker.listImages()`. The `buildArgs` option passes `--build-arg` flags to the Docker build command.
|
|
53
|
-
|
|
54
|
-
## Running a Container
|
|
55
|
-
|
|
56
|
-
Create and start a container from an image with port mappings, volumes, and environment variables.
|
|
57
|
-
|
|
58
|
-
```ts skip
|
|
59
|
-
const containerId = await docker.runContainer('nginx:latest', {
|
|
60
|
-
name: 'web-server',
|
|
61
|
-
ports: ['8080:80'],
|
|
62
|
-
detach: true,
|
|
63
|
-
environment: { NGINX_HOST: 'localhost' }
|
|
64
|
-
})
|
|
65
|
-
console.log('Container started:', containerId)
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
The `detach: true` option runs the container in the background and returns its ID. Without it, the call blocks until the container exits.
|
|
69
|
-
|
|
70
|
-
## Executing Commands in a Container
|
|
71
|
-
|
|
72
|
-
Run commands inside a running container and capture the output.
|
|
73
|
-
|
|
74
|
-
```ts skip
|
|
75
|
-
const result = await docker.execCommand('web-server', ['ls', '-la', '/usr/share/nginx/html'])
|
|
76
|
-
console.log('stdout:', result.stdout)
|
|
77
|
-
console.log('exit code:', result.exitCode)
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
The command array avoids shell interpretation issues. The returned object includes `stdout`, `stderr`, and `exitCode`.
|
|
81
|
-
|
|
82
|
-
## Creating a Shell
|
|
83
|
-
|
|
84
|
-
The `createShell` method returns a shell-like wrapper for running multiple commands against the same container.
|
|
85
|
-
|
|
86
|
-
```ts skip
|
|
87
|
-
const shell = await docker.createShell('web-server', {
|
|
88
|
-
workdir: '/app'
|
|
89
|
-
})
|
|
90
|
-
await shell.run('ls -la')
|
|
91
|
-
console.log(shell.last.stdout)
|
|
92
|
-
await shell.run('cat package.json')
|
|
93
|
-
console.log(shell.last.stdout)
|
|
94
|
-
await shell.destroy()
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
Call `destroy()` when finished to clean up any helper containers created for volume-mounted shells.
|
|
98
|
-
|
|
99
|
-
## Summary
|
|
100
|
-
|
|
101
|
-
The `docker` feature provides a complete programmatic interface to Docker: build images, run and manage containers, execute commands inside them, retrieve logs, and prune unused resources. All operations require the Docker daemon to be running on the host.
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: "Downloader"
|
|
3
|
-
tags: [downloader, network, files, http]
|
|
4
|
-
lastTested: null
|
|
5
|
-
lastTestPassed: null
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# downloader
|
|
9
|
-
|
|
10
|
-
Download files from remote URLs and save them to the local filesystem.
|
|
11
|
-
|
|
12
|
-
## Overview
|
|
13
|
-
|
|
14
|
-
The `downloader` feature is an on-demand feature that fetches files from HTTP/HTTPS URLs and writes them to disk. It handles the network request, buffering, and file writing automatically. Use it when you need to programmatically pull remote assets -- images, documents, data files -- into your project.
|
|
15
|
-
|
|
16
|
-
## Feature Documentation
|
|
17
|
-
|
|
18
|
-
Let us inspect the feature's built-in documentation to understand its API.
|
|
19
|
-
|
|
20
|
-
```ts
|
|
21
|
-
const desc = container.features.describe('downloader')
|
|
22
|
-
console.log(desc)
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
The feature exposes a single `download(url, targetPath)` method that fetches a URL and writes the response body to the specified path.
|
|
26
|
-
|
|
27
|
-
## Enabling the Feature
|
|
28
|
-
|
|
29
|
-
Enable the downloader and inspect its initial state.
|
|
30
|
-
|
|
31
|
-
```ts
|
|
32
|
-
const downloader = container.feature('downloader', { enable: true })
|
|
33
|
-
console.log('Downloader enabled:', downloader.state.enabled)
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
Once enabled, the feature is ready to accept download requests.
|
|
37
|
-
|
|
38
|
-
## Inspecting the API
|
|
39
|
-
|
|
40
|
-
The downloader has a straightforward interface: one method for downloading.
|
|
41
|
-
|
|
42
|
-
```ts
|
|
43
|
-
const methods = Object.getOwnPropertyNames(Object.getPrototypeOf(downloader))
|
|
44
|
-
.filter(m => !m.startsWith('_') && m !== 'constructor')
|
|
45
|
-
console.log('Available methods:', methods.join(', '))
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
The `download` method takes two arguments: a URL string and a target file path. The target path is resolved relative to the container's working directory.
|
|
49
|
-
|
|
50
|
-
## How Downloading Works
|
|
51
|
-
|
|
52
|
-
Here is what happens when you call `download()`:
|
|
53
|
-
|
|
54
|
-
1. The feature makes an HTTP fetch to the provided URL
|
|
55
|
-
2. The response is buffered into memory
|
|
56
|
-
3. The buffer is written to the filesystem at the target path
|
|
57
|
-
4. The path is resolved using the container's path resolution
|
|
58
|
-
|
|
59
|
-
```ts
|
|
60
|
-
// Example usage (not executed to avoid network calls):
|
|
61
|
-
// await downloader.download(
|
|
62
|
-
// 'https://example.com/data.json',
|
|
63
|
-
// 'downloads/data.json'
|
|
64
|
-
// )
|
|
65
|
-
console.log('Downloader is ready. Call downloader.download(url, path) to fetch files.')
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
## Summary
|
|
69
|
-
|
|
70
|
-
This demo covered the `downloader` feature, which provides a simple one-method API for fetching remote files and saving them locally. It handles HTTP requests, buffering, and file writing, making it the right choice for any task that involves pulling assets from the network.
|
package/docs/examples/entity.md
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: "Entity"
|
|
3
|
-
tags: [entity, state, events, tools, core]
|
|
4
|
-
lastTested: null
|
|
5
|
-
lastTestPassed: null
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# entity
|
|
9
|
-
|
|
10
|
-
Lightweight, composable objects with observable state, a typed event bus, and an optional tool interface.
|
|
11
|
-
|
|
12
|
-
## Overview
|
|
13
|
-
|
|
14
|
-
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()`.
|
|
15
|
-
|
|
16
|
-
## Basic Entity with Observable State
|
|
17
|
-
|
|
18
|
-
Create an entity and read/write state through the observable `state` property.
|
|
19
|
-
|
|
20
|
-
```ts
|
|
21
|
-
const counter = container.entity<{ count: number }>('counter')
|
|
22
|
-
counter.setState({ count: 0 })
|
|
23
|
-
|
|
24
|
-
counter.state.observe((next) => {
|
|
25
|
-
console.log('count changed to', next.count)
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
counter.setState(s => ({ count: s.count + 1 }))
|
|
29
|
-
counter.setState(s => ({ count: s.count + 1 }))
|
|
30
|
-
console.log('final count:', counter.state.get('count'))
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
`setState` accepts either a partial object or a function that receives the current state. Observers fire synchronously after each change.
|
|
34
|
-
|
|
35
|
-
## Typed Event Bus
|
|
36
|
-
|
|
37
|
-
Every entity has a built-in event bus. Declare the event map as the third type parameter.
|
|
38
|
-
|
|
39
|
-
```ts
|
|
40
|
-
type TimerEvents = {
|
|
41
|
-
tick: [elapsed: number]
|
|
42
|
-
done: []
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const timer = container.entity<{}, {}, TimerEvents>('timer')
|
|
46
|
-
|
|
47
|
-
timer.on('tick', (elapsed) => {
|
|
48
|
-
console.log('tick at', elapsed, 'ms')
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
timer.once('done', () => {
|
|
52
|
-
console.log('timer finished')
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
timer.emit('tick', 100)
|
|
56
|
-
timer.emit('tick', 200)
|
|
57
|
-
timer.emit('done')
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
`once` auto-detaches after the first fire. `waitFor` returns a promise that resolves on the next emit of that event.
|
|
61
|
-
|
|
62
|
-
## Extending with Methods
|
|
63
|
-
|
|
64
|
-
Use `.extend()` to graft methods and getters onto an entity. All base properties — `state`, `options`, `container`, and the event methods — are available via `this`.
|
|
65
|
-
|
|
66
|
-
```ts
|
|
67
|
-
const session = container.entity('session', { userId: '42' })
|
|
68
|
-
.extend({
|
|
69
|
-
greet() {
|
|
70
|
-
return `Hello user ${this.options.userId}`
|
|
71
|
-
},
|
|
72
|
-
get label() {
|
|
73
|
-
return `Session ${this.id} (user ${this.options.userId})`
|
|
74
|
-
},
|
|
75
|
-
bump() {
|
|
76
|
-
const visits = (this.state.get('visits') ?? 0) + 1
|
|
77
|
-
this.setState({ visits })
|
|
78
|
-
this.emit('visited', visits)
|
|
79
|
-
return visits
|
|
80
|
-
},
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
console.log(session.greet())
|
|
84
|
-
console.log(session.label)
|
|
85
|
-
console.log('visits:', session.bump())
|
|
86
|
-
console.log('visits:', session.bump())
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
Extensions are chained via prototype delegation — each layer can see everything below it.
|
|
90
|
-
|
|
91
|
-
## Exposing Methods as AI Tools
|
|
92
|
-
|
|
93
|
-
Use `.expose(methodName, zodSchema)` to register methods as tools. `.toTools()` returns `{ schemas, handlers }` compatible with `assistant.addTools()`.
|
|
94
|
-
|
|
95
|
-
```ts
|
|
96
|
-
const search = container.entity('search', {})
|
|
97
|
-
.extend({
|
|
98
|
-
async lookup({ query }: { query: string }) {
|
|
99
|
-
return `Results for: ${query}`
|
|
100
|
-
},
|
|
101
|
-
async summarize({ text, maxWords }: { text: string; maxWords: number }) {
|
|
102
|
-
return text.split(' ').slice(0, maxWords).join(' ')
|
|
103
|
-
},
|
|
104
|
-
})
|
|
105
|
-
.expose('lookup', z.object({
|
|
106
|
-
query: z.string().describe('The search query'),
|
|
107
|
-
}))
|
|
108
|
-
.expose('summarize', z.object({
|
|
109
|
-
text: z.string().describe('Text to summarize'),
|
|
110
|
-
maxWords: z.number().describe('Maximum words in summary'),
|
|
111
|
-
}))
|
|
112
|
-
|
|
113
|
-
const { schemas, handlers } = search.toTools()
|
|
114
|
-
console.log('registered tools:', Object.keys(schemas))
|
|
115
|
-
|
|
116
|
-
// Pass directly to an assistant
|
|
117
|
-
// assistant.addTools(search)
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
`.expose()` is chainable and returns `this`, so you can stack as many as you need.
|
|
121
|
-
|
|
122
|
-
## Summary
|
|
123
|
-
|
|
124
|
-
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.
|
package/docs/examples/esbuild.md
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: "esbuild"
|
|
3
|
-
tags: [esbuild, transpilation, bundling, typescript]
|
|
4
|
-
lastTested: null
|
|
5
|
-
lastTestPassed: null
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# esbuild
|
|
9
|
-
|
|
10
|
-
Transpile TypeScript, TSX, and JSX to JavaScript at runtime using Bun's built-in transpiler. Compile code strings on the fly without touching the filesystem.
|
|
11
|
-
|
|
12
|
-
## Overview
|
|
13
|
-
|
|
14
|
-
The `esbuild` feature is a core feature, meaning it is auto-enabled on every container. You can access it directly as a global or via `container.feature('esbuild')`. It wraps Bun's transpiler and exposes both synchronous and asynchronous `transform` methods. Use it for runtime code generation, plugin systems, or any scenario where you need to compile TypeScript strings to runnable JavaScript.
|
|
15
|
-
|
|
16
|
-
## Synchronous Transform
|
|
17
|
-
|
|
18
|
-
Use `transformSync()` to transpile a TypeScript string to JavaScript in a single blocking call.
|
|
19
|
-
|
|
20
|
-
```ts
|
|
21
|
-
const result = esbuild.transformSync('const x: number = 42; console.log(x);')
|
|
22
|
-
console.log('Input: const x: number = 42; console.log(x);')
|
|
23
|
-
console.log('Output:', result.code.trim())
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
The type annotations are stripped and the output is plain JavaScript.
|
|
27
|
-
|
|
28
|
-
## Async Transform
|
|
29
|
-
|
|
30
|
-
The async `transform()` method does the same thing but returns a promise. Prefer this in hot paths where you do not want to block.
|
|
31
|
-
|
|
32
|
-
```ts
|
|
33
|
-
const tsxCode = `
|
|
34
|
-
interface Props { name: string }
|
|
35
|
-
const Greet = (props: Props) => <h1>Hello {props.name}</h1>
|
|
36
|
-
`
|
|
37
|
-
const out = await esbuild.transform(tsxCode, { loader: 'tsx' })
|
|
38
|
-
console.log('TSX transpiled:')
|
|
39
|
-
console.log(out.code.trim())
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
Notice the `loader: 'tsx'` option tells the transpiler to handle JSX syntax.
|
|
43
|
-
|
|
44
|
-
## Minification
|
|
45
|
-
|
|
46
|
-
Pass `minify: true` to produce compact output with whitespace removed.
|
|
47
|
-
|
|
48
|
-
```ts
|
|
49
|
-
const verbose = `
|
|
50
|
-
function greet(name: string): string {
|
|
51
|
-
const greeting = "Hello, " + name + "!";
|
|
52
|
-
return greeting;
|
|
53
|
-
}
|
|
54
|
-
`
|
|
55
|
-
const normal = esbuild.transformSync(verbose)
|
|
56
|
-
const minified = esbuild.transformSync(verbose, { minify: true })
|
|
57
|
-
console.log('Normal length:', normal.code.length)
|
|
58
|
-
console.log('Minified length:', minified.code.length)
|
|
59
|
-
console.log('Minified:', minified.code.trim())
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
Minification is useful when generating code that will be sent to a browser or embedded in a response.
|
|
63
|
-
|
|
64
|
-
## Different Loaders
|
|
65
|
-
|
|
66
|
-
The feature supports multiple source languages via the `loader` option.
|
|
67
|
-
|
|
68
|
-
```ts
|
|
69
|
-
const jsxResult = esbuild.transformSync(
|
|
70
|
-
'const App = () => <div className="app">Content</div>',
|
|
71
|
-
{ loader: 'tsx' }
|
|
72
|
-
)
|
|
73
|
-
console.log('JSX output:', jsxResult.code.trim())
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
Supported loaders include `ts` (default), `tsx`, `jsx`, and `js`.
|
|
77
|
-
|
|
78
|
-
## Summary
|
|
79
|
-
|
|
80
|
-
This demo covered synchronous and asynchronous transpilation, minification, and using different source loaders. The `esbuild` feature gives you runtime TypeScript-to-JavaScript compilation with zero configuration.
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: "Features as Tool Providers for Assistants"
|
|
3
|
-
tags: [feature, tools, assistant, composition, use, setupToolsConsumer]
|
|
4
|
-
lastTested: null
|
|
5
|
-
lastTestPassed: null
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Features as Tool Providers for Assistants
|
|
9
|
-
|
|
10
|
-
Any feature can expose tools that assistants pick up via `assistant.use(feature)`. This is how you compose lower-level container capabilities into an assistant-ready tool surface. The built-in `fileTools` feature is the canonical example — it wraps `fs` and `grep` into a focused set of tools modeled on what coding assistants need.
|
|
11
|
-
|
|
12
|
-
## The Pattern
|
|
13
|
-
|
|
14
|
-
A feature becomes a tool provider by defining three things:
|
|
15
|
-
|
|
16
|
-
1. **`static tools`** — a record mapping tool names to Zod schemas with descriptions
|
|
17
|
-
2. **Matching methods** — instance methods whose names match the keys in `static tools`
|
|
18
|
-
3. **`setupToolsConsumer()`** (optional) — a hook that runs when an assistant calls `use()`, perfect for injecting system prompt guidance
|
|
19
|
-
|
|
20
|
-
When an assistant calls `assistant.use(feature)`, the framework:
|
|
21
|
-
- Reads `static tools` to register each tool with its schema
|
|
22
|
-
- Routes tool calls to the matching instance methods
|
|
23
|
-
- Calls `setupToolsConsumer()` so the feature can configure the assistant (e.g. add system prompt extensions)
|
|
24
|
-
|
|
25
|
-
## Anatomy of fileTools
|
|
26
|
-
|
|
27
|
-
Here's the structure of the built-in `fileTools` feature (simplified for clarity):
|
|
28
|
-
|
|
29
|
-
```ts
|
|
30
|
-
import { z } from 'zod'
|
|
31
|
-
import { Feature } from '@soederpop/luca/feature'
|
|
32
|
-
|
|
33
|
-
export class FileTools extends Feature {
|
|
34
|
-
static { Feature.register(this, 'fileTools') }
|
|
35
|
-
|
|
36
|
-
// ── 1. Declare tools with Zod schemas ──────────────────────────
|
|
37
|
-
static tools = {
|
|
38
|
-
readFile: {
|
|
39
|
-
description: 'Read the contents of a file.',
|
|
40
|
-
schema: z.object({
|
|
41
|
-
path: z.string().describe('File path relative to the project root'),
|
|
42
|
-
offset: z.number().optional().describe('Line number to start reading from'),
|
|
43
|
-
limit: z.number().optional().describe('Maximum number of lines to read'),
|
|
44
|
-
}),
|
|
45
|
-
},
|
|
46
|
-
searchFiles: {
|
|
47
|
-
description: 'Search file contents for a pattern using ripgrep.',
|
|
48
|
-
schema: z.object({
|
|
49
|
-
pattern: z.string().describe('Search pattern (regex supported)'),
|
|
50
|
-
path: z.string().optional().describe('Directory to search in'),
|
|
51
|
-
include: z.string().optional().describe('Glob pattern to filter files'),
|
|
52
|
-
}),
|
|
53
|
-
},
|
|
54
|
-
editFile: {
|
|
55
|
-
description: 'Replace an exact string match in a file.',
|
|
56
|
-
schema: z.object({
|
|
57
|
-
path: z.string().describe('File path relative to the project root'),
|
|
58
|
-
oldString: z.string().describe('The exact text to find and replace'),
|
|
59
|
-
newString: z.string().describe('The replacement text'),
|
|
60
|
-
}),
|
|
61
|
-
},
|
|
62
|
-
// ... more tools
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// ── 2. Implement each tool as an instance method ───────────────
|
|
66
|
-
// Method names must match the keys in static tools exactly.
|
|
67
|
-
// Each receives the parsed args object and returns a string.
|
|
68
|
-
|
|
69
|
-
async readFile(args: { path: string; offset?: number; limit?: number }) {
|
|
70
|
-
const fs = this.container.feature('fs')
|
|
71
|
-
const content = await fs.readFileAsync(args.path)
|
|
72
|
-
// ... handle offset/limit
|
|
73
|
-
return content
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
async searchFiles(args: { pattern: string; path?: string; include?: string }) {
|
|
77
|
-
const grep = this.container.feature('grep')
|
|
78
|
-
const results = await grep.search({ pattern: args.pattern, path: args.path, include: args.include })
|
|
79
|
-
return JSON.stringify(results.map(r => ({ file: r.file, line: r.line, content: r.content })))
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
async editFile(args: { path: string; oldString: string; newString: string }) {
|
|
83
|
-
const fs = this.container.feature('fs')
|
|
84
|
-
const content = await fs.readFileAsync(args.path)
|
|
85
|
-
const updated = content.replace(args.oldString, args.newString)
|
|
86
|
-
await fs.writeFileAsync(args.path, updated)
|
|
87
|
-
return `Edited ${args.path}`
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// ── 3. Configure the assistant when it calls use() ─────────────
|
|
91
|
-
override setupToolsConsumer(consumer) {
|
|
92
|
-
// If the consumer is an assistant, inject guidance into its system prompt
|
|
93
|
-
if (typeof consumer.addSystemPromptExtension === 'function') {
|
|
94
|
-
consumer.addSystemPromptExtension('fileTools', [
|
|
95
|
-
'## File Tools',
|
|
96
|
-
'- All file paths are relative to the project root unless they start with /',
|
|
97
|
-
'- Use searchFiles to understand code before modifying it',
|
|
98
|
-
'- Use editFile for surgical changes — prefer it over writeFile',
|
|
99
|
-
].join('\n'))
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
## Using It
|
|
106
|
-
|
|
107
|
-
```ts
|
|
108
|
-
const assistant = container.feature('assistant', {
|
|
109
|
-
systemPrompt: 'You are a coding assistant.',
|
|
110
|
-
model: 'gpt-4.1-mini',
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
const fileTools = container.feature('fileTools')
|
|
114
|
-
assistant.use(fileTools)
|
|
115
|
-
await assistant.start()
|
|
116
|
-
|
|
117
|
-
// The assistant now has readFile, searchFiles, editFile, etc.
|
|
118
|
-
// and its system prompt includes the fileTools guidance.
|
|
119
|
-
console.log(Object.keys(assistant.tools))
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
### Selective tool registration
|
|
123
|
-
|
|
124
|
-
You can expose only a subset of tools:
|
|
125
|
-
|
|
126
|
-
```ts
|
|
127
|
-
assistant.use(fileTools.toTools({ only: ['readFile', 'searchFiles', 'listDirectory'] }))
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
## Why This Pattern Matters
|
|
131
|
-
|
|
132
|
-
This is how features compose for AI. Instead of the assistant importing `fs` and `grep` directly:
|
|
133
|
-
|
|
134
|
-
- The **feature** owns the tool surface — schemas, descriptions, and implementations in one place
|
|
135
|
-
- The **assistant** gets a curated interface, not raw container access
|
|
136
|
-
- **`setupToolsConsumer()`** lets the feature teach the assistant how to use the tools well
|
|
137
|
-
- **`toTools({ only })`** lets you scope down what the assistant can do
|
|
138
|
-
|
|
139
|
-
Any feature you build can follow this same pattern. Define `static tools`, implement matching methods, optionally override `setupToolsConsumer()`, and assistants can `use()` it.
|
|
140
|
-
|
|
141
|
-
## Summary
|
|
142
|
-
|
|
143
|
-
Features are the natural place to package tools for assistants. The `static tools` record declares the schema, instance methods implement the logic, and `setupToolsConsumer()` wires up assistant-specific configuration like system prompt extensions. This keeps tool definitions, implementations, and assistant guidance co-located in a single feature class.
|