dexto 1.5.8 → 1.6.1
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/README.md +3 -3
- package/dist/agents/agent-template.yml +2 -2
- package/dist/agents/coding-agent/README.md +10 -10
- package/dist/agents/coding-agent/coding-agent.yml +84 -83
- package/dist/agents/default-agent.yml +32 -47
- package/dist/agents/explore-agent/explore-agent.yml +3 -6
- package/dist/agents/image-editor-agent/image-editor-agent.yml +1 -1
- package/dist/agents/nano-banana-agent/nano-banana-agent.yml +1 -1
- package/dist/agents/podcast-agent/podcast-agent.yml +1 -1
- package/dist/agents/product-name-researcher/product-name-researcher.yml +1 -1
- package/dist/agents/sora-video-agent/sora-video-agent.yml +4 -6
- package/dist/agents/triage-demo/triage-agent.yml +1 -1
- package/dist/analytics/events.d.ts +1 -1
- package/dist/analytics/events.d.ts.map +1 -1
- package/dist/api/mcp/tool-aggregation-handler.d.ts +2 -2
- package/dist/api/server-hono.d.ts +2 -2
- package/dist/api/server-hono.d.ts.map +1 -1
- package/dist/api/server-hono.js +37 -60
- package/dist/cli/approval/cli-approval-handler.d.ts +10 -3
- package/dist/cli/approval/cli-approval-handler.d.ts.map +1 -1
- package/dist/cli/approval/cli-approval-handler.js +1 -1
- package/dist/cli/assets/sounds/SOURCES.md +35 -0
- package/dist/cli/assets/sounds/boot.wav +0 -0
- package/dist/cli/assets/sounds/chime.wav +0 -0
- package/dist/cli/assets/sounds/coin.wav +0 -0
- package/dist/cli/assets/sounds/confirm.wav +0 -0
- package/dist/cli/assets/sounds/levelup.wav +0 -0
- package/dist/cli/assets/sounds/ping.wav +0 -0
- package/dist/cli/assets/sounds/powerup.wav +0 -0
- package/dist/cli/assets/sounds/startup.wav +0 -0
- package/dist/cli/assets/sounds/success.wav +0 -0
- package/dist/cli/assets/sounds/treasure.wav +0 -0
- package/dist/cli/assets/sounds/win.wav +0 -0
- package/dist/cli/commands/create-app.d.ts +1 -11
- package/dist/cli/commands/create-app.d.ts.map +1 -1
- package/dist/cli/commands/create-app.js +21 -545
- package/dist/cli/commands/create-image.d.ts.map +1 -1
- package/dist/cli/commands/create-image.js +54 -53
- package/dist/cli/commands/image.d.ts +52 -0
- package/dist/cli/commands/image.d.ts.map +1 -0
- package/dist/cli/commands/image.js +118 -0
- package/dist/cli/commands/index.d.ts +2 -1
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +3 -1
- package/dist/cli/commands/init-app.d.ts +4 -8
- package/dist/cli/commands/init-app.d.ts.map +1 -1
- package/dist/cli/commands/init-app.js +37 -161
- package/dist/cli/commands/interactive-commands/command-parser.d.ts +2 -0
- package/dist/cli/commands/interactive-commands/command-parser.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/commands.d.ts +1 -1
- package/dist/cli/commands/interactive-commands/commands.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/commands.js +2 -2
- package/dist/cli/commands/interactive-commands/exit-handler.d.ts +12 -0
- package/dist/cli/commands/interactive-commands/exit-handler.d.ts.map +1 -0
- package/dist/cli/commands/interactive-commands/exit-handler.js +20 -0
- package/dist/cli/commands/interactive-commands/exit-stats.d.ts +24 -0
- package/dist/cli/commands/interactive-commands/exit-stats.d.ts.map +1 -0
- package/dist/cli/commands/interactive-commands/exit-stats.js +17 -0
- package/dist/cli/commands/interactive-commands/general-commands.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/general-commands.js +55 -5
- package/dist/cli/commands/interactive-commands/prompt-commands.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/prompt-commands.js +14 -74
- package/dist/cli/commands/interactive-commands/session/index.d.ts +2 -1
- package/dist/cli/commands/interactive-commands/session/index.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/session/index.js +2 -1
- package/dist/cli/commands/interactive-commands/session/session-commands.d.ts +2 -2
- package/dist/cli/commands/interactive-commands/session/session-commands.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/session/session-commands.js +2 -4
- package/dist/cli/commands/interactive-commands/system/system-commands.d.ts +1 -13
- package/dist/cli/commands/interactive-commands/system/system-commands.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/system/system-commands.js +52 -83
- package/dist/cli/commands/plugin.d.ts +4 -4
- package/dist/cli/commands/sync-agents.d.ts +2 -12
- package/dist/cli/commands/sync-agents.d.ts.map +1 -1
- package/dist/cli/commands/sync-agents.js +2 -50
- package/dist/cli/ink-cli/InkCLIRefactored.d.ts +7 -1
- package/dist/cli/ink-cli/InkCLIRefactored.d.ts.map +1 -1
- package/dist/cli/ink-cli/InkCLIRefactored.js +138 -27
- package/dist/cli/ink-cli/components/ApprovalPrompt.d.ts +2 -2
- package/dist/cli/ink-cli/components/ApprovalPrompt.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/ApprovalPrompt.js +85 -30
- package/dist/cli/ink-cli/components/BackgroundTasksPanel.js +1 -1
- package/dist/cli/ink-cli/components/ElicitationForm.d.ts +5 -3
- package/dist/cli/ink-cli/components/ElicitationForm.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/ElicitationForm.js +414 -180
- package/dist/cli/ink-cli/components/Footer.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/Footer.js +1 -2
- package/dist/cli/ink-cli/components/ResourceAutocomplete.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/ResourceAutocomplete.js +20 -11
- package/dist/cli/ink-cli/components/SlashCommandAutocomplete.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/SlashCommandAutocomplete.js +47 -67
- package/dist/cli/ink-cli/components/StatusBar.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/StatusBar.js +20 -10
- package/dist/cli/ink-cli/components/TodoPanel.js +1 -1
- package/dist/cli/ink-cli/components/base/BaseSelector.d.ts +2 -1
- package/dist/cli/ink-cli/components/base/BaseSelector.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/base/BaseSelector.js +37 -27
- package/dist/cli/ink-cli/components/chat/Header.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/chat/Header.js +1 -1
- package/dist/cli/ink-cli/components/chat/MessageItem.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/chat/MessageItem.js +3 -1
- package/dist/cli/ink-cli/components/chat/ToolIcon.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/chat/ToolIcon.js +5 -15
- package/dist/cli/ink-cli/components/chat/styled-boxes/ConfigBox.js +1 -1
- package/dist/cli/ink-cli/components/chat/styled-boxes/LogConfigBox.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/chat/styled-boxes/LogConfigBox.js +1 -1
- package/dist/cli/ink-cli/components/modes/AlternateBufferCLI.d.ts +3 -1
- package/dist/cli/ink-cli/components/modes/AlternateBufferCLI.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/modes/AlternateBufferCLI.js +5 -3
- package/dist/cli/ink-cli/components/modes/StaticCLI.d.ts +3 -1
- package/dist/cli/ink-cli/components/modes/StaticCLI.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/modes/StaticCLI.js +10 -3
- package/dist/cli/ink-cli/components/overlays/CommandOutputOverlay.d.ts +13 -0
- package/dist/cli/ink-cli/components/overlays/CommandOutputOverlay.d.ts.map +1 -0
- package/dist/cli/ink-cli/components/overlays/CommandOutputOverlay.js +60 -0
- package/dist/cli/ink-cli/components/overlays/LogLevelSelector.js +1 -1
- package/dist/cli/ink-cli/components/overlays/ModelSelectorRefactored.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/overlays/ModelSelectorRefactored.js +213 -100
- package/dist/cli/ink-cli/components/overlays/PromptList.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/overlays/PromptList.js +12 -16
- package/dist/cli/ink-cli/components/overlays/SoundsSelector.d.ts +21 -0
- package/dist/cli/ink-cli/components/overlays/SoundsSelector.d.ts.map +1 -0
- package/dist/cli/ink-cli/components/overlays/SoundsSelector.js +566 -0
- package/dist/cli/ink-cli/components/overlays/ToolBrowser.d.ts +1 -1
- package/dist/cli/ink-cli/components/overlays/ToolBrowser.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/overlays/ToolBrowser.js +100 -45
- package/dist/cli/ink-cli/components/overlays/custom-model-wizard/LocalModelWizard.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/overlays/custom-model-wizard/LocalModelWizard.js +8 -13
- package/dist/cli/ink-cli/components/renderers/FilePreviewRenderer.d.ts +3 -3
- package/dist/cli/ink-cli/components/renderers/FilePreviewRenderer.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/renderers/FilePreviewRenderer.js +6 -5
- package/dist/cli/ink-cli/components/renderers/FileRenderer.d.ts +3 -1
- package/dist/cli/ink-cli/components/renderers/FileRenderer.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/renderers/FileRenderer.js +18 -7
- package/dist/cli/ink-cli/components/renderers/ShellRenderer.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/renderers/ShellRenderer.js +7 -17
- package/dist/cli/ink-cli/components/renderers/index.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/renderers/index.js +1 -1
- package/dist/cli/ink-cli/components/shared/FocusOverlayFrame.d.ts +7 -0
- package/dist/cli/ink-cli/components/shared/FocusOverlayFrame.d.ts.map +1 -0
- package/dist/cli/ink-cli/components/shared/FocusOverlayFrame.js +8 -0
- package/dist/cli/ink-cli/components/shared/HintBar.d.ts +6 -0
- package/dist/cli/ink-cli/components/shared/HintBar.d.ts.map +1 -0
- package/dist/cli/ink-cli/components/shared/HintBar.js +6 -0
- package/dist/cli/ink-cli/constants/spinnerFrames.d.ts +2 -0
- package/dist/cli/ink-cli/constants/spinnerFrames.d.ts.map +1 -0
- package/dist/cli/ink-cli/constants/spinnerFrames.js +1 -0
- package/dist/cli/ink-cli/constants/tips.d.ts.map +1 -1
- package/dist/cli/ink-cli/constants/tips.js +2 -1
- package/dist/cli/ink-cli/containers/InputContainer.d.ts +4 -0
- package/dist/cli/ink-cli/containers/InputContainer.d.ts.map +1 -1
- package/dist/cli/ink-cli/containers/InputContainer.js +47 -21
- package/dist/cli/ink-cli/containers/OverlayContainer.d.ts +2 -0
- package/dist/cli/ink-cli/containers/OverlayContainer.d.ts.map +1 -1
- package/dist/cli/ink-cli/containers/OverlayContainer.js +101 -40
- package/dist/cli/ink-cli/hooks/useAgentEvents.d.ts.map +1 -1
- package/dist/cli/ink-cli/hooks/useAgentEvents.js +15 -16
- package/dist/cli/ink-cli/hooks/useAnimationTick.d.ts +11 -0
- package/dist/cli/ink-cli/hooks/useAnimationTick.d.ts.map +1 -0
- package/dist/cli/ink-cli/hooks/useAnimationTick.js +54 -0
- package/dist/cli/ink-cli/hooks/useCLIState.d.ts.map +1 -1
- package/dist/cli/ink-cli/hooks/useCLIState.js +1 -0
- package/dist/cli/ink-cli/hooks/useTokenCounter.d.ts.map +1 -1
- package/dist/cli/ink-cli/hooks/useTokenCounter.js +7 -4
- package/dist/cli/ink-cli/services/CommandService.d.ts +1 -1
- package/dist/cli/ink-cli/services/CommandService.d.ts.map +1 -1
- package/dist/cli/ink-cli/services/CommandService.js +2 -2
- package/dist/cli/ink-cli/services/processStream.d.ts +2 -2
- package/dist/cli/ink-cli/services/processStream.d.ts.map +1 -1
- package/dist/cli/ink-cli/services/processStream.js +27 -19
- package/dist/cli/ink-cli/state/initialState.d.ts.map +1 -1
- package/dist/cli/ink-cli/state/initialState.js +1 -0
- package/dist/cli/ink-cli/state/types.d.ts +15 -3
- package/dist/cli/ink-cli/state/types.d.ts.map +1 -1
- package/dist/cli/ink-cli/utils/commandOverlays.d.ts.map +1 -1
- package/dist/cli/ink-cli/utils/commandOverlays.js +1 -0
- package/dist/cli/ink-cli/utils/elicitationSchema.d.ts +11 -0
- package/dist/cli/ink-cli/utils/elicitationSchema.d.ts.map +1 -0
- package/dist/cli/ink-cli/utils/elicitationSchema.js +80 -0
- package/dist/cli/ink-cli/utils/index.d.ts +1 -1
- package/dist/cli/ink-cli/utils/index.d.ts.map +1 -1
- package/dist/cli/ink-cli/utils/index.js +1 -1
- package/dist/cli/ink-cli/utils/messageFormatting.d.ts +10 -19
- package/dist/cli/ink-cli/utils/messageFormatting.d.ts.map +1 -1
- package/dist/cli/ink-cli/utils/messageFormatting.js +43 -262
- package/dist/cli/ink-cli/utils/overlayPresentation.d.ts +19 -0
- package/dist/cli/ink-cli/utils/overlayPresentation.d.ts.map +1 -0
- package/dist/cli/ink-cli/utils/overlayPresentation.js +33 -0
- package/dist/cli/ink-cli/utils/overlaySizing.d.ts +19 -0
- package/dist/cli/ink-cli/utils/overlaySizing.d.ts.map +1 -0
- package/dist/cli/ink-cli/utils/overlaySizing.js +11 -0
- package/dist/cli/ink-cli/utils/soundNotification.d.ts +19 -13
- package/dist/cli/ink-cli/utils/soundNotification.d.ts.map +1 -1
- package/dist/cli/ink-cli/utils/soundNotification.js +120 -97
- package/dist/cli/ink-cli/utils/toolUtils.d.ts.map +1 -1
- package/dist/cli/ink-cli/utils/toolUtils.js +2 -9
- package/dist/cli/utils/config-validation.d.ts +11 -11
- package/dist/cli/utils/config-validation.d.ts.map +1 -1
- package/dist/cli/utils/config-validation.js +56 -290
- package/dist/cli/utils/image-store.d.ts +16 -0
- package/dist/cli/utils/image-store.d.ts.map +1 -0
- package/dist/cli/utils/image-store.js +289 -0
- package/dist/cli/utils/scaffolding-utils.d.ts +5 -0
- package/dist/cli/utils/scaffolding-utils.d.ts.map +1 -1
- package/dist/cli/utils/scaffolding-utils.js +46 -4
- package/dist/cli/utils/template-engine.d.ts +28 -16
- package/dist/cli/utils/template-engine.d.ts.map +1 -1
- package/dist/cli/utils/template-engine.js +339 -479
- package/dist/config/cli-overrides.d.ts +4 -3
- package/dist/config/cli-overrides.d.ts.map +1 -1
- package/dist/config/cli-overrides.js +7 -9
- package/dist/index-main.d.ts +2 -0
- package/dist/index-main.d.ts.map +1 -0
- package/dist/index-main.js +1554 -0
- package/dist/index.js +2 -1589
- package/dist/utils/session-logger-factory.d.ts +3 -0
- package/dist/utils/session-logger-factory.d.ts.map +1 -0
- package/dist/utils/session-logger-factory.js +34 -0
- package/dist/webui/assets/{index-Cz2z7NQ8.js → index-CKhumsZA.js} +231 -231
- package/dist/webui/index.html +1 -1
- package/package.json +11 -8
- package/dist/cli/cli-subscriber.d.ts +0 -45
- package/dist/cli/cli-subscriber.d.ts.map +0 -1
- package/dist/cli/cli-subscriber.js +0 -204
|
@@ -2,135 +2,86 @@
|
|
|
2
2
|
* Template Engine for Dexto Project Scaffolding
|
|
3
3
|
*
|
|
4
4
|
* Provides code generation functions for various project types.
|
|
5
|
-
*
|
|
6
|
-
* -
|
|
7
|
-
*
|
|
5
|
+
*
|
|
6
|
+
* Note: create-app/init-app scaffolds are programmatic (no YAML/images).
|
|
7
|
+
* Image scaffolds are generated via `dexto create-image`.
|
|
8
8
|
*/
|
|
9
9
|
/**
|
|
10
|
-
* Generates src/index.ts for an app using
|
|
10
|
+
* Generates src/index.ts for an app using programmatic configuration.
|
|
11
11
|
*/
|
|
12
|
-
export function
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
import { DextoAgent } from '@dexto/core';
|
|
19
|
-
import {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
// Create agent - providers already registered by image environment
|
|
28
|
-
const agent = new DextoAgent(config, './agents/default.yml');
|
|
29
|
-
|
|
30
|
-
await agent.start();
|
|
31
|
-
console.log('✅ Agent started\\n');
|
|
32
|
-
|
|
33
|
-
// Create a session
|
|
34
|
-
const session = await agent.createSession();
|
|
35
|
-
|
|
36
|
-
// Example interaction
|
|
37
|
-
const response = await agent.run(
|
|
38
|
-
'Hello! What can you help me with?',
|
|
39
|
-
undefined, // imageDataInput
|
|
40
|
-
undefined, // fileDataInput
|
|
41
|
-
session.id // sessionId
|
|
42
|
-
);
|
|
43
|
-
|
|
44
|
-
console.log('Agent response:', response);
|
|
45
|
-
|
|
46
|
-
// Cleanup
|
|
47
|
-
await agent.stop();
|
|
48
|
-
}
|
|
12
|
+
export function generateIndexForCodeFirstDI(context) {
|
|
13
|
+
const defaultProvider = context.llmProvider ?? 'openai';
|
|
14
|
+
const defaultModel = context.llmModel ?? 'gpt-4o';
|
|
15
|
+
return `// Standalone Dexto app (programmatic)
|
|
16
|
+
import 'dotenv/config';
|
|
17
|
+
|
|
18
|
+
import { DextoAgent, createLogger } from '@dexto/core';
|
|
19
|
+
import { MemoryBlobStore, MemoryCacheStore, MemoryDatabaseStore } from '@dexto/storage';
|
|
20
|
+
|
|
21
|
+
const agentId = '${context.projectName}';
|
|
22
|
+
const logger = createLogger({
|
|
23
|
+
agentId,
|
|
24
|
+
config: { level: 'info', transports: [{ type: 'console', colorize: true }] },
|
|
25
|
+
});
|
|
49
26
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
27
|
+
const agent = new DextoAgent({
|
|
28
|
+
agentId,
|
|
29
|
+
llm: { provider: '${defaultProvider}', model: '${defaultModel}' },
|
|
30
|
+
systemPrompt: 'You are a helpful AI assistant.',
|
|
31
|
+
logger,
|
|
32
|
+
storage: {
|
|
33
|
+
cache: new MemoryCacheStore(),
|
|
34
|
+
database: new MemoryDatabaseStore(),
|
|
35
|
+
blob: new MemoryBlobStore({}, logger),
|
|
36
|
+
},
|
|
53
37
|
});
|
|
38
|
+
|
|
39
|
+
await agent.start();
|
|
40
|
+
const session = await agent.createSession();
|
|
41
|
+
console.log((await agent.generate('Hello! What can you do?', session.id)).content);
|
|
42
|
+
await agent.stop();
|
|
54
43
|
`;
|
|
55
44
|
}
|
|
56
45
|
/**
|
|
57
|
-
* Generates src/index.ts for a web server application using
|
|
46
|
+
* Generates src/index.ts for a web server application using programmatic configuration.
|
|
58
47
|
*/
|
|
59
|
-
export function
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
import { DextoAgent } from '@dexto/core';
|
|
66
|
-
import {
|
|
48
|
+
export function generateWebServerIndexForCodeFirstDI(context) {
|
|
49
|
+
const defaultProvider = context.llmProvider ?? 'openai';
|
|
50
|
+
const defaultModel = context.llmModel ?? 'gpt-4o';
|
|
51
|
+
return `// Dexto Web Server (programmatic)
|
|
52
|
+
import 'dotenv/config';
|
|
53
|
+
|
|
54
|
+
import { DextoAgent, createLogger } from '@dexto/core';
|
|
55
|
+
import { MemoryBlobStore, MemoryCacheStore, MemoryDatabaseStore } from '@dexto/storage';
|
|
67
56
|
import { startDextoServer } from '@dexto/server';
|
|
68
57
|
import { resolve } from 'node:path';
|
|
69
|
-
import { existsSync } from 'node:fs';
|
|
70
58
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const config = await loadAgentConfig('./agents/default.yml');
|
|
77
|
-
console.log('✅ Config loaded\\n');
|
|
78
|
-
|
|
79
|
-
// Create agent
|
|
80
|
-
console.log('🤖 Creating agent...');
|
|
81
|
-
const agent = new DextoAgent(config, './agents/default.yml');
|
|
82
|
-
console.log('✅ Agent created\\n');
|
|
83
|
-
|
|
84
|
-
// Start the server
|
|
85
|
-
console.log('🌐 Starting Dexto server...');
|
|
86
|
-
|
|
87
|
-
const webRoot = resolve(process.cwd(), 'app');
|
|
88
|
-
|
|
89
|
-
if (!existsSync(webRoot)) {
|
|
90
|
-
console.error(\`❌ Error: Web root not found at \${webRoot}\`);
|
|
91
|
-
console.error(' Make sure the app/ directory exists');
|
|
92
|
-
process.exit(1);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
console.log(\`📁 Serving static files from: \${webRoot}\`);
|
|
59
|
+
const agentId = '${context.projectName}';
|
|
60
|
+
const logger = createLogger({
|
|
61
|
+
agentId,
|
|
62
|
+
config: { level: 'info', transports: [{ type: 'console', colorize: true }] },
|
|
63
|
+
});
|
|
96
64
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
console.log(' http://localhost:3000\\n');
|
|
109
|
-
console.log('📚 Available endpoints:');
|
|
110
|
-
console.log(' • Web UI: http://localhost:3000');
|
|
111
|
-
console.log(' • REST API: http://localhost:3000/api/*');
|
|
112
|
-
console.log(' • Health Check: http://localhost:3000/health');
|
|
113
|
-
console.log(' • OpenAPI Spec: http://localhost:3000/openapi.json');
|
|
114
|
-
console.log(' • Agent Card: http://localhost:3000/.well-known/agent-card.json\\n');
|
|
115
|
-
|
|
116
|
-
console.log('Press Ctrl+C to stop the server...\\n');
|
|
117
|
-
|
|
118
|
-
// Handle graceful shutdown
|
|
119
|
-
const shutdown = async () => {
|
|
120
|
-
console.log('\\n🛑 Shutting down...');
|
|
121
|
-
await stop();
|
|
122
|
-
console.log('✅ Server stopped\\n');
|
|
123
|
-
process.exit(0);
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
process.on('SIGINT', shutdown);
|
|
127
|
-
process.on('SIGTERM', shutdown);
|
|
128
|
-
}
|
|
65
|
+
const agent = new DextoAgent({
|
|
66
|
+
agentId,
|
|
67
|
+
llm: { provider: '${defaultProvider}', model: '${defaultModel}' },
|
|
68
|
+
systemPrompt: 'You are a helpful AI assistant.',
|
|
69
|
+
logger,
|
|
70
|
+
storage: {
|
|
71
|
+
cache: new MemoryCacheStore(),
|
|
72
|
+
database: new MemoryDatabaseStore(),
|
|
73
|
+
blob: new MemoryBlobStore({}, logger),
|
|
74
|
+
},
|
|
75
|
+
});
|
|
129
76
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
process.
|
|
77
|
+
const { stop } = await startDextoServer(agent, {
|
|
78
|
+
port: 3000,
|
|
79
|
+
webRoot: resolve(process.cwd(), 'app'),
|
|
80
|
+
agentCard: { name: '${context.projectName}', description: '${context.description}' },
|
|
133
81
|
});
|
|
82
|
+
|
|
83
|
+
process.on('SIGINT', () => void stop());
|
|
84
|
+
process.on('SIGTERM', () => void stop());
|
|
134
85
|
`;
|
|
135
86
|
}
|
|
136
87
|
/**
|
|
@@ -569,44 +520,8 @@ header h1 {
|
|
|
569
520
|
*/
|
|
570
521
|
export function generateDextoImageFile(context) {
|
|
571
522
|
const extendsField = context.baseImage ? ` extends: '${context.baseImage}',\n` : '';
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
export default defineImage({
|
|
575
|
-
name: '${context.imageName || context.projectName}',
|
|
576
|
-
version: '1.0.0',
|
|
577
|
-
description: '${context.description}',
|
|
578
|
-
target: '${context.target || 'local-development'}',
|
|
579
|
-
${extendsField}
|
|
580
|
-
// Providers are AUTO-DISCOVERED from convention-based folders:
|
|
581
|
-
// tools/ - Custom tool providers
|
|
582
|
-
// blob-store/ - Blob storage providers
|
|
583
|
-
// compression/ - Compression strategy providers
|
|
584
|
-
// plugins/ - Plugin providers
|
|
585
|
-
//
|
|
586
|
-
// Each provider must export from an index.ts file in its folder.
|
|
587
|
-
// The bundler will automatically register them when the image is imported.
|
|
588
|
-
|
|
589
|
-
providers: {
|
|
590
|
-
// Manual registration for built-in core providers
|
|
591
|
-
// (These come from core, not from our providers/ folder)
|
|
592
|
-
// TODO: This is a hack to get the local blob store provider to work. Should be auto-registered or dealt with in a better way.
|
|
593
|
-
blobStore: {
|
|
594
|
-
register: async () => {
|
|
595
|
-
const { localBlobStoreProvider, inMemoryBlobStoreProvider } = await import(
|
|
596
|
-
'@dexto/core'
|
|
597
|
-
);
|
|
598
|
-
const { blobStoreRegistry } = await import('@dexto/core');
|
|
599
|
-
|
|
600
|
-
blobStoreRegistry.register(localBlobStoreProvider);
|
|
601
|
-
blobStoreRegistry.register(inMemoryBlobStoreProvider);
|
|
602
|
-
|
|
603
|
-
console.log('✓ Registered core blob storage providers: local, in-memory');
|
|
604
|
-
},
|
|
605
|
-
},
|
|
606
|
-
},
|
|
607
|
-
|
|
608
|
-
defaults: {
|
|
609
|
-
storage: {
|
|
523
|
+
const storageDefaults = context.baseImage
|
|
524
|
+
? ` storage: {
|
|
610
525
|
blob: {
|
|
611
526
|
type: 'local',
|
|
612
527
|
storePath: './data/blobs',
|
|
@@ -618,83 +533,48 @@ ${extendsField}
|
|
|
618
533
|
cache: {
|
|
619
534
|
type: 'in-memory',
|
|
620
535
|
},
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
*/
|
|
635
|
-
export function generateDextoConfigFile(context) {
|
|
636
|
-
return `/**
|
|
637
|
-
* ${context.projectName} - Provider Registration
|
|
638
|
-
*
|
|
639
|
-
* This file registers all custom providers before agent initialization.
|
|
640
|
-
* This is the manual registration approach - for most use cases, consider
|
|
641
|
-
* using Dexto images instead (see: dexto create-image).
|
|
642
|
-
*/
|
|
643
|
-
|
|
644
|
-
import {
|
|
645
|
-
blobStoreRegistry,
|
|
646
|
-
customToolRegistry,
|
|
647
|
-
compactionRegistry,
|
|
648
|
-
pluginRegistry,
|
|
649
|
-
} from '@dexto/core';
|
|
536
|
+
},`
|
|
537
|
+
: ` storage: {
|
|
538
|
+
blob: {
|
|
539
|
+
type: 'example-blob',
|
|
540
|
+
},
|
|
541
|
+
database: {
|
|
542
|
+
type: 'example-database',
|
|
543
|
+
},
|
|
544
|
+
cache: {
|
|
545
|
+
type: 'example-cache',
|
|
546
|
+
},
|
|
547
|
+
},`;
|
|
548
|
+
return `import type { ImageDefinition } from '@dexto/image-bundler';
|
|
650
549
|
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
*/
|
|
654
|
-
export const projectConfig = {
|
|
655
|
-
name: '${context.projectName}',
|
|
550
|
+
const image = {
|
|
551
|
+
name: '${context.imageName || context.projectName}',
|
|
656
552
|
version: '1.0.0',
|
|
657
553
|
description: '${context.description}',
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
//
|
|
669
|
-
// import { myBlobProvider } from './storage/my-blob.js';
|
|
670
|
-
// blobStoreRegistry.register(myBlobProvider);
|
|
671
|
-
|
|
672
|
-
// Example: Register custom tool
|
|
673
|
-
// import { myToolProvider } from './tools/my-tool.js';
|
|
674
|
-
// customToolRegistry.register(myToolProvider);
|
|
675
|
-
|
|
676
|
-
// Example: Register plugin
|
|
677
|
-
// import { myPluginProvider } from './plugins/my-plugin.js';
|
|
678
|
-
// pluginRegistry.register(myPluginProvider);
|
|
554
|
+
target: '${context.target || 'local-development'}',
|
|
555
|
+
${extendsField}
|
|
556
|
+
// Factories are AUTO-DISCOVERED from convention-based folders:
|
|
557
|
+
// tools/<type>/index.ts
|
|
558
|
+
// storage/blob/<type>/index.ts
|
|
559
|
+
// storage/database/<type>/index.ts
|
|
560
|
+
// storage/cache/<type>/index.ts
|
|
561
|
+
// hooks/<type>/index.ts
|
|
562
|
+
// compaction/<type>/index.ts
|
|
563
|
+
//
|
|
564
|
+
// Each factory module must export a factory constant (export const factory = ...).
|
|
679
565
|
|
|
680
|
-
|
|
681
|
-
}
|
|
566
|
+
defaults: {
|
|
567
|
+
${storageDefaults}
|
|
568
|
+
logger: {
|
|
569
|
+
level: 'info',
|
|
570
|
+
transports: [{ type: 'console', colorize: true }],
|
|
571
|
+
},
|
|
572
|
+
},
|
|
682
573
|
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
* Use this for setting up monitoring, analytics, error tracking, etc.
|
|
686
|
-
*/
|
|
687
|
-
export async function initialize() {
|
|
688
|
-
console.log(\`✓ Initialized \${projectConfig.name} v\${projectConfig.version}\`);
|
|
689
|
-
}
|
|
574
|
+
constraints: ['filesystem-required', 'offline-capable'],
|
|
575
|
+
} satisfies ImageDefinition;
|
|
690
576
|
|
|
691
|
-
|
|
692
|
-
* Optional: Cleanup logic
|
|
693
|
-
* Called when the application shuts down
|
|
694
|
-
*/
|
|
695
|
-
export async function cleanup() {
|
|
696
|
-
console.log(\`✓ Cleaned up \${projectConfig.name}\`);
|
|
697
|
-
}
|
|
577
|
+
export default image;
|
|
698
578
|
`;
|
|
699
579
|
}
|
|
700
580
|
/**
|
|
@@ -703,7 +583,7 @@ export async function cleanup() {
|
|
|
703
583
|
export function generateImageReadme(context) {
|
|
704
584
|
const imageName = context.imageName || context.projectName;
|
|
705
585
|
const extendsNote = context.baseImage
|
|
706
|
-
? `\n\nThis image extends \`${context.baseImage}\`, inheriting its
|
|
586
|
+
? `\n\nThis image extends \`${context.baseImage}\`, inheriting its factories and adding custom ones.\n`
|
|
707
587
|
: '';
|
|
708
588
|
return `# ${imageName}
|
|
709
589
|
|
|
@@ -711,16 +591,14 @@ ${context.description}${extendsNote}
|
|
|
711
591
|
|
|
712
592
|
## What is this?
|
|
713
593
|
|
|
714
|
-
A **Dexto image**
|
|
715
|
-
|
|
594
|
+
A **Dexto image** is a distributable npm module that exports a typed \`DextoImage\` (a plain object)
|
|
595
|
+
describing tool/storage/hook/compaction factories + optional default config.
|
|
716
596
|
|
|
717
597
|
## What's Included
|
|
718
598
|
|
|
719
|
-
|
|
720
|
-
- ✅
|
|
721
|
-
- ✅
|
|
722
|
-
- ✅ Context management
|
|
723
|
-
- ✅ Default configurations
|
|
599
|
+
This package contains:
|
|
600
|
+
- ✅ Factories (auto-discovered from convention-based folders)
|
|
601
|
+
- ✅ Optional defaults (\`image.defaults\`) that merge into agent config (config wins)
|
|
724
602
|
|
|
725
603
|
## Quick Start
|
|
726
604
|
|
|
@@ -728,40 +606,33 @@ The harness provides:
|
|
|
728
606
|
# Build the image
|
|
729
607
|
pnpm run build
|
|
730
608
|
|
|
731
|
-
#
|
|
732
|
-
|
|
609
|
+
# Install into the Dexto CLI (local)
|
|
610
|
+
npm pack
|
|
611
|
+
dexto image install ./<generated-file>.tgz
|
|
733
612
|
\`\`\`
|
|
734
613
|
|
|
735
614
|
## Usage
|
|
736
615
|
|
|
737
|
-
|
|
738
|
-
import { createAgent } from '${imageName}';
|
|
739
|
-
import { loadAgentConfig } from '@dexto/agent-management';
|
|
740
|
-
|
|
741
|
-
const config = await loadAgentConfig('./agents/default.yml');
|
|
742
|
-
|
|
743
|
-
// Import creates the harness (providers auto-registered)
|
|
744
|
-
const agent = createAgent(config);
|
|
745
|
-
|
|
746
|
-
// The harness handles everything
|
|
747
|
-
await agent.start();
|
|
748
|
-
\`\`\`
|
|
616
|
+
Set \`image: '${imageName}'\` in your agent config (or pass \`--image\` in the CLI), then run Dexto.
|
|
749
617
|
|
|
750
|
-
## Adding
|
|
618
|
+
## Adding Factories
|
|
751
619
|
|
|
752
|
-
Add your custom
|
|
753
|
-
- \`tools
|
|
754
|
-
- \`blob
|
|
755
|
-
- \`
|
|
756
|
-
- \`
|
|
620
|
+
Add your custom factories to convention-based folders:
|
|
621
|
+
- \`tools/<type>/\` - Tool factories
|
|
622
|
+
- \`storage/blob/<type>/\` - Blob storage factories
|
|
623
|
+
- \`storage/database/<type>/\` - Database factories
|
|
624
|
+
- \`storage/cache/<type>/\` - Cache factories
|
|
625
|
+
- \`hooks/<type>/\` - Hook factories
|
|
626
|
+
- \`compaction/<type>/\` - Compaction factories
|
|
757
627
|
|
|
758
|
-
**Convention:** Each
|
|
628
|
+
**Convention:** Each factory lives in its own folder with an \`index.ts\` file.
|
|
629
|
+
Each \`index.ts\` must export a \`factory\` constant (e.g. \`export const factory = myToolFactory;\`).
|
|
759
630
|
|
|
760
631
|
Example:
|
|
761
632
|
\`\`\`
|
|
762
633
|
tools/
|
|
763
634
|
my-tool/
|
|
764
|
-
index.ts #
|
|
635
|
+
index.ts # Factory implementation (auto-discovered)
|
|
765
636
|
helpers.ts # Optional helper functions
|
|
766
637
|
types.ts # Optional type definitions
|
|
767
638
|
\`\`\`
|
|
@@ -772,20 +643,10 @@ tools/
|
|
|
772
643
|
pnpm run build
|
|
773
644
|
\`\`\`
|
|
774
645
|
|
|
775
|
-
This runs \`dexto-bundle build
|
|
776
|
-
1. Discovers
|
|
777
|
-
2.
|
|
778
|
-
3.
|
|
779
|
-
|
|
780
|
-
## Architecture
|
|
781
|
-
|
|
782
|
-
When imported, this image:
|
|
783
|
-
1. Auto-registers providers (side effect)
|
|
784
|
-
2. Exposes harness factory (\`createAgent\`)
|
|
785
|
-
3. Re-exports registries for runtime customization
|
|
786
|
-
|
|
787
|
-
The resulting harness manages your agent's runtime, including provider lifecycle,
|
|
788
|
-
context management, and tool orchestration.
|
|
646
|
+
This runs \`dexto-bundle build\`, which:
|
|
647
|
+
1. Discovers factories from convention-based folders
|
|
648
|
+
2. Compiles factory source files to \`dist/\`
|
|
649
|
+
3. Generates \`dist/index.js\` exporting a \`DextoImage\` (no side effects)
|
|
789
650
|
|
|
790
651
|
## Publishing
|
|
791
652
|
|
|
@@ -795,24 +656,19 @@ npm publish
|
|
|
795
656
|
|
|
796
657
|
Users can then:
|
|
797
658
|
\`\`\`bash
|
|
798
|
-
|
|
659
|
+
dexto image install ${imageName}
|
|
799
660
|
\`\`\`
|
|
800
|
-
|
|
801
|
-
## Learn More
|
|
802
|
-
|
|
803
|
-
- [Dexto Images Guide](https://docs.dexto.ai/docs/guides/images)
|
|
804
|
-
- [Provider Development](https://docs.dexto.ai/docs/guides/providers)
|
|
805
|
-
- [Bundler Documentation](https://docs.dexto.ai/docs/tools/bundler)
|
|
806
661
|
`;
|
|
807
662
|
}
|
|
808
663
|
/**
|
|
809
|
-
* Generates an example custom tool
|
|
664
|
+
* Generates an example custom tool factory
|
|
810
665
|
*/
|
|
811
666
|
export function generateExampleTool(toolName = 'example-tool') {
|
|
812
|
-
// Convert kebab-case to camelCase for
|
|
813
|
-
const
|
|
667
|
+
// Convert kebab-case to camelCase for a readable type name base
|
|
668
|
+
const typeNameBase = toolName.replace(/-([a-z])/g, (_, char) => char.toUpperCase());
|
|
814
669
|
return `import { z } from 'zod';
|
|
815
|
-
import type {
|
|
670
|
+
import type { ToolFactory } from '@dexto/agent-config';
|
|
671
|
+
import type { Tool, ToolExecutionContext } from '@dexto/core';
|
|
816
672
|
|
|
817
673
|
const ConfigSchema = z
|
|
818
674
|
.object({
|
|
@@ -821,32 +677,34 @@ const ConfigSchema = z
|
|
|
821
677
|
})
|
|
822
678
|
.strict();
|
|
823
679
|
|
|
824
|
-
type ${
|
|
680
|
+
type ${typeNameBase.charAt(0).toUpperCase() + typeNameBase.slice(1)}Config = z.output<typeof ConfigSchema>;
|
|
825
681
|
|
|
826
682
|
/**
|
|
827
|
-
* Example
|
|
683
|
+
* Example tool factory
|
|
828
684
|
*
|
|
829
|
-
* This demonstrates how to create a
|
|
830
|
-
* The
|
|
685
|
+
* This demonstrates how to create a tool factory that can be used by an image.
|
|
686
|
+
* The bundler auto-discovers this module when placed in tools/<type>/index.ts.
|
|
687
|
+
*
|
|
688
|
+
* Contract: export a factory constant with { configSchema, create }.
|
|
831
689
|
*/
|
|
832
|
-
export const
|
|
833
|
-
type: '${toolName}',
|
|
690
|
+
export const factory: ToolFactory<${typeNameBase.charAt(0).toUpperCase() + typeNameBase.slice(1)}Config> = {
|
|
834
691
|
configSchema: ConfigSchema,
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
692
|
+
metadata: {
|
|
693
|
+
displayName: 'Example Tool',
|
|
694
|
+
description: 'Example tool factory',
|
|
695
|
+
category: 'utilities',
|
|
696
|
+
},
|
|
697
|
+
create: (_config) => {
|
|
698
|
+
const tool: Tool = {
|
|
699
|
+
id: '${toolName}',
|
|
700
|
+
description: 'An example tool that demonstrates the tool factory pattern',
|
|
841
701
|
inputSchema: z.object({
|
|
842
702
|
input: z.string().describe('Input text to process'),
|
|
843
703
|
}),
|
|
844
|
-
|
|
845
|
-
execute: async (input: unknown) => {
|
|
704
|
+
execute: async (input: unknown, context: ToolExecutionContext) => {
|
|
846
705
|
const { input: inputText } = input as { input: string };
|
|
847
706
|
context.logger.info(\`Example tool called with: \${inputText}\`);
|
|
848
707
|
|
|
849
|
-
// Your tool logic here
|
|
850
708
|
return {
|
|
851
709
|
result: \`Processed: \${inputText}\`,
|
|
852
710
|
};
|
|
@@ -855,33 +713,196 @@ export const ${providerName}Provider: CustomToolProvider<'${toolName}', ${provid
|
|
|
855
713
|
|
|
856
714
|
return [tool];
|
|
857
715
|
},
|
|
716
|
+
};
|
|
717
|
+
`;
|
|
718
|
+
}
|
|
719
|
+
/**
|
|
720
|
+
* Generates an example custom hook factory
|
|
721
|
+
*/
|
|
722
|
+
export function generateExampleHook(hookName) {
|
|
723
|
+
return `import { z } from 'zod';
|
|
724
|
+
import type { HookFactory } from '@dexto/agent-config';
|
|
725
|
+
import type { Hook } from '@dexto/core';
|
|
858
726
|
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
727
|
+
const ConfigSchema = z
|
|
728
|
+
.object({
|
|
729
|
+
type: z.literal('${hookName}'),
|
|
730
|
+
})
|
|
731
|
+
.strict();
|
|
732
|
+
|
|
733
|
+
type ExampleHookConfig = z.output<typeof ConfigSchema>;
|
|
734
|
+
|
|
735
|
+
/**
|
|
736
|
+
* Example hook factory
|
|
737
|
+
*
|
|
738
|
+
* Hooks are resolved from image factories, same as tools.
|
|
739
|
+
* The bundler auto-discovers this module when placed in hooks/<type>/index.ts.
|
|
740
|
+
*/
|
|
741
|
+
export const factory: HookFactory<ExampleHookConfig> = {
|
|
742
|
+
configSchema: ConfigSchema,
|
|
743
|
+
create: (_config) => {
|
|
744
|
+
const hook: Hook = {
|
|
745
|
+
beforeLLMRequest: async (payload, context) => {
|
|
746
|
+
context.logger.info(\`${hookName} saw input: \${payload.text}\`);
|
|
747
|
+
return { ok: true };
|
|
748
|
+
},
|
|
749
|
+
};
|
|
750
|
+
|
|
751
|
+
return hook;
|
|
863
752
|
},
|
|
864
753
|
};
|
|
865
754
|
`;
|
|
866
755
|
}
|
|
867
756
|
/**
|
|
868
|
-
* Generates
|
|
757
|
+
* Generates an example custom compaction factory
|
|
869
758
|
*/
|
|
870
|
-
export function
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
759
|
+
export function generateExampleCompaction(compactionType) {
|
|
760
|
+
return `import { z } from 'zod';
|
|
761
|
+
import type { CompactionFactory } from '@dexto/agent-config';
|
|
762
|
+
import type { CompactionStrategy } from '@dexto/core';
|
|
763
|
+
|
|
764
|
+
const ConfigSchema = z
|
|
765
|
+
.object({
|
|
766
|
+
type: z.literal('${compactionType}'),
|
|
767
|
+
enabled: z.boolean().default(true).describe('Enable compaction strategy'),
|
|
768
|
+
maxContextTokens: z
|
|
769
|
+
.number()
|
|
770
|
+
.positive()
|
|
771
|
+
.optional()
|
|
772
|
+
.describe('Max tokens before compaction'),
|
|
773
|
+
thresholdPercent: z
|
|
774
|
+
.number()
|
|
775
|
+
.min(0.1)
|
|
776
|
+
.max(1.0)
|
|
777
|
+
.default(0.9)
|
|
778
|
+
.describe('Trigger threshold (0–1)'),
|
|
779
|
+
})
|
|
780
|
+
.strict();
|
|
781
|
+
|
|
782
|
+
type ExampleCompactionConfig = z.output<typeof ConfigSchema>;
|
|
783
|
+
|
|
784
|
+
/**
|
|
785
|
+
* Example compaction factory
|
|
786
|
+
*
|
|
787
|
+
* Compaction is a DI surface. Agents select exactly one strategy via \`compaction.type\`.
|
|
788
|
+
* The bundler auto-discovers this module when placed in compaction/<type>/index.ts.
|
|
789
|
+
*/
|
|
790
|
+
export const factory: CompactionFactory<ExampleCompactionConfig> = {
|
|
791
|
+
configSchema: ConfigSchema,
|
|
792
|
+
create: (config) => {
|
|
793
|
+
const strategy: CompactionStrategy = {
|
|
794
|
+
name: '${compactionType}',
|
|
795
|
+
getSettings: () => ({
|
|
796
|
+
enabled: config.enabled,
|
|
797
|
+
maxContextTokens: config.maxContextTokens,
|
|
798
|
+
thresholdPercent: config.thresholdPercent,
|
|
799
|
+
}),
|
|
800
|
+
getModelLimits: (modelContextWindow) => ({
|
|
801
|
+
contextWindow: config.maxContextTokens
|
|
802
|
+
? Math.min(modelContextWindow, config.maxContextTokens)
|
|
803
|
+
: modelContextWindow,
|
|
804
|
+
}),
|
|
805
|
+
shouldCompact: () => false,
|
|
806
|
+
compact: async () => [],
|
|
807
|
+
};
|
|
874
808
|
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
809
|
+
return strategy;
|
|
810
|
+
},
|
|
811
|
+
};
|
|
812
|
+
`;
|
|
813
|
+
}
|
|
814
|
+
/**
|
|
815
|
+
* Generates an example in-memory cache factory
|
|
816
|
+
*/
|
|
817
|
+
export function generateExampleCacheFactory(cacheType) {
|
|
818
|
+
return `import { z } from 'zod';
|
|
819
|
+
import type { CacheFactory } from '@dexto/agent-config';
|
|
820
|
+
import { MemoryCacheStore } from '@dexto/storage';
|
|
879
821
|
|
|
880
|
-
|
|
881
|
-
|
|
822
|
+
const ConfigSchema = z
|
|
823
|
+
.object({
|
|
824
|
+
type: z.literal('${cacheType}'),
|
|
825
|
+
})
|
|
826
|
+
.strict();
|
|
827
|
+
|
|
828
|
+
type ExampleCacheConfig = z.output<typeof ConfigSchema>;
|
|
829
|
+
|
|
830
|
+
/**
|
|
831
|
+
* Example cache factory
|
|
832
|
+
*
|
|
833
|
+
* Storage backends are resolved from image factories.
|
|
834
|
+
* The bundler auto-discovers this module when placed in storage/cache/<type>/index.ts.
|
|
835
|
+
*/
|
|
836
|
+
export const factory: CacheFactory<ExampleCacheConfig> = {
|
|
837
|
+
configSchema: ConfigSchema,
|
|
838
|
+
create: (_config, _logger) => new MemoryCacheStore(),
|
|
839
|
+
};
|
|
840
|
+
`;
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* Generates an example in-memory database factory
|
|
844
|
+
*/
|
|
845
|
+
export function generateExampleDatabaseFactory(databaseType) {
|
|
846
|
+
return `import { z } from 'zod';
|
|
847
|
+
import type { DatabaseFactory } from '@dexto/agent-config';
|
|
848
|
+
import { MemoryDatabaseStore } from '@dexto/storage';
|
|
849
|
+
|
|
850
|
+
const ConfigSchema = z
|
|
851
|
+
.object({
|
|
852
|
+
type: z.literal('${databaseType}'),
|
|
853
|
+
})
|
|
854
|
+
.strict();
|
|
855
|
+
|
|
856
|
+
type ExampleDatabaseConfig = z.output<typeof ConfigSchema>;
|
|
857
|
+
|
|
858
|
+
/**
|
|
859
|
+
* Example database factory
|
|
860
|
+
*
|
|
861
|
+
* Storage backends are resolved from image factories.
|
|
862
|
+
* The bundler auto-discovers this module when placed in storage/database/<type>/index.ts.
|
|
863
|
+
*/
|
|
864
|
+
export const factory: DatabaseFactory<ExampleDatabaseConfig> = {
|
|
865
|
+
configSchema: ConfigSchema,
|
|
866
|
+
create: (_config, _logger) => new MemoryDatabaseStore(),
|
|
867
|
+
};
|
|
868
|
+
`;
|
|
869
|
+
}
|
|
870
|
+
/**
|
|
871
|
+
* Generates an example in-memory blob store factory
|
|
872
|
+
*/
|
|
873
|
+
export function generateExampleBlobStoreFactory(blobType) {
|
|
874
|
+
return `import { z } from 'zod';
|
|
875
|
+
import type { BlobStoreFactory } from '@dexto/agent-config';
|
|
876
|
+
import { InMemoryBlobStoreSchema, MemoryBlobStore } from '@dexto/storage';
|
|
877
|
+
|
|
878
|
+
const ConfigSchema = InMemoryBlobStoreSchema.extend({
|
|
879
|
+
type: z.literal('${blobType}'),
|
|
880
|
+
}).strict();
|
|
881
|
+
|
|
882
|
+
type ExampleBlobStoreConfig = z.output<typeof ConfigSchema>;
|
|
883
|
+
|
|
884
|
+
/**
|
|
885
|
+
* Example blob store factory
|
|
886
|
+
*
|
|
887
|
+
* Blob stores are resolved from image factories.
|
|
888
|
+
* The bundler auto-discovers this module when placed in storage/blob/<type>/index.ts.
|
|
889
|
+
*/
|
|
890
|
+
export const factory: BlobStoreFactory<ExampleBlobStoreConfig> = {
|
|
891
|
+
configSchema: ConfigSchema,
|
|
892
|
+
create: (config, logger) => {
|
|
893
|
+
const { type: _type, ...options } = config;
|
|
894
|
+
return new MemoryBlobStore(options, logger);
|
|
895
|
+
},
|
|
896
|
+
};
|
|
897
|
+
`;
|
|
898
|
+
}
|
|
899
|
+
/**
|
|
900
|
+
* Generates README for an app project
|
|
901
|
+
*/
|
|
902
|
+
export function generateAppReadme(context) {
|
|
882
903
|
return `# ${context.projectName}
|
|
883
904
|
|
|
884
|
-
${context.description}
|
|
905
|
+
${context.description}
|
|
885
906
|
|
|
886
907
|
## Quick Start
|
|
887
908
|
|
|
@@ -903,8 +924,6 @@ pnpm start
|
|
|
903
924
|
${context.projectName}/
|
|
904
925
|
├── src/
|
|
905
926
|
│ └── index.ts # Entry point
|
|
906
|
-
├── agents/
|
|
907
|
-
│ └── default.yml # Agent configuration
|
|
908
927
|
├── .env # Environment variables (gitignored)
|
|
909
928
|
├── package.json
|
|
910
929
|
└── tsconfig.json
|
|
@@ -912,178 +931,19 @@ ${context.projectName}/
|
|
|
912
931
|
|
|
913
932
|
## Configuration
|
|
914
933
|
|
|
915
|
-
Edit \`
|
|
916
|
-
- System
|
|
917
|
-
- LLM provider
|
|
918
|
-
-
|
|
919
|
-
-
|
|
920
|
-
-
|
|
934
|
+
Edit \`src/index.ts\` to configure:
|
|
935
|
+
- System prompt
|
|
936
|
+
- LLM provider/model/API keys
|
|
937
|
+
- Storage backends
|
|
938
|
+
- Tools
|
|
939
|
+
- External tools via MCP (\`mcpServers\`)
|
|
940
|
+
|
|
941
|
+
By default this scaffold uses in-memory storage. To add persistence, swap in a file-backed
|
|
942
|
+
database and blob store (e.g. SQLite + local blobs).
|
|
921
943
|
|
|
922
944
|
## Learn More
|
|
923
945
|
|
|
924
946
|
- [Dexto Documentation](https://docs.dexto.ai)
|
|
925
947
|
- [Agent Configuration Guide](https://docs.dexto.ai/docs/guides/configuration)
|
|
926
|
-
- [Using Images](https://docs.dexto.ai/docs/guides/images)
|
|
927
|
-
`;
|
|
928
|
-
}
|
|
929
|
-
/**
|
|
930
|
-
* Generates auto-discovery script for from-core mode
|
|
931
|
-
*/
|
|
932
|
-
export function generateDiscoveryScript() {
|
|
933
|
-
return `#!/usr/bin/env tsx
|
|
934
|
-
/**
|
|
935
|
-
* Provider Auto-Discovery Script
|
|
936
|
-
*
|
|
937
|
-
* Scans conventional folders (tools/, blob-store/, compression/, plugins/)
|
|
938
|
-
* and generates src/providers.ts with import + registration statements.
|
|
939
|
-
*/
|
|
940
|
-
|
|
941
|
-
import * as fs from 'fs/promises';
|
|
942
|
-
import * as path from 'path';
|
|
943
|
-
import { fileURLToPath } from 'url';
|
|
944
|
-
|
|
945
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
946
|
-
const __dirname = path.dirname(__filename);
|
|
947
|
-
const projectRoot = path.resolve(__dirname, '..');
|
|
948
|
-
|
|
949
|
-
interface ProviderInfo {
|
|
950
|
-
category: 'customTools' | 'blobStore' | 'compression' | 'plugins';
|
|
951
|
-
folderName: string;
|
|
952
|
-
path: string;
|
|
953
|
-
registryName: string;
|
|
954
|
-
}
|
|
955
|
-
|
|
956
|
-
const PROVIDER_CATEGORIES = [
|
|
957
|
-
{ folder: 'tools', category: 'customTools' as const, registry: 'customToolRegistry' },
|
|
958
|
-
{ folder: 'blob-store', category: 'blobStore' as const, registry: 'blobStoreRegistry' },
|
|
959
|
-
{ folder: 'compaction', category: 'compaction' as const, registry: 'compactionRegistry' },
|
|
960
|
-
{ folder: 'plugins', category: 'plugins' as const, registry: 'pluginRegistry' },
|
|
961
|
-
];
|
|
962
|
-
|
|
963
|
-
async function discoverProviders(): Promise<ProviderInfo[]> {
|
|
964
|
-
const providers: ProviderInfo[] = [];
|
|
965
|
-
|
|
966
|
-
for (const { folder, category, registry } of PROVIDER_CATEGORIES) {
|
|
967
|
-
const folderPath = path.join(projectRoot, folder);
|
|
968
|
-
|
|
969
|
-
try {
|
|
970
|
-
const entries = await fs.readdir(folderPath, { withFileTypes: true });
|
|
971
|
-
|
|
972
|
-
for (const entry of entries) {
|
|
973
|
-
if (!entry.isDirectory()) continue;
|
|
974
|
-
if (entry.name.startsWith('.')) continue;
|
|
975
|
-
|
|
976
|
-
// Check if provider has index.ts
|
|
977
|
-
const indexPath = path.join(folderPath, entry.name, 'index.ts');
|
|
978
|
-
try {
|
|
979
|
-
await fs.access(indexPath);
|
|
980
|
-
providers.push({
|
|
981
|
-
category,
|
|
982
|
-
folderName: entry.name,
|
|
983
|
-
path: \`../\${folder}/\${entry.name}/index.js\`,
|
|
984
|
-
registryName: registry,
|
|
985
|
-
});
|
|
986
|
-
} catch {
|
|
987
|
-
// No index.ts found, skip
|
|
988
|
-
}
|
|
989
|
-
}
|
|
990
|
-
} catch {
|
|
991
|
-
// Folder doesn't exist or can't be read, skip
|
|
992
|
-
}
|
|
993
|
-
}
|
|
994
|
-
|
|
995
|
-
return providers;
|
|
996
|
-
}
|
|
997
|
-
|
|
998
|
-
function generateProvidersFile(providers: ProviderInfo[]): string {
|
|
999
|
-
// Helper to convert kebab-case to camelCase for valid JS identifiers
|
|
1000
|
-
const toCamelCase = (str: string): string => {
|
|
1001
|
-
return str.replace(/-([a-z])/g, (_, char) => char.toUpperCase());
|
|
1002
|
-
};
|
|
1003
|
-
|
|
1004
|
-
const imports: string[] = [];
|
|
1005
|
-
const registrations: string[] = [];
|
|
1006
|
-
const registries = new Set<string>();
|
|
1007
|
-
|
|
1008
|
-
providers.forEach((provider, index) => {
|
|
1009
|
-
const varName = \`provider\${index}\`;
|
|
1010
|
-
const providerName = \`\${toCamelCase(provider.folderName)}Provider\`;
|
|
1011
|
-
imports.push(\`import { \${providerName} as \${varName} } from '\${provider.path}';\`);
|
|
1012
|
-
registrations.push(\` \${provider.registryName}.register(\${varName});\`);
|
|
1013
|
-
registries.add(provider.registryName);
|
|
1014
|
-
});
|
|
1015
|
-
|
|
1016
|
-
const registryImports = Array.from(registries).join(', ');
|
|
1017
|
-
|
|
1018
|
-
return \`// AUTO-GENERATED - DO NOT EDIT
|
|
1019
|
-
// This file is generated by scripts/discover-providers.ts
|
|
1020
|
-
// Run 'pnpm run discover' to regenerate
|
|
1021
|
-
|
|
1022
|
-
import { \${registryImports} } from '@dexto/core';
|
|
1023
|
-
\${imports.join('\\n')}
|
|
1024
|
-
|
|
1025
|
-
/**
|
|
1026
|
-
* Register all discovered providers
|
|
1027
|
-
* Called automatically when this module is imported
|
|
1028
|
-
*/
|
|
1029
|
-
export function registerProviders(): void {
|
|
1030
|
-
\${registrations.join('\\n')}
|
|
1031
|
-
}
|
|
1032
|
-
|
|
1033
|
-
// Auto-register on import
|
|
1034
|
-
registerProviders();
|
|
1035
|
-
|
|
1036
|
-
console.log('✓ Registered \${providers.length} provider(s)');
|
|
1037
|
-
\`;
|
|
1038
|
-
}
|
|
1039
|
-
|
|
1040
|
-
function generateEntryPoint(): string {
|
|
1041
|
-
return \`// AUTO-GENERATED - DO NOT EDIT
|
|
1042
|
-
// This file is the build entry point that wires everything together
|
|
1043
|
-
// Run 'pnpm run discover' to regenerate
|
|
1044
|
-
|
|
1045
|
-
// Register providers first
|
|
1046
|
-
import './_providers.js';
|
|
1047
|
-
|
|
1048
|
-
// Then run the user's app
|
|
1049
|
-
import './index.js';
|
|
1050
|
-
\`;
|
|
1051
|
-
}
|
|
1052
|
-
|
|
1053
|
-
async function main() {
|
|
1054
|
-
console.log('🔍 Discovering providers...\\n');
|
|
1055
|
-
|
|
1056
|
-
const providers = await discoverProviders();
|
|
1057
|
-
|
|
1058
|
-
if (providers.length === 0) {
|
|
1059
|
-
console.log('⚠️ No providers found');
|
|
1060
|
-
console.log(' Add providers to: tools/, blob-store/, compression/, or plugins/\\n');
|
|
1061
|
-
} else {
|
|
1062
|
-
console.log(\`✅ Found \${providers.length} provider(s):\`);
|
|
1063
|
-
providers.forEach(p => {
|
|
1064
|
-
console.log(\` • \${p.category}/\${p.folderName}\`);
|
|
1065
|
-
});
|
|
1066
|
-
console.log();
|
|
1067
|
-
}
|
|
1068
|
-
|
|
1069
|
-
// Generate provider registrations
|
|
1070
|
-
const providersPath = path.join(projectRoot, 'src', '_providers.ts');
|
|
1071
|
-
const providersContent = generateProvidersFile(providers);
|
|
1072
|
-
await fs.writeFile(providersPath, providersContent, 'utf-8');
|
|
1073
|
-
console.log(\`📝 Generated: src/_providers.ts\`);
|
|
1074
|
-
|
|
1075
|
-
// Generate build entry point
|
|
1076
|
-
const entryPath = path.join(projectRoot, 'src', '_entry.ts');
|
|
1077
|
-
const entryContent = generateEntryPoint();
|
|
1078
|
-
await fs.writeFile(entryPath, entryContent, 'utf-8');
|
|
1079
|
-
console.log(\`📝 Generated: src/_entry.ts\`);
|
|
1080
|
-
|
|
1081
|
-
console.log();
|
|
1082
|
-
}
|
|
1083
|
-
|
|
1084
|
-
main().catch(error => {
|
|
1085
|
-
console.error('❌ Discovery failed:', error);
|
|
1086
|
-
process.exit(1);
|
|
1087
|
-
});
|
|
1088
948
|
`;
|
|
1089
949
|
}
|