dexto 1.1.11 → 1.2.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 +222 -84
- package/dist/agents/agent-registry.json +9 -0
- 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 +41 -2
- package/dist/agents/default-agent.yml +37 -3
- package/dist/agents/github-agent/github-agent.yml +39 -0
- package/dist/agents/image-editor-agent/image-editor-agent.yml +6 -2
- package/dist/agents/music-agent/README.md +1 -1
- package/dist/agents/music-agent/music-agent.yml +33 -2
- package/dist/agents/nano-banana-agent/nano-banana-agent.yml +32 -1
- package/dist/agents/podcast-agent/README.md +1 -1
- package/dist/agents/podcast-agent/podcast-agent.yml +34 -3
- package/dist/agents/product-name-researcher/product-name-researcher.yml +34 -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 +14 -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 +13 -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/memory/memory-handler.d.ts +4 -1
- package/dist/api/memory/memory-handler.d.ts.map +1 -1
- package/dist/api/memory/memory-handler.js +10 -2
- package/dist/api/middleware/errorHandler.d.ts.map +1 -1
- package/dist/api/middleware/errorHandler.js +2 -0
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +158 -42
- package/dist/api/websocket-subscriber.d.ts.map +1 -1
- package/dist/api/websocket-subscriber.js +6 -0
- package/dist/cli/commands/interactive-commands/model/model-commands.js +2 -2
- package/dist/cli/utils/options.js +2 -2
- package/dist/index.js +64 -18
- package/dist/webui/.next/standalone/.next/static/b_pyEEg2sitTwMzZWW7vE/_buildManifest.js +1 -0
- package/dist/webui/.next/standalone/.next/static/chunks/419-a07413b585273a24.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/{711-76a7d2bf4d6f69e5.js → 765-755286dc586b1a51.js} +1 -1
- 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/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/css/c3c26ec984df1deb.css +1 -0
- package/dist/webui/.next/standalone/package.json +1 -0
- package/dist/webui/.next/standalone/packages/webui/.next/BUILD_ID +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/app-build-manifest.json +18 -18
- package/dist/webui/.next/standalone/packages/webui/.next/build-manifest.json +4 -4
- 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 +1 -7
- 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 +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/app/chat/[sessionId]/page.js.nft.json +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/app/chat/[sessionId]/page_client-reference-manifest.js +1 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/app/page.js +1 -1
- 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/chunks/1.js +5 -5
- 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/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/pages-manifest.json +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/b_pyEEg2sitTwMzZWW7vE/_buildManifest.js +1 -0
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/419-a07413b585273a24.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/{711-76a7d2bf4d6f69e5.js → 765-755286dc586b1a51.js} +1 -1
- 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/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/css/c3c26ec984df1deb.css +1 -0
- package/dist/webui/.next/standalone/packages/webui/package.json +5 -1
- package/dist/webui/.next/standalone/packages/webui/server.js +1 -1
- package/dist/webui/.next/static/b_pyEEg2sitTwMzZWW7vE/_buildManifest.js +1 -0
- package/dist/webui/.next/static/chunks/419-a07413b585273a24.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/{711-76a7d2bf4d6f69e5.js → 765-755286dc586b1a51.js} +1 -1
- 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/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/css/c3c26ec984df1deb.css +1 -0
- package/dist/webui/package.json +5 -1
- package/package.json +2 -2
- package/dist/webui/.next/standalone/.next/static/VoeDi3iuGmMdZu_kx-R2X/_buildManifest.js +0 -1
- package/dist/webui/.next/standalone/.next/static/chunks/419-5526a47c95a2fa60.js +0 -1
- package/dist/webui/.next/standalone/.next/static/chunks/429-838829c1391e496d.js +0 -25
- package/dist/webui/.next/standalone/.next/static/chunks/459-62011998b002cbf6.js +0 -1
- package/dist/webui/.next/standalone/.next/static/chunks/854-8cad9404fc78e0cc.js +0 -1
- package/dist/webui/.next/standalone/.next/static/chunks/935-07f9df196b13275e.js +0 -1
- package/dist/webui/.next/standalone/.next/static/chunks/app/chat/[sessionId]/page-b8acc47b0d8c5c0a.js +0 -1
- package/dist/webui/.next/standalone/.next/static/chunks/app/page-e117ae372850d25f.js +0 -1
- package/dist/webui/.next/standalone/.next/static/chunks/app/playground/page-09340fb6b3f4caa2.js +0 -1
- package/dist/webui/.next/standalone/.next/static/chunks/main-b65ece3506a2355c.js +0 -1
- package/dist/webui/.next/standalone/.next/static/css/21e6c142ca3cdc42.css +0 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/419.js +0 -25
- package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/654.js +0 -1
- package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/71.js +0 -5
- package/dist/webui/.next/standalone/packages/webui/.next/static/VoeDi3iuGmMdZu_kx-R2X/_buildManifest.js +0 -1
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/419-5526a47c95a2fa60.js +0 -1
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/429-838829c1391e496d.js +0 -25
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/459-62011998b002cbf6.js +0 -1
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/854-8cad9404fc78e0cc.js +0 -1
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/935-07f9df196b13275e.js +0 -1
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/app/chat/[sessionId]/page-b8acc47b0d8c5c0a.js +0 -1
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/app/page-e117ae372850d25f.js +0 -1
- package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/app/playground/page-09340fb6b3f4caa2.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/21e6c142ca3cdc42.css +0 -1
- package/dist/webui/.next/static/VoeDi3iuGmMdZu_kx-R2X/_buildManifest.js +0 -1
- package/dist/webui/.next/static/chunks/419-5526a47c95a2fa60.js +0 -1
- package/dist/webui/.next/static/chunks/429-838829c1391e496d.js +0 -25
- package/dist/webui/.next/static/chunks/459-62011998b002cbf6.js +0 -1
- package/dist/webui/.next/static/chunks/854-8cad9404fc78e0cc.js +0 -1
- package/dist/webui/.next/static/chunks/935-07f9df196b13275e.js +0 -1
- package/dist/webui/.next/static/chunks/app/chat/[sessionId]/page-b8acc47b0d8c5c0a.js +0 -1
- package/dist/webui/.next/static/chunks/app/page-e117ae372850d25f.js +0 -1
- package/dist/webui/.next/static/chunks/app/playground/page-09340fb6b3f4caa2.js +0 -1
- package/dist/webui/.next/static/chunks/main-b65ece3506a2355c.js +0 -1
- package/dist/webui/.next/static/css/21e6c142ca3cdc42.css +0 -1
- /package/dist/webui/.next/standalone/.next/static/{VoeDi3iuGmMdZu_kx-R2X → b_pyEEg2sitTwMzZWW7vE}/_ssgManifest.js +0 -0
- /package/dist/webui/.next/standalone/packages/webui/.next/static/{VoeDi3iuGmMdZu_kx-R2X → b_pyEEg2sitTwMzZWW7vE}/_ssgManifest.js +0 -0
- /package/dist/webui/.next/static/{VoeDi3iuGmMdZu_kx-R2X → b_pyEEg2sitTwMzZWW7vE}/_ssgManifest.js +0 -0
package/dist/api/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/api/server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAY,MAAM,SAAS,CAAC;AACjD,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAErC,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,EAAkD,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAS7F,OAAO,EAA0B,UAAU,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/api/server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAY,MAAM,SAAS,CAAC;AACjD,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAErC,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,EAAkD,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAS7F,OAAO,EAA0B,UAAU,EAAmB,MAAM,aAAa,CAAC;AA8DlF,wBAAsB,aAAa,CAC/B,KAAK,EAAE,UAAU,EACjB,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,EACtC,UAAU,CAAC,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC;IACP,GAAG,EAAE,OAAO,CAAC;IACb,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;IACpB,GAAG,EAAE,eAAe,CAAC;IACrB,aAAa,EAAE,wBAAwB,CAAC;IACxC,iBAAiB,EAAE,sBAAsB,CAAC;CAC7C,CAAC,CAmxED;AAED,wBAAsB,cAAc,CAChC,KAAK,EAAE,UAAU,EACjB,IAAI,SAAO,EACX,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,EACtC,OAAO,CAAC,EAAE,MAAM;;;;;GA6BnB"}
|
package/dist/api/server.js
CHANGED
|
@@ -7,7 +7,7 @@ import { logger, redactSensitiveData, deriveDisplayName } from '@dexto/core';
|
|
|
7
7
|
import { setupA2ARoutes } from './a2a.js';
|
|
8
8
|
import { setupMemoryRoutes } from './memory/memory-handler.js';
|
|
9
9
|
import { createMcpTransport, initializeMcpServer, initializeMcpServerApiEndpoints, } from './mcp/mcp_handler.js';
|
|
10
|
-
import { createAgentCard, Dexto,
|
|
10
|
+
import { createAgentCard, Dexto, DextoAgent, loadAgentConfig } from '@dexto/core';
|
|
11
11
|
import { stringify as yamlStringify, parse as yamlParse } from 'yaml';
|
|
12
12
|
import os from 'os';
|
|
13
13
|
import { promises as fs } from 'fs';
|
|
@@ -55,6 +55,42 @@ export async function initializeApi(agent, agentCardOverride, listenPort, agentI
|
|
|
55
55
|
let activeAgentId = agentId || 'default-agent';
|
|
56
56
|
let isSwitchingAgent = false;
|
|
57
57
|
registerGracefulShutdown(() => activeAgent);
|
|
58
|
+
// CORS middleware to allow frontend to connect from different ports
|
|
59
|
+
app.use((req, res, next) => {
|
|
60
|
+
const origin = req.headers.origin;
|
|
61
|
+
// Define allowed origins based on environment
|
|
62
|
+
const allowedOrigins = [];
|
|
63
|
+
// 1. Always allow localhost/127.0.0.1 on any port (for local development)
|
|
64
|
+
if (origin) {
|
|
65
|
+
const originUrl = new URL(origin);
|
|
66
|
+
const hostname = originUrl.hostname;
|
|
67
|
+
if (hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '::1') {
|
|
68
|
+
allowedOrigins.push(origin);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// 2. Allow custom origins from environment variable (for production/network deployments)
|
|
72
|
+
const customOrigins = process.env.DEXTO_ALLOWED_ORIGINS;
|
|
73
|
+
if (customOrigins) {
|
|
74
|
+
allowedOrigins.push(...customOrigins.split(',').map((o) => o.trim()));
|
|
75
|
+
}
|
|
76
|
+
// 3. Set CORS headers
|
|
77
|
+
if (origin && allowedOrigins.includes(origin)) {
|
|
78
|
+
res.setHeader('Access-Control-Allow-Origin', origin);
|
|
79
|
+
res.setHeader('Access-Control-Allow-Credentials', 'true');
|
|
80
|
+
}
|
|
81
|
+
else if (allowedOrigins.length === 0 && !origin) {
|
|
82
|
+
// If no origin header (e.g., server-to-server), allow it
|
|
83
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
84
|
+
}
|
|
85
|
+
// If origin is not allowed, don't set CORS headers (browser will block)
|
|
86
|
+
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD');
|
|
87
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
|
|
88
|
+
// Handle preflight requests
|
|
89
|
+
if (req.method === 'OPTIONS') {
|
|
90
|
+
return res.status(204).end();
|
|
91
|
+
}
|
|
92
|
+
return next();
|
|
93
|
+
});
|
|
58
94
|
// this will apply middleware to all /api/llm/* routes
|
|
59
95
|
app.use('/api/llm', expressRedactionMiddleware);
|
|
60
96
|
app.use('/api/config.yaml', expressRedactionMiddleware);
|
|
@@ -80,7 +116,7 @@ export async function initializeApi(agent, agentCardOverride, listenPort, agentI
|
|
|
80
116
|
function ensureAgentAvailable() {
|
|
81
117
|
// Gate requests during agent switching
|
|
82
118
|
if (isSwitchingAgent) {
|
|
83
|
-
throw AgentError.
|
|
119
|
+
throw AgentError.switchInProgress();
|
|
84
120
|
}
|
|
85
121
|
// Fast path: most common case is agent is started and running
|
|
86
122
|
if (activeAgent.isStarted() && !activeAgent.isStopped()) {
|
|
@@ -94,41 +130,103 @@ export async function initializeApi(agent, agentCardOverride, listenPort, agentI
|
|
|
94
130
|
throw AgentError.notStarted();
|
|
95
131
|
}
|
|
96
132
|
}
|
|
133
|
+
/**
|
|
134
|
+
* Common agent switching logic shared by switchAgentById and switchAgentByPath.
|
|
135
|
+
* Handles: registering subscribers, starting agent, stopping previous agent, updating global state.
|
|
136
|
+
*
|
|
137
|
+
* @param newAgent The new DextoAgent instance to switch to
|
|
138
|
+
* @param agentId The identifier for the agent (used for logging and state tracking)
|
|
139
|
+
* @returns Agent info for the newly activated agent
|
|
140
|
+
*/
|
|
141
|
+
async function performAgentSwitch(newAgent, agentId) {
|
|
142
|
+
// Register event subscribers with new agent before starting
|
|
143
|
+
logger.info('Registering event subscribers with new agent...');
|
|
144
|
+
newAgent.registerSubscriber(webSubscriber);
|
|
145
|
+
newAgent.registerSubscriber(webhookSubscriber);
|
|
146
|
+
logger.info(`Starting new agent: ${agentId}`);
|
|
147
|
+
await newAgent.start();
|
|
148
|
+
// Stop previous agent last (only after new one is fully operational)
|
|
149
|
+
const previousAgent = activeAgent;
|
|
150
|
+
activeAgent = newAgent;
|
|
151
|
+
activeAgentId = agentId;
|
|
152
|
+
// Update agent card for A2A and MCP routes
|
|
153
|
+
agentCardData = createAgentCard({
|
|
154
|
+
defaultName: agentId,
|
|
155
|
+
defaultVersion: overrides.version ?? '1.0.0',
|
|
156
|
+
defaultBaseUrl: baseApiUrl,
|
|
157
|
+
webSubscriber,
|
|
158
|
+
}, overrides);
|
|
159
|
+
logger.info(`Successfully switched to agent: ${agentId}`);
|
|
160
|
+
// Now safely stop the previous agent
|
|
161
|
+
try {
|
|
162
|
+
if (previousAgent && previousAgent !== newAgent) {
|
|
163
|
+
logger.info('Stopping previous agent...');
|
|
164
|
+
await previousAgent.stop();
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
logger.warn(`Stopping previous agent failed: ${err}`);
|
|
169
|
+
// Don't throw here as the switch was successful
|
|
170
|
+
}
|
|
171
|
+
return await resolveAgentInfo(agentId);
|
|
172
|
+
}
|
|
97
173
|
async function switchAgentById(agentId) {
|
|
98
174
|
if (isSwitchingAgent) {
|
|
99
|
-
throw AgentError.
|
|
175
|
+
throw AgentError.switchInProgress();
|
|
100
176
|
}
|
|
101
177
|
isSwitchingAgent = true;
|
|
102
178
|
let newAgent;
|
|
103
179
|
try {
|
|
104
|
-
//
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
180
|
+
// 1. SHUTDOWN OLD TELEMETRY FIRST (before creating new agent)
|
|
181
|
+
// This allows new agent to have different telemetry config (endpoint, protocol, etc.)
|
|
182
|
+
logger.info('Shutting down telemetry for agent switch...');
|
|
183
|
+
const { Telemetry } = await import('@dexto/core');
|
|
184
|
+
await Telemetry.shutdownGlobal();
|
|
185
|
+
// 2. Create new agent from registry (will initialize fresh telemetry in createAgentServices)
|
|
186
|
+
newAgent = await Dexto.createAgent(agentId);
|
|
187
|
+
// 3. Use common switch logic (register subscribers, start agent, stop previous)
|
|
188
|
+
return await performAgentSwitch(newAgent, agentId);
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
logger.error(`Failed to switch to agent '${agentId}': ${error instanceof Error ? error.message : String(error)}`, { error });
|
|
192
|
+
// Clean up the failed new agent if it was created
|
|
193
|
+
if (newAgent) {
|
|
194
|
+
try {
|
|
195
|
+
await newAgent.stop();
|
|
196
|
+
}
|
|
197
|
+
catch (cleanupErr) {
|
|
198
|
+
logger.warn(`Failed to cleanup new agent: ${cleanupErr}`);
|
|
122
199
|
}
|
|
123
200
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
201
|
+
throw error;
|
|
202
|
+
}
|
|
203
|
+
finally {
|
|
204
|
+
isSwitchingAgent = false;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
async function switchAgentByPath(filePath) {
|
|
208
|
+
if (isSwitchingAgent) {
|
|
209
|
+
throw AgentError.switchInProgress();
|
|
210
|
+
}
|
|
211
|
+
isSwitchingAgent = true;
|
|
212
|
+
let newAgent;
|
|
213
|
+
try {
|
|
214
|
+
// 1. SHUTDOWN OLD TELEMETRY FIRST (before creating new agent)
|
|
215
|
+
// This allows new agent to have different telemetry config (endpoint, protocol, etc.)
|
|
216
|
+
logger.info('Shutting down telemetry for agent switch...');
|
|
217
|
+
const { Telemetry } = await import('@dexto/core');
|
|
218
|
+
await Telemetry.shutdownGlobal();
|
|
219
|
+
// 2. Load agent configuration from file path
|
|
220
|
+
const config = await loadAgentConfig(filePath);
|
|
221
|
+
// 3. Create new agent instance directly (will initialize fresh telemetry in createAgentServices)
|
|
222
|
+
newAgent = new DextoAgent(config, filePath);
|
|
223
|
+
// 4. Derive agent ID from config or filename
|
|
224
|
+
const agentId = config.agentCard?.name || path.basename(filePath, path.extname(filePath));
|
|
225
|
+
// 5. Use common switch logic (register subscribers, start agent, stop previous)
|
|
226
|
+
return await performAgentSwitch(newAgent, agentId);
|
|
129
227
|
}
|
|
130
228
|
catch (error) {
|
|
131
|
-
logger.error(`Failed to switch to agent '${
|
|
229
|
+
logger.error(`Failed to switch to agent from path '${filePath}': ${error instanceof Error ? error.message : String(error)}`, { error });
|
|
132
230
|
// Clean up the failed new agent if it was created
|
|
133
231
|
if (newAgent) {
|
|
134
232
|
try {
|
|
@@ -587,6 +685,28 @@ export async function initializeApi(agent, agentCardOverride, listenPort, agentI
|
|
|
587
685
|
return next(error);
|
|
588
686
|
}
|
|
589
687
|
});
|
|
688
|
+
// Endpoint to restart an MCP server
|
|
689
|
+
const RestartMcpServerParamsSchema = z.object({
|
|
690
|
+
serverId: z.string().min(1, 'Server ID is required'),
|
|
691
|
+
});
|
|
692
|
+
app.post('/api/mcp/servers/:serverId/restart', async (req, res, next) => {
|
|
693
|
+
try {
|
|
694
|
+
ensureAgentAvailable();
|
|
695
|
+
const { serverId } = parseQuery(RestartMcpServerParamsSchema, req.params);
|
|
696
|
+
logger.info(`Received request to POST /api/mcp/servers/${serverId}/restart`);
|
|
697
|
+
// Check if server exists before attempting to restart
|
|
698
|
+
const clientExists = activeAgent.getMcpClients().has(serverId);
|
|
699
|
+
if (!clientExists) {
|
|
700
|
+
logger.warn(`Attempted to restart non-existent server: ${serverId}`);
|
|
701
|
+
return res.status(404).json({ error: `Server '${serverId}' not found.` });
|
|
702
|
+
}
|
|
703
|
+
await activeAgent.restartMcpServer(serverId);
|
|
704
|
+
return res.status(200).json({ status: 'restarted', id: serverId });
|
|
705
|
+
}
|
|
706
|
+
catch (error) {
|
|
707
|
+
return next(error);
|
|
708
|
+
}
|
|
709
|
+
});
|
|
590
710
|
// Execute an MCP tool via REST wrapper
|
|
591
711
|
const ExecuteMcpToolParamsSchema = z.object({
|
|
592
712
|
serverId: z.string().min(1, 'Server ID is required'),
|
|
@@ -878,7 +998,7 @@ export async function initializeApi(agent, agentCardOverride, listenPort, agentI
|
|
|
878
998
|
const overrides = agentCardOverride ?? {};
|
|
879
999
|
const resolvedPort = typeof listenPort === 'number' ? listenPort : Number(process.env.PORT || 3000);
|
|
880
1000
|
const baseApiUrl = process.env.DEXTO_BASE_URL || `http://localhost:${resolvedPort}`;
|
|
881
|
-
|
|
1001
|
+
let agentCardData = createAgentCard({
|
|
882
1002
|
defaultName: overrides.name ?? 'dexto',
|
|
883
1003
|
defaultVersion: overrides.version ?? '1.0.0',
|
|
884
1004
|
defaultBaseUrl: baseApiUrl,
|
|
@@ -887,19 +1007,15 @@ export async function initializeApi(agent, agentCardOverride, listenPort, agentI
|
|
|
887
1007
|
const _agentName = agentCardData.name;
|
|
888
1008
|
const _agentVersion = agentCardData.version;
|
|
889
1009
|
// Setup A2A routes
|
|
890
|
-
setupA2ARoutes(app, agentCardData);
|
|
1010
|
+
setupA2ARoutes(app, () => agentCardData);
|
|
891
1011
|
// Setup Memory routes
|
|
892
|
-
app.use('/api/memory', setupMemoryRoutes(activeAgent));
|
|
1012
|
+
app.use('/api/memory', setupMemoryRoutes(() => activeAgent));
|
|
893
1013
|
// --- Initialize and Setup MCP Server and Endpoints ---
|
|
894
1014
|
// Get transport type from environment variable or default to http
|
|
895
1015
|
try {
|
|
896
1016
|
const transportType = process.env.DEXTO_MCP_TRANSPORT_TYPE || 'http';
|
|
897
1017
|
const mcpTransport = await createMcpTransport(transportType);
|
|
898
|
-
|
|
899
|
-
// initializeMcpServer receives the original agent, so MCP endpoints keep talking to the stale instance post-switch.
|
|
900
|
-
// Make MCP consume the current agent via a getter to stay in sync.
|
|
901
|
-
await initializeMcpServer(agent, agentCardData, // Pass the agent card data for the MCP resource
|
|
902
|
-
mcpTransport);
|
|
1018
|
+
await initializeMcpServer(() => activeAgent, () => agentCardData, mcpTransport);
|
|
903
1019
|
await initializeMcpServerApiEndpoints(app, mcpTransport);
|
|
904
1020
|
}
|
|
905
1021
|
catch (error) {
|
|
@@ -958,6 +1074,10 @@ export async function initializeApi(agent, agentCardOverride, listenPort, agentI
|
|
|
958
1074
|
.string()
|
|
959
1075
|
.min(1, 'Agent id is required')
|
|
960
1076
|
.describe('Unique agent identifier (e.g., "database-agent")'),
|
|
1077
|
+
path: z
|
|
1078
|
+
.string()
|
|
1079
|
+
.optional()
|
|
1080
|
+
.describe('Optional absolute file path for file-based agents (e.g., "/path/to/agent.yml")'),
|
|
961
1081
|
})
|
|
962
1082
|
.strict();
|
|
963
1083
|
const UninstallAgentSchema = z
|
|
@@ -1041,16 +1161,12 @@ export async function initializeApi(agent, agentCardOverride, listenPort, agentI
|
|
|
1041
1161
|
});
|
|
1042
1162
|
app.post('/api/agents/switch', express.json(), async (req, res, next) => {
|
|
1043
1163
|
try {
|
|
1044
|
-
const { id } = parseBody(AgentIdentifierSchema, req.body);
|
|
1045
|
-
|
|
1164
|
+
const { id, path } = parseBody(AgentIdentifierSchema, req.body);
|
|
1165
|
+
// Route based on presence of path parameter
|
|
1166
|
+
const result = path ? await switchAgentByPath(path) : await switchAgentById(id);
|
|
1046
1167
|
return sendJsonResponse(res, { switched: true, ...result });
|
|
1047
1168
|
}
|
|
1048
1169
|
catch (error) {
|
|
1049
|
-
if (error instanceof Error &&
|
|
1050
|
-
error.message &&
|
|
1051
|
-
error.message.includes('already in progress')) {
|
|
1052
|
-
return res.status(409).json({ error: error.message });
|
|
1053
|
-
}
|
|
1054
1170
|
return next(error);
|
|
1055
1171
|
}
|
|
1056
1172
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"websocket-subscriber.d.ts","sourceRoot":"","sources":["../../src/api/websocket-subscriber.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAa,MAAM,IAAI,CAAC;AAEhD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C;;GAEG;AACH,qBAAa,wBAAyB,YAAW,eAAe;IAIhD,OAAO,CAAC,GAAG;IAHvB,OAAO,CAAC,WAAW,CAA6B;IAChD,OAAO,CAAC,eAAe,CAAC,CAAkB;gBAEtB,GAAG,EAAE,eAAe;IAmBxC;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"websocket-subscriber.d.ts","sourceRoot":"","sources":["../../src/api/websocket-subscriber.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAa,MAAM,IAAI,CAAC;AAEhD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C;;GAEG;AACH,qBAAa,wBAAyB,YAAW,eAAe;IAIhD,OAAO,CAAC,GAAG;IAHvB,OAAO,CAAC,WAAW,CAA6B;IAChD,OAAO,CAAC,eAAe,CAAC,CAAkB;gBAEtB,GAAG,EAAE,eAAe;IAmBxC;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI;IA6PxC;;OAEG;IACH,OAAO,IAAI,IAAI;IAiBf;;;OAGG;IACH,WAAW,IAAI,IAAI;IAYnB,OAAO,CAAC,SAAS;CAUpB"}
|
|
@@ -70,6 +70,12 @@ export class WebSocketEventSubscriber {
|
|
|
70
70
|
});
|
|
71
71
|
}, { signal });
|
|
72
72
|
eventBus.on('llmservice:toolResult', (payload) => {
|
|
73
|
+
logger.debug(`[websocket-subscriber]: llmservice:toolResult: ${JSON.stringify({
|
|
74
|
+
toolName: payload.toolName,
|
|
75
|
+
callId: payload.callId,
|
|
76
|
+
success: payload.success,
|
|
77
|
+
sessionId: payload.sessionId,
|
|
78
|
+
})}`);
|
|
73
79
|
const data = {
|
|
74
80
|
toolName: payload.toolName,
|
|
75
81
|
callId: payload.callId,
|
|
@@ -140,8 +140,8 @@ export const modelCommands = {
|
|
|
140
140
|
console.log(` ${chalk.yellow('/model current')} - Display currently active model and configuration`);
|
|
141
141
|
console.log(` ${chalk.yellow('/model switch')} ${chalk.blue('<model>')} - Switch to a different AI model (provider auto-detected)`);
|
|
142
142
|
console.log(` Examples:`);
|
|
143
|
-
console.log(` ${chalk.dim('/model switch gpt-
|
|
144
|
-
console.log(` ${chalk.dim('/model switch claude-4-
|
|
143
|
+
console.log(` ${chalk.dim('/model switch gpt-5')}`);
|
|
144
|
+
console.log(` ${chalk.dim('/model switch claude-sonnet-4-5-20250929')}`);
|
|
145
145
|
console.log(` ${chalk.dim('/model switch gemini-2.5-pro')}`);
|
|
146
146
|
console.log(` ${chalk.yellow('/model help')} - Show this help message`);
|
|
147
147
|
console.log(chalk.dim('\n💡 Switching models allows you to use different AI capabilities'));
|
|
@@ -13,9 +13,9 @@ export function validateCliOptions(opts) {
|
|
|
13
13
|
agent: z.string().min(1, 'Agent name or path must not be empty').optional(),
|
|
14
14
|
strict: z.boolean().optional().default(false),
|
|
15
15
|
verbose: z.boolean().optional().default(true),
|
|
16
|
-
mode: z.enum(['
|
|
16
|
+
mode: z.enum(['web', 'cli', 'server', 'discord', 'telegram', 'mcp'], {
|
|
17
17
|
errorMap: () => ({
|
|
18
|
-
message: 'Mode must be one of "
|
|
18
|
+
message: 'Mode must be one of "web", "cli", "server", "discord", "telegram", or "mcp"',
|
|
19
19
|
}),
|
|
20
20
|
}),
|
|
21
21
|
webPort: z.string().refine((val) => {
|
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';
|
|
@@ -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
|
|
@@ -409,31 +411,55 @@ program
|
|
|
409
411
|
// Main customer facing description
|
|
410
412
|
.description('Dexto CLI - AI-powered assistant with session management\n\n' +
|
|
411
413
|
'Basic Usage:\n' +
|
|
412
|
-
' dexto Start
|
|
413
|
-
' dexto "query"
|
|
414
|
-
' 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' +
|
|
415
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' +
|
|
416
420
|
'Session Management:\n' +
|
|
417
421
|
' dexto -c Continue most recent conversation\n' +
|
|
418
|
-
' dexto -c -p "query" Continue
|
|
419
|
-
' 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' +
|
|
420
424
|
'Tool Confirmation:\n' +
|
|
421
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' +
|
|
422
430
|
'Advanced Modes:\n' +
|
|
423
|
-
' dexto --mode web Run web UI\n' +
|
|
424
431
|
' dexto --mode server Run as API server\n' +
|
|
425
432
|
' dexto --mode discord Run as Discord bot\n' +
|
|
426
433
|
' dexto --mode telegram Run as Telegram bot\n' +
|
|
427
434
|
' dexto --mode mcp Run as MCP server\n\n' +
|
|
428
435
|
'Session Commands: dexto session list|history|delete • search\n' +
|
|
429
436
|
'Search: dexto search <query> [--session <id>] [--role <role>]\n\n' +
|
|
430
|
-
'See https://
|
|
437
|
+
'See https://docs.dexto.ai for documentation and examples')
|
|
431
438
|
.action(withAnalytics('main', async (prompt = []) => {
|
|
432
439
|
// ——— ENV CHECK (optional) ———
|
|
433
440
|
if (!existsSync('.env')) {
|
|
434
441
|
logger.debug('WARNING: .env file not found; copy .env.example and set your API keys.');
|
|
435
442
|
}
|
|
436
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
|
+
}
|
|
437
463
|
let headlessInput = undefined;
|
|
438
464
|
// Prefer explicit -p/--prompt for headless one-shot
|
|
439
465
|
if (opts.prompt !== undefined && String(opts.prompt).trim() !== '') {
|
|
@@ -456,6 +482,13 @@ program
|
|
|
456
482
|
}
|
|
457
483
|
// Note: Agent selection must be passed via -a/--agent. We no longer interpret
|
|
458
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
|
+
}
|
|
459
492
|
// ——— Infer provider & API key from model ———
|
|
460
493
|
if (opts.model) {
|
|
461
494
|
let provider;
|
|
@@ -469,7 +502,8 @@ program
|
|
|
469
502
|
}
|
|
470
503
|
const apiKey = resolveApiKeyForProvider(provider);
|
|
471
504
|
if (!apiKey) {
|
|
472
|
-
|
|
505
|
+
const envVar = getPrimaryApiKeyEnvVar(provider);
|
|
506
|
+
console.error(`❌ Missing API key for provider '${provider}' - please set $${envVar}`);
|
|
473
507
|
safeExit('main', 1, 'missing-api-key');
|
|
474
508
|
}
|
|
475
509
|
opts.provider = provider;
|
|
@@ -536,6 +570,7 @@ program
|
|
|
536
570
|
}
|
|
537
571
|
// ——— CREATE AGENT ———
|
|
538
572
|
let agent;
|
|
573
|
+
let derivedAgentId;
|
|
539
574
|
try {
|
|
540
575
|
console.log(`🚀 Initializing Dexto with config: ${resolvedPath}`);
|
|
541
576
|
// Set run mode for tool confirmation provider
|
|
@@ -551,6 +586,11 @@ program
|
|
|
551
586
|
agent = new DextoAgent(validatedConfig, resolvedPath);
|
|
552
587
|
// Start the agent (initialize async services)
|
|
553
588
|
await agent.start();
|
|
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));
|
|
554
594
|
}
|
|
555
595
|
catch (err) {
|
|
556
596
|
if (err instanceof ExitSignal)
|
|
@@ -628,11 +668,15 @@ program
|
|
|
628
668
|
case 'web': {
|
|
629
669
|
const webPort = parseInt(opts.webPort, 10);
|
|
630
670
|
const frontPort = getPort(process.env.FRONTEND_PORT, webPort, 'FRONTEND_PORT');
|
|
631
|
-
|
|
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');
|
|
632
676
|
const apiUrl = process.env.API_URL ?? `http://localhost:${apiPort}`;
|
|
633
677
|
const nextJSserverURL = process.env.FRONTEND_URL ?? `http://localhost:${frontPort}`;
|
|
634
678
|
// Start API server
|
|
635
|
-
await startApiServer(agent, apiPort, agent.getEffectiveConfig().agentCard || {},
|
|
679
|
+
await startApiServer(agent, apiPort, agent.getEffectiveConfig().agentCard || {}, derivedAgentId);
|
|
636
680
|
// Start Next.js web server
|
|
637
681
|
const webServerStarted = await startNextJsWebServer(apiUrl, frontPort, nextJSserverURL);
|
|
638
682
|
// Open WebUI in browser if server started successfully
|
|
@@ -653,10 +697,12 @@ program
|
|
|
653
697
|
case 'server': {
|
|
654
698
|
// Start server with REST APIs and WebSockets only
|
|
655
699
|
const agentCard = agent.getEffectiveConfig().agentCard ?? {};
|
|
656
|
-
|
|
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');
|
|
657
703
|
const apiUrl = process.env.API_URL ?? `http://localhost:${apiPort}`;
|
|
658
704
|
console.log('🌐 Starting server (REST APIs + WebSockets)...');
|
|
659
|
-
await startApiServer(agent, apiPort, agentCard,
|
|
705
|
+
await startApiServer(agent, apiPort, agentCard, derivedAgentId);
|
|
660
706
|
console.log(`✅ Server running at ${apiUrl}`);
|
|
661
707
|
console.log('Available endpoints:');
|
|
662
708
|
console.log(' POST /api/message - Send async message');
|
|
@@ -706,7 +752,7 @@ program
|
|
|
706
752
|
);
|
|
707
753
|
// Use stdio transport in mcp mode
|
|
708
754
|
const mcpTransport = await createMcpTransport('stdio');
|
|
709
|
-
await initializeMcpServer(agent, agentCardData, mcpTransport);
|
|
755
|
+
await initializeMcpServer(() => agent, () => agentCardData, mcpTransport);
|
|
710
756
|
}
|
|
711
757
|
catch (err) {
|
|
712
758
|
// Write to stderr instead of stdout to avoid interfering with MCP protocol
|
|
@@ -716,7 +762,7 @@ program
|
|
|
716
762
|
break;
|
|
717
763
|
}
|
|
718
764
|
default:
|
|
719
|
-
console.error(`❌ Unknown mode '${opts.mode}'. Use
|
|
765
|
+
console.error(`❌ Unknown mode '${opts.mode}'. Use web, cli, server, discord, telegram, or mcp.`);
|
|
720
766
|
safeExit('main', 1, 'unknown-mode');
|
|
721
767
|
}
|
|
722
768
|
}, { timeoutMs: 0 }));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
self.__BUILD_MANIFEST=function(e,r,t,_){return{__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},__routerFilterStatic:{numItems:3,errorRate:1e-4,numBits:58,numHashes:14,bitArray:[1,1,e,e,0,e,e,0,r,e,r,e,r,e,e,e,r,e,e,e,r,r,e,r,r,r,r,r,e,e,e,e,e,e,r,e,e,r,e,e,r,r,e,r,e,r,r,e,e,e,r,r,r,r,e,r,r,e]},__routerFilterDynamic:{numItems:e,errorRate:1e-4,numBits:20,numHashes:14,bitArray:[r,r,r,r,e,e,e,r,e,e,r,r,r,r,e,r,r,e,e,e]},"/_error":["static/chunks/pages/_error-162d61367b59fad2.js"],sortedPages:["/_app","/_error"]}}(1,0,1e-4,14),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
|