dexto 1.1.10 → 1.2.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/README.md +222 -84
- package/dist/agents/agent-registry.json +39 -1
- package/dist/agents/agent-template.yml +1 -1
- package/dist/agents/coding-agent/README.md +188 -0
- package/dist/agents/coding-agent/coding-agent.yml +203 -0
- package/dist/agents/database-agent/database-agent.yml +44 -2
- package/dist/agents/default-agent.yml +137 -13
- package/dist/agents/github-agent/github-agent.yml +42 -0
- package/dist/agents/image-editor-agent/image-editor-agent.yml +9 -2
- package/dist/agents/music-agent/README.md +1 -1
- package/dist/agents/music-agent/music-agent.yml +36 -2
- package/dist/agents/nano-banana-agent/nano-banana-agent.yml +35 -1
- package/dist/agents/podcast-agent/README.md +1 -1
- package/dist/agents/podcast-agent/podcast-agent.yml +37 -3
- package/dist/agents/product-name-researcher/product-name-researcher.yml +37 -1
- package/dist/agents/sora-video-agent/README.md +122 -0
- package/dist/agents/sora-video-agent/sora-video-agent.yml +98 -0
- package/dist/agents/talk2pdf-agent/talk2pdf-agent.yml +17 -2
- package/dist/agents/triage-demo/README.md +6 -6
- package/dist/agents/triage-demo/billing-agent.yml +1 -1
- package/dist/agents/triage-demo/escalation-agent.yml +1 -1
- package/dist/agents/triage-demo/product-info-agent.yml +1 -1
- package/dist/agents/triage-demo/technical-support-agent.yml +1 -1
- package/dist/agents/triage-demo/triage-agent.yml +16 -1
- package/dist/analytics/wrapper.d.ts.map +1 -1
- package/dist/analytics/wrapper.js +5 -3
- package/dist/api/a2a.d.ts +2 -2
- package/dist/api/a2a.d.ts.map +1 -1
- package/dist/api/a2a.js +3 -2
- package/dist/api/mcp/mcp_handler.d.ts +3 -3
- package/dist/api/mcp/mcp_handler.d.ts.map +1 -1
- package/dist/api/mcp/mcp_handler.js +7 -4
- package/dist/api/mcp/tool-aggregation-handler.d.ts.map +1 -1
- package/dist/api/mcp/tool-aggregation-handler.js +34 -42
- package/dist/api/memory/memory-handler.d.ts +18 -0
- package/dist/api/memory/memory-handler.d.ts.map +1 -0
- package/dist/api/memory/memory-handler.js +137 -0
- package/dist/api/middleware/errorHandler.d.ts.map +1 -1
- package/dist/api/middleware/errorHandler.js +2 -0
- package/dist/api/server.d.ts +2 -2
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +1129 -257
- package/dist/api/webhook-subscriber.d.ts.map +1 -1
- package/dist/api/webhook-subscriber.js +2 -1
- package/dist/api/websocket-subscriber.d.ts.map +1 -1
- package/dist/api/websocket-subscriber.js +67 -10
- package/dist/cli/cli-subscriber.d.ts +2 -1
- package/dist/cli/cli-subscriber.d.ts.map +1 -1
- package/dist/cli/cli-subscriber.js +11 -3
- package/dist/cli/cli.d.ts.map +1 -1
- package/dist/cli/cli.js +1 -0
- package/dist/cli/commands/install.d.ts +3 -3
- package/dist/cli/commands/install.d.ts.map +1 -1
- package/dist/cli/commands/install.js +223 -41
- package/dist/cli/commands/interactive-commands/model/model-commands.js +2 -2
- package/dist/cli/commands/interactive-commands/prompt-commands.d.ts +8 -1
- package/dist/cli/commands/interactive-commands/prompt-commands.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/prompt-commands.js +252 -4
- package/dist/cli/commands/list-agents.d.ts.map +1 -1
- package/dist/cli/commands/list-agents.js +22 -3
- package/dist/cli/commands/setup.d.ts +4 -4
- package/dist/cli/commands/uninstall.d.ts +1 -1
- package/dist/cli/tool-confirmation/cli-confirmation-handler.d.ts +36 -7
- package/dist/cli/tool-confirmation/cli-confirmation-handler.d.ts.map +1 -1
- package/dist/cli/tool-confirmation/cli-confirmation-handler.js +314 -34
- package/dist/cli/utils/options.js +2 -2
- package/dist/index.js +117 -64
- package/dist/webui/.next/standalone/.next/static/chunks/419-6d449dcb2b056299.js +1 -0
- package/dist/webui/.next/standalone/.next/static/chunks/614-3519f8a6051e0088.js +1 -0
- package/dist/webui/.next/standalone/.next/static/chunks/656-5a9f6405badf66a8.js +25 -0
- package/dist/webui/.next/standalone/.next/static/chunks/765-755286dc586b1a51.js +1 -0
- package/dist/webui/.next/standalone/.next/static/chunks/804-f40df92a3adffcc0.js +1 -0
- package/dist/webui/.next/standalone/.next/static/chunks/854-232126f3c77e6c0b.js +1 -0
- package/dist/webui/.next/standalone/.next/static/chunks/app/chat/[sessionId]/page-a695b09e6bac5274.js +1 -0
- package/dist/webui/.next/standalone/.next/static/chunks/app/layout-f4a6ee5a028899d1.js +1 -0
- package/dist/webui/.next/standalone/.next/static/chunks/app/page-d1f127a0cac96246.js +1 -0
- package/dist/webui/.next/standalone/.next/static/chunks/app/playground/page-6f8d2abe76e51dfc.js +1 -0
- package/dist/webui/.next/standalone/.next/static/chunks/main-7decd42f62688419.js +1 -0
- package/dist/webui/.next/standalone/.next/static/chunks/{webpack-7c234e7e7e272295.js → webpack-7229fd0786f0483c.js} +1 -1
- package/dist/webui/.next/standalone/.next/static/css/c3c26ec984df1deb.css +1 -0
- package/dist/webui/.next/standalone/.next/static/css/de70bee13400563f.css +1 -0
- package/dist/webui/.next/standalone/.next/static/uqfH8SY_uhwdc0ZkpMwCO/_buildManifest.js +1 -0
- package/dist/webui/.next/standalone/package.json +7 -2
- package/dist/webui/.next/standalone/packages/webui/.next/BUILD_ID +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/app-build-manifest.json +30 -15
- package/dist/webui/.next/standalone/packages/webui/.next/app-path-routes-manifest.json +1 -0
- package/dist/webui/.next/standalone/packages/webui/.next/build-manifest.json +7 -7
- package/dist/webui/.next/standalone/packages/webui/.next/prerender-manifest.json +3 -3
- package/dist/webui/.next/standalone/packages/webui/.next/required-server-files.json +1 -11
- package/dist/webui/.next/standalone/packages/webui/.next/routes-manifest.json +11 -8
- package/dist/webui/.next/standalone/packages/webui/.next/server/app/_not-found/page.js +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/app/chat/[sessionId]/page.js +2 -0
- package/dist/webui/.next/standalone/packages/webui/.next/server/app/chat/[sessionId]/page.js.nft.json +1 -0
- package/dist/webui/.next/standalone/packages/webui/.next/server/app/chat/[sessionId]/page_client-reference-manifest.js +1 -0
- package/dist/webui/.next/standalone/packages/webui/.next/server/app/page.js +2 -11
- package/dist/webui/.next/standalone/packages/webui/.next/server/app/page.js.nft.json +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/app/playground/page.js +4 -8
- package/dist/webui/.next/standalone/packages/webui/.next/server/app/playground/page.js.nft.json +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/app/playground/page_client-reference-manifest.js +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/app-paths-manifest.json +1 -0
- package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/1.js +12 -0
- package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/102.js +25 -0
- package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/383.js +1 -0
- package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/{619.js → 426.js} +2 -2
- package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/43.js +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/985.js +5 -0
- package/dist/webui/.next/standalone/packages/webui/.next/server/middleware-build-manifest.js +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/pages/500.html +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/server-reference-manifest.json +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/419-6d449dcb2b056299.js +1 -0
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/614-3519f8a6051e0088.js +1 -0
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/656-5a9f6405badf66a8.js +25 -0
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/765-755286dc586b1a51.js +1 -0
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/804-f40df92a3adffcc0.js +1 -0
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/854-232126f3c77e6c0b.js +1 -0
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/app/chat/[sessionId]/page-a695b09e6bac5274.js +1 -0
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/app/layout-f4a6ee5a028899d1.js +1 -0
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/app/page-d1f127a0cac96246.js +1 -0
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/app/playground/page-6f8d2abe76e51dfc.js +1 -0
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/main-7decd42f62688419.js +1 -0
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/{webpack-7c234e7e7e272295.js → webpack-7229fd0786f0483c.js} +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/static/css/c3c26ec984df1deb.css +1 -0
- package/dist/webui/.next/standalone/packages/webui/.next/static/css/de70bee13400563f.css +1 -0
- package/dist/webui/.next/standalone/packages/webui/.next/static/uqfH8SY_uhwdc0ZkpMwCO/_buildManifest.js +1 -0
- package/dist/webui/.next/standalone/packages/webui/package.json +11 -4
- package/dist/webui/.next/standalone/packages/webui/server.js +1 -1
- package/dist/webui/.next/static/chunks/419-6d449dcb2b056299.js +1 -0
- package/dist/webui/.next/static/chunks/614-3519f8a6051e0088.js +1 -0
- package/dist/webui/.next/static/chunks/656-5a9f6405badf66a8.js +25 -0
- package/dist/webui/.next/static/chunks/765-755286dc586b1a51.js +1 -0
- package/dist/webui/.next/static/chunks/804-f40df92a3adffcc0.js +1 -0
- package/dist/webui/.next/static/chunks/854-232126f3c77e6c0b.js +1 -0
- package/dist/webui/.next/static/chunks/app/chat/[sessionId]/page-a695b09e6bac5274.js +1 -0
- package/dist/webui/.next/static/chunks/app/layout-f4a6ee5a028899d1.js +1 -0
- package/dist/webui/.next/static/chunks/app/page-d1f127a0cac96246.js +1 -0
- package/dist/webui/.next/static/chunks/app/playground/page-6f8d2abe76e51dfc.js +1 -0
- package/dist/webui/.next/static/chunks/main-7decd42f62688419.js +1 -0
- package/dist/webui/.next/static/chunks/{webpack-7c234e7e7e272295.js → webpack-7229fd0786f0483c.js} +1 -1
- package/dist/webui/.next/static/css/c3c26ec984df1deb.css +1 -0
- package/dist/webui/.next/static/css/de70bee13400563f.css +1 -0
- package/dist/webui/.next/static/uqfH8SY_uhwdc0ZkpMwCO/_buildManifest.js +1 -0
- package/dist/webui/package.json +11 -4
- package/package.json +5 -4
- package/dist/webui/.next/standalone/.next/static/PvkEd_BO6ZXxX99T_gUvs/_buildManifest.js +0 -1
- package/dist/webui/.next/standalone/.next/static/chunks/179-78abc2eacbc41da9.js +0 -1
- package/dist/webui/.next/standalone/.next/static/chunks/442-b1916bec348454b3.js +0 -1
- package/dist/webui/.next/standalone/.next/static/chunks/544-c4a8f278ed1a25d7.js +0 -1
- package/dist/webui/.next/standalone/.next/static/chunks/854-2a6d5a5297a15d52.js +0 -1
- package/dist/webui/.next/standalone/.next/static/chunks/app/layout-dde711766eda096b.js +0 -1
- package/dist/webui/.next/standalone/.next/static/chunks/app/page-5e94d5a49dc718d0.js +0 -1
- package/dist/webui/.next/standalone/.next/static/chunks/app/playground/page-9ae40e0b219583e3.js +0 -1
- package/dist/webui/.next/standalone/.next/static/chunks/main-b65ece3506a2355c.js +0 -1
- package/dist/webui/.next/standalone/.next/static/css/045cc65741e38fbd.css +0 -3
- package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/549.js +0 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/950.js +0 -5
- package/dist/webui/.next/standalone/packages/webui/.next/static/PvkEd_BO6ZXxX99T_gUvs/_buildManifest.js +0 -1
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/179-78abc2eacbc41da9.js +0 -1
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/442-b1916bec348454b3.js +0 -1
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/544-c4a8f278ed1a25d7.js +0 -1
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/854-2a6d5a5297a15d52.js +0 -1
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/app/layout-dde711766eda096b.js +0 -1
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/app/page-5e94d5a49dc718d0.js +0 -1
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/app/playground/page-9ae40e0b219583e3.js +0 -1
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/main-b65ece3506a2355c.js +0 -1
- package/dist/webui/.next/standalone/packages/webui/.next/static/css/045cc65741e38fbd.css +0 -3
- package/dist/webui/.next/static/PvkEd_BO6ZXxX99T_gUvs/_buildManifest.js +0 -1
- package/dist/webui/.next/static/chunks/179-78abc2eacbc41da9.js +0 -1
- package/dist/webui/.next/static/chunks/442-b1916bec348454b3.js +0 -1
- package/dist/webui/.next/static/chunks/544-c4a8f278ed1a25d7.js +0 -1
- package/dist/webui/.next/static/chunks/854-2a6d5a5297a15d52.js +0 -1
- package/dist/webui/.next/static/chunks/app/layout-dde711766eda096b.js +0 -1
- package/dist/webui/.next/static/chunks/app/page-5e94d5a49dc718d0.js +0 -1
- package/dist/webui/.next/static/chunks/app/playground/page-9ae40e0b219583e3.js +0 -1
- package/dist/webui/.next/static/chunks/main-b65ece3506a2355c.js +0 -1
- package/dist/webui/.next/static/css/045cc65741e38fbd.css +0 -3
- /package/dist/webui/.next/standalone/.next/static/{PvkEd_BO6ZXxX99T_gUvs → uqfH8SY_uhwdc0ZkpMwCO}/_ssgManifest.js +0 -0
- /package/dist/webui/.next/standalone/packages/webui/.next/static/{PvkEd_BO6ZXxX99T_gUvs → uqfH8SY_uhwdc0ZkpMwCO}/_ssgManifest.js +0 -0
- /package/dist/webui/.next/static/{PvkEd_BO6ZXxX99T_gUvs → uqfH8SY_uhwdc0ZkpMwCO}/_ssgManifest.js +0 -0
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import { applyLayeredEnvironmentLoading } from '@dexto/core';
|
|
|
5
5
|
await applyLayeredEnvironmentLoading();
|
|
6
6
|
import { existsSync } from 'fs';
|
|
7
7
|
import { createRequire } from 'module';
|
|
8
|
+
import path from 'path';
|
|
8
9
|
import { Command } from 'commander';
|
|
9
10
|
import * as p from '@clack/prompts';
|
|
10
11
|
import chalk from 'chalk';
|
|
@@ -13,8 +14,8 @@ import { withAnalytics, safeExit, ExitSignal } from './analytics/wrapper.js';
|
|
|
13
14
|
// Use createRequire to import package.json without experimental warning
|
|
14
15
|
const require = createRequire(import.meta.url);
|
|
15
16
|
const pkg = require('../package.json');
|
|
16
|
-
import { logger, getProviderFromModel, getAllSupportedModels, DextoAgent, loadAgentConfig, } from '@dexto/core';
|
|
17
|
-
import { resolveAgentPath, getAgentRegistry, isPath, resolveApiKeyForProvider } from '@dexto/core';
|
|
17
|
+
import { logger, getProviderFromModel, getAllSupportedModels, DextoAgent, loadAgentConfig, globalPreferencesExist, loadGlobalPreferences, } from '@dexto/core';
|
|
18
|
+
import { resolveAgentPath, getAgentRegistry, isPath, resolveApiKeyForProvider, getPrimaryApiKeyEnvVar, } from '@dexto/core';
|
|
18
19
|
import { startAiCli, startHeadlessCli, loadMostRecentSession } from './cli/cli.js';
|
|
19
20
|
import { startApiServer } from './api/server.js';
|
|
20
21
|
import { startDiscordBot } from './discord/bot.js';
|
|
@@ -40,7 +41,7 @@ program
|
|
|
40
41
|
.name('dexto')
|
|
41
42
|
.description('AI-powered CLI and WebUI for interacting with MCP servers')
|
|
42
43
|
.version(pkg.version, '-v, --version', 'output the current version')
|
|
43
|
-
.option('-a, --agent <
|
|
44
|
+
.option('-a, --agent <id|path>', 'Agent ID or path to agent config file')
|
|
44
45
|
.option('-p, --prompt <text>', 'Run prompt and exit. Alternatively provide a single quoted string as positional argument.')
|
|
45
46
|
.option('-s, --strict', 'Require all server connections to succeed')
|
|
46
47
|
.option('--no-verbose', 'Disable verbose output')
|
|
@@ -51,8 +52,9 @@ program
|
|
|
51
52
|
.option('--auto-approve', 'Always approve tool executions without confirmation prompts')
|
|
52
53
|
.option('-c, --continue', 'Continue most recent conversation')
|
|
53
54
|
.option('-r, --resume <sessionId>', 'Resume session by ID')
|
|
54
|
-
.option('--mode <mode>', 'The application in which dexto should talk to you -
|
|
55
|
-
.option('--web-port <port>', '
|
|
55
|
+
.option('--mode <mode>', 'The application in which dexto should talk to you - web | cli | server | discord | telegram | mcp', 'web')
|
|
56
|
+
.option('--web-port <port>', 'port for the web UI (default: 3000)', '3000')
|
|
57
|
+
.option('--api-port <port>', 'port for the API server (default: web-port + 1)')
|
|
56
58
|
.option('--no-auto-install', 'Disable automatic installation of missing agents from registry')
|
|
57
59
|
.enablePositionalOptions();
|
|
58
60
|
// 2) `create-app` SUB-COMMAND
|
|
@@ -156,10 +158,17 @@ program
|
|
|
156
158
|
// 5) `install` SUB-COMMAND
|
|
157
159
|
program
|
|
158
160
|
.command('install [agents...]')
|
|
159
|
-
.description('Install agents from
|
|
161
|
+
.description('Install agents from registry or custom YAML files/directories')
|
|
160
162
|
.option('--all', 'Install all available agents from registry')
|
|
161
163
|
.option('--no-inject-preferences', 'Skip injecting global preferences into installed agents')
|
|
162
164
|
.option('--force', 'Force reinstall even if agent is already installed')
|
|
165
|
+
.addHelpText('after', `
|
|
166
|
+
Examples:
|
|
167
|
+
$ dexto install default-agent Install agent from registry
|
|
168
|
+
$ dexto install agent1 agent2 Install multiple registry agents
|
|
169
|
+
$ dexto install --all Install all available registry agents
|
|
170
|
+
$ dexto install ./my-agent.yml Install custom agent from YAML file
|
|
171
|
+
$ dexto install ./my-agent-dir/ Install custom agent from directory (interactive)`)
|
|
163
172
|
.action(withAnalytics('install', async (agents = [], options) => {
|
|
164
173
|
try {
|
|
165
174
|
await handleInstallCommand(agents, options);
|
|
@@ -231,7 +240,7 @@ async function bootstrapAgentFromGlobalOpts() {
|
|
|
231
240
|
const resolvedPath = await resolveAgentPath(globalOpts.agent, globalOpts.autoInstall !== false, true);
|
|
232
241
|
const rawConfig = await loadAgentConfig(resolvedPath);
|
|
233
242
|
const mergedConfig = applyCLIOverrides(rawConfig, globalOpts);
|
|
234
|
-
const agent = new DextoAgent(mergedConfig,
|
|
243
|
+
const agent = new DextoAgent(mergedConfig, resolvedPath);
|
|
235
244
|
await agent.start();
|
|
236
245
|
// Register graceful shutdown
|
|
237
246
|
const shutdown = async () => {
|
|
@@ -402,31 +411,55 @@ program
|
|
|
402
411
|
// Main customer facing description
|
|
403
412
|
.description('Dexto CLI - AI-powered assistant with session management\n\n' +
|
|
404
413
|
'Basic Usage:\n' +
|
|
405
|
-
' dexto Start
|
|
406
|
-
' dexto "query"
|
|
407
|
-
' dexto -p "query" Run query, then exit\n' +
|
|
414
|
+
' dexto Start web UI (default)\n' +
|
|
415
|
+
' dexto "query" Run one-shot query (auto-uses CLI mode)\n' +
|
|
416
|
+
' dexto -p "query" Run one-shot query, then exit\n' +
|
|
408
417
|
' cat file | dexto -p "query" Process piped content\n\n' +
|
|
418
|
+
'CLI Mode:\n' +
|
|
419
|
+
' dexto --mode cli Start interactive CLI REPL\n\n' +
|
|
409
420
|
'Session Management:\n' +
|
|
410
421
|
' dexto -c Continue most recent conversation\n' +
|
|
411
|
-
' dexto -c -p "query" Continue
|
|
412
|
-
' dexto -r "<session-id>" "query" Resume
|
|
422
|
+
' dexto -c -p "query" Continue with one-shot query, then exit\n' +
|
|
423
|
+
' dexto -r "<session-id>" "query" Resume with one-shot query\n\n' +
|
|
413
424
|
'Tool Confirmation:\n' +
|
|
414
425
|
' dexto --auto-approve Auto-approve all tool executions\n\n' +
|
|
426
|
+
'Agent Selection:\n' +
|
|
427
|
+
' dexto --agent coding-agent Use installed agent by name\n' +
|
|
428
|
+
' dexto --agent ./my-agent.yml Use agent from file path\n' +
|
|
429
|
+
' dexto -a agents/custom.yml Short form with relative path\n\n' +
|
|
415
430
|
'Advanced Modes:\n' +
|
|
416
|
-
' dexto --mode web Run web UI\n' +
|
|
417
431
|
' dexto --mode server Run as API server\n' +
|
|
418
432
|
' dexto --mode discord Run as Discord bot\n' +
|
|
419
433
|
' dexto --mode telegram Run as Telegram bot\n' +
|
|
420
434
|
' dexto --mode mcp Run as MCP server\n\n' +
|
|
421
435
|
'Session Commands: dexto session list|history|delete • search\n' +
|
|
422
436
|
'Search: dexto search <query> [--session <id>] [--role <role>]\n\n' +
|
|
423
|
-
'See https://
|
|
437
|
+
'See https://docs.dexto.ai for documentation and examples')
|
|
424
438
|
.action(withAnalytics('main', async (prompt = []) => {
|
|
425
439
|
// ——— ENV CHECK (optional) ———
|
|
426
440
|
if (!existsSync('.env')) {
|
|
427
441
|
logger.debug('WARNING: .env file not found; copy .env.example and set your API keys.');
|
|
428
442
|
}
|
|
429
443
|
const opts = program.opts();
|
|
444
|
+
// ——— LOAD DEFAULT MODE FROM PREFERENCES ———
|
|
445
|
+
// If --mode was not explicitly provided on CLI, use defaultMode from preferences
|
|
446
|
+
const modeSource = program.getOptionValueSource('mode');
|
|
447
|
+
const explicitModeProvided = modeSource === 'cli';
|
|
448
|
+
if (!explicitModeProvided) {
|
|
449
|
+
try {
|
|
450
|
+
if (globalPreferencesExist()) {
|
|
451
|
+
const preferences = await loadGlobalPreferences();
|
|
452
|
+
if (preferences.defaults?.defaultMode) {
|
|
453
|
+
opts.mode = preferences.defaults.defaultMode;
|
|
454
|
+
logger.debug(`Using default mode from preferences: ${opts.mode}`);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
catch (error) {
|
|
459
|
+
// Silently fall back to hardcoded default if preferences loading fails
|
|
460
|
+
logger.debug(`Failed to load default mode from preferences: ${error instanceof Error ? error.message : String(error)}`);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
430
463
|
let headlessInput = undefined;
|
|
431
464
|
// Prefer explicit -p/--prompt for headless one-shot
|
|
432
465
|
if (opts.prompt !== undefined && String(opts.prompt).trim() !== '') {
|
|
@@ -449,6 +482,13 @@ program
|
|
|
449
482
|
}
|
|
450
483
|
// Note: Agent selection must be passed via -a/--agent. We no longer interpret
|
|
451
484
|
// the first positional argument as an agent name to avoid ambiguity with prompts.
|
|
485
|
+
// ——— FORCE CLI MODE FOR HEADLESS PROMPTS ———
|
|
486
|
+
// If a prompt was provided via -p or positional args, force CLI mode
|
|
487
|
+
if (headlessInput && opts.mode !== 'cli') {
|
|
488
|
+
console.log(`ℹ️ Prompt detected via -p or positional argument. Forcing CLI mode for one-shot execution.`);
|
|
489
|
+
console.log(` Original mode: ${opts.mode} → Overridden to: cli`);
|
|
490
|
+
opts.mode = 'cli';
|
|
491
|
+
}
|
|
452
492
|
// ——— Infer provider & API key from model ———
|
|
453
493
|
if (opts.model) {
|
|
454
494
|
let provider;
|
|
@@ -462,7 +502,8 @@ program
|
|
|
462
502
|
}
|
|
463
503
|
const apiKey = resolveApiKeyForProvider(provider);
|
|
464
504
|
if (!apiKey) {
|
|
465
|
-
|
|
505
|
+
const envVar = getPrimaryApiKeyEnvVar(provider);
|
|
506
|
+
console.error(`❌ Missing API key for provider '${provider}' - please set $${envVar}`);
|
|
466
507
|
safeExit('main', 1, 'missing-api-key');
|
|
467
508
|
}
|
|
468
509
|
opts.provider = provider;
|
|
@@ -529,6 +570,7 @@ program
|
|
|
529
570
|
}
|
|
530
571
|
// ——— CREATE AGENT ———
|
|
531
572
|
let agent;
|
|
573
|
+
let derivedAgentId;
|
|
532
574
|
try {
|
|
533
575
|
console.log(`🚀 Initializing Dexto with config: ${resolvedPath}`);
|
|
534
576
|
// Set run mode for tool confirmation provider
|
|
@@ -541,51 +583,14 @@ program
|
|
|
541
583
|
}
|
|
542
584
|
}
|
|
543
585
|
// DextoAgent will parse/validate again (parse-twice pattern)
|
|
544
|
-
agent = new DextoAgent(validatedConfig,
|
|
586
|
+
agent = new DextoAgent(validatedConfig, resolvedPath);
|
|
545
587
|
// Start the agent (initialize async services)
|
|
546
588
|
await agent.start();
|
|
547
|
-
//
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
logger.info(`Resumed session: ${opts.resume}`, null, 'cyan');
|
|
553
|
-
}
|
|
554
|
-
catch (err) {
|
|
555
|
-
console.error(`❌ Failed to resume session '${opts.resume}': ${err instanceof Error ? err.message : String(err)}`);
|
|
556
|
-
console.error('💡 Use `dexto session list` to see available sessions');
|
|
557
|
-
safeExit('main', 1, 'resume-failed');
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
else if (opts.continue) {
|
|
561
|
-
try {
|
|
562
|
-
// Continue from most recent session
|
|
563
|
-
await loadMostRecentSession(agent);
|
|
564
|
-
// If no sessions existed, create a new one to honor default-new invariant
|
|
565
|
-
const sessionsAfter = await agent.listSessions();
|
|
566
|
-
if (sessionsAfter.length === 0) {
|
|
567
|
-
const session = await agent.createSession();
|
|
568
|
-
await agent.loadSessionAsDefault(session.id);
|
|
569
|
-
logger.info(`Created new session: ${session.id}`, null, 'green');
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
catch (err) {
|
|
573
|
-
console.error(`❌ Failed to continue session: ${err instanceof Error ? err.message : String(err)}`);
|
|
574
|
-
safeExit('main', 1, 'continue-failed');
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
else {
|
|
578
|
-
// Default behavior: create new session
|
|
579
|
-
try {
|
|
580
|
-
const session = await agent.createSession();
|
|
581
|
-
await agent.loadSessionAsDefault(session.id);
|
|
582
|
-
logger.info(`Created new session: ${session.id}`, null, 'green');
|
|
583
|
-
}
|
|
584
|
-
catch (err) {
|
|
585
|
-
console.error(`❌ Failed to create new session: ${err instanceof Error ? err.message : String(err)}`);
|
|
586
|
-
safeExit('main', 1, 'create-session-failed');
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
+
// Derive a concise agent ID for display purposes (used by API/UI)
|
|
590
|
+
// Prefer agentCard.name, otherwise extract from filename
|
|
591
|
+
derivedAgentId =
|
|
592
|
+
validatedConfig.agentCard?.name ||
|
|
593
|
+
path.basename(resolvedPath, path.extname(resolvedPath));
|
|
589
594
|
}
|
|
590
595
|
catch (err) {
|
|
591
596
|
if (err instanceof ExitSignal)
|
|
@@ -597,6 +602,48 @@ program
|
|
|
597
602
|
// ——— Dispatch based on --mode ———
|
|
598
603
|
switch (opts.mode) {
|
|
599
604
|
case 'cli': {
|
|
605
|
+
// Handle session options - only for CLI mode
|
|
606
|
+
if (opts.resume) {
|
|
607
|
+
try {
|
|
608
|
+
// Resume specific session by ID
|
|
609
|
+
await agent.loadSessionAsDefault(opts.resume);
|
|
610
|
+
logger.info(`Resumed session: ${opts.resume}`, null, 'cyan');
|
|
611
|
+
}
|
|
612
|
+
catch (err) {
|
|
613
|
+
console.error(`❌ Failed to resume session '${opts.resume}': ${err instanceof Error ? err.message : String(err)}`);
|
|
614
|
+
console.error('💡 Use `dexto session list` to see available sessions');
|
|
615
|
+
safeExit('main', 1, 'resume-failed');
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
else if (opts.continue) {
|
|
619
|
+
try {
|
|
620
|
+
// Continue from most recent session
|
|
621
|
+
await loadMostRecentSession(agent);
|
|
622
|
+
// If no sessions existed, create a new one to honor default-new invariant
|
|
623
|
+
const sessionsAfter = await agent.listSessions();
|
|
624
|
+
if (sessionsAfter.length === 0) {
|
|
625
|
+
const session = await agent.createSession();
|
|
626
|
+
await agent.loadSessionAsDefault(session.id);
|
|
627
|
+
logger.info(`Created new session: ${session.id}`, null, 'green');
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
catch (err) {
|
|
631
|
+
console.error(`❌ Failed to continue session: ${err instanceof Error ? err.message : String(err)}`);
|
|
632
|
+
safeExit('main', 1, 'continue-failed');
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
else {
|
|
636
|
+
// Default behavior: create new session for CLI mode
|
|
637
|
+
try {
|
|
638
|
+
const session = await agent.createSession();
|
|
639
|
+
await agent.loadSessionAsDefault(session.id);
|
|
640
|
+
logger.info(`Created new session: ${session.id}`, null, 'green');
|
|
641
|
+
}
|
|
642
|
+
catch (err) {
|
|
643
|
+
console.error(`❌ Failed to create new session: ${err instanceof Error ? err.message : String(err)}`);
|
|
644
|
+
safeExit('main', 1, 'create-session-failed');
|
|
645
|
+
}
|
|
646
|
+
}
|
|
600
647
|
const toolConfirmationMode = agent.getEffectiveConfig().toolConfirmation?.mode ?? 'event-based';
|
|
601
648
|
if (toolConfirmationMode === 'event-based') {
|
|
602
649
|
// Set up CLI tool confirmation subscriber
|
|
@@ -621,11 +668,15 @@ program
|
|
|
621
668
|
case 'web': {
|
|
622
669
|
const webPort = parseInt(opts.webPort, 10);
|
|
623
670
|
const frontPort = getPort(process.env.FRONTEND_PORT, webPort, 'FRONTEND_PORT');
|
|
624
|
-
|
|
671
|
+
// Use explicit --api-port if provided, otherwise default to webPort + 1
|
|
672
|
+
const defaultApiPort = opts.apiPort
|
|
673
|
+
? parseInt(opts.apiPort, 10)
|
|
674
|
+
: webPort + 1;
|
|
675
|
+
const apiPort = getPort(process.env.API_PORT, defaultApiPort, 'API_PORT');
|
|
625
676
|
const apiUrl = process.env.API_URL ?? `http://localhost:${apiPort}`;
|
|
626
677
|
const nextJSserverURL = process.env.FRONTEND_URL ?? `http://localhost:${frontPort}`;
|
|
627
678
|
// Start API server
|
|
628
|
-
await startApiServer(agent, apiPort, agent.getEffectiveConfig().agentCard || {},
|
|
679
|
+
await startApiServer(agent, apiPort, agent.getEffectiveConfig().agentCard || {}, derivedAgentId);
|
|
629
680
|
// Start Next.js web server
|
|
630
681
|
const webServerStarted = await startNextJsWebServer(apiUrl, frontPort, nextJSserverURL);
|
|
631
682
|
// Open WebUI in browser if server started successfully
|
|
@@ -646,10 +697,12 @@ program
|
|
|
646
697
|
case 'server': {
|
|
647
698
|
// Start server with REST APIs and WebSockets only
|
|
648
699
|
const agentCard = agent.getEffectiveConfig().agentCard ?? {};
|
|
649
|
-
|
|
700
|
+
// Use explicit --api-port if provided, otherwise default to 3001
|
|
701
|
+
const defaultApiPort = opts.apiPort ? parseInt(opts.apiPort, 10) : 3001;
|
|
702
|
+
const apiPort = getPort(process.env.API_PORT, defaultApiPort, 'API_PORT');
|
|
650
703
|
const apiUrl = process.env.API_URL ?? `http://localhost:${apiPort}`;
|
|
651
704
|
console.log('🌐 Starting server (REST APIs + WebSockets)...');
|
|
652
|
-
await startApiServer(agent, apiPort, agentCard,
|
|
705
|
+
await startApiServer(agent, apiPort, agentCard, derivedAgentId);
|
|
653
706
|
console.log(`✅ Server running at ${apiUrl}`);
|
|
654
707
|
console.log('Available endpoints:');
|
|
655
708
|
console.log(' POST /api/message - Send async message');
|
|
@@ -699,7 +752,7 @@ program
|
|
|
699
752
|
);
|
|
700
753
|
// Use stdio transport in mcp mode
|
|
701
754
|
const mcpTransport = await createMcpTransport('stdio');
|
|
702
|
-
await initializeMcpServer(agent, agentCardData, mcpTransport);
|
|
755
|
+
await initializeMcpServer(() => agent, () => agentCardData, mcpTransport);
|
|
703
756
|
}
|
|
704
757
|
catch (err) {
|
|
705
758
|
// Write to stderr instead of stdout to avoid interfering with MCP protocol
|
|
@@ -709,7 +762,7 @@ program
|
|
|
709
762
|
break;
|
|
710
763
|
}
|
|
711
764
|
default:
|
|
712
|
-
console.error(`❌ Unknown mode '${opts.mode}'. Use
|
|
765
|
+
console.error(`❌ Unknown mode '${opts.mode}'. Use web, cli, server, discord, telegram, or mcp.`);
|
|
713
766
|
safeExit('main', 1, 'unknown-mode');
|
|
714
767
|
}
|
|
715
768
|
}, { timeoutMs: 0 }));
|