@mcpc-tech/unplugin-dev-inspector-mcp 0.0.31 → 0.0.34
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 +38 -1
- package/client/dist/inspector.iife.js +241 -238
- package/client.d.ts +55 -9
- package/dist/config-updater.cjs +242 -40
- package/dist/config-updater.js +270 -68
- package/dist/index.cjs +19 -0
- package/dist/index.js +19 -0
- package/package.json +6 -6
package/client.d.ts
CHANGED
|
@@ -3,19 +3,65 @@
|
|
|
3
3
|
|
|
4
4
|
declare module "virtual:dev-inspector-mcp" {
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
* JSON Schema for tool input parameters
|
|
7
|
+
*/
|
|
8
|
+
export interface ToolInputSchema {
|
|
9
|
+
type: "object";
|
|
10
|
+
properties: Record<
|
|
11
|
+
string,
|
|
12
|
+
{
|
|
13
|
+
type: string;
|
|
14
|
+
description?: string;
|
|
15
|
+
enum?: string[];
|
|
16
|
+
default?: unknown;
|
|
17
|
+
}
|
|
18
|
+
>;
|
|
19
|
+
required?: string[];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Custom inspector tool definition
|
|
24
|
+
*/
|
|
25
|
+
export interface InspectorTool {
|
|
26
|
+
/** Unique tool name */
|
|
27
|
+
name: string;
|
|
28
|
+
/** Tool description for AI agents */
|
|
29
|
+
description: string;
|
|
30
|
+
/** JSON Schema defining input parameters */
|
|
31
|
+
inputSchema: ToolInputSchema;
|
|
32
|
+
/** Implementation function that executes when the tool is called */
|
|
33
|
+
implementation: (args: Record<string, unknown>) => unknown | Promise<unknown>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Register a custom tool that can be called by AI agents through MCP.
|
|
10
38
|
*
|
|
11
39
|
* @example
|
|
12
40
|
* ```typescript
|
|
13
|
-
*
|
|
14
|
-
* import 'virtual:dev-inspector-mcp';
|
|
15
|
-
* ```
|
|
41
|
+
* import { registerInspectorTool } from 'virtual:dev-inspector-mcp';
|
|
16
42
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
43
|
+
* registerInspectorTool({
|
|
44
|
+
* name: "custom_alert",
|
|
45
|
+
* description: "Show a custom alert in the browser",
|
|
46
|
+
* inputSchema: {
|
|
47
|
+
* type: "object",
|
|
48
|
+
* properties: {
|
|
49
|
+
* message: { type: "string", description: "Message to display" }
|
|
50
|
+
* },
|
|
51
|
+
* required: ["message"]
|
|
52
|
+
* },
|
|
53
|
+
* implementation: (args) => {
|
|
54
|
+
* alert(args.message as string);
|
|
55
|
+
* return { success: true };
|
|
56
|
+
* }
|
|
57
|
+
* });
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export function registerInspectorTool(tool: InspectorTool): void;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Development-only inspector initialization module.
|
|
64
|
+
* This module is automatically tree-shaken in production builds.
|
|
19
65
|
*/
|
|
20
66
|
const _default: void;
|
|
21
67
|
export default _default;
|
package/dist/config-updater.cjs
CHANGED
|
@@ -87226,7 +87226,7 @@ function setupInspectorMiddleware(middlewares, config) {
|
|
|
87226
87226
|
}
|
|
87227
87227
|
|
|
87228
87228
|
//#endregion
|
|
87229
|
-
//#region ../../node_modules/.pnpm/@mcpc-tech+acp-ai-provider@0.1.
|
|
87229
|
+
//#region ../../node_modules/.pnpm/@mcpc-tech+acp-ai-provider@0.1.41/node_modules/@mcpc-tech/acp-ai-provider/index.mjs
|
|
87230
87230
|
(0, node_module.createRequire)(require("url").pathToFileURL(__filename).href);
|
|
87231
87231
|
function formatToolError(toolResult) {
|
|
87232
87232
|
if (!toolResult || toolResult.length === 0) return "Unknown tool error";
|
|
@@ -87383,8 +87383,13 @@ var ToolProxyHost = class {
|
|
|
87383
87383
|
* Start TCP server and return MCP server config for ACP
|
|
87384
87384
|
*/
|
|
87385
87385
|
async start() {
|
|
87386
|
-
if (this.server)
|
|
87387
|
-
|
|
87386
|
+
if (!this.server) await this.startServer();
|
|
87387
|
+
return this.getServerConfig();
|
|
87388
|
+
}
|
|
87389
|
+
/**
|
|
87390
|
+
* Get MCP server configuration
|
|
87391
|
+
*/
|
|
87392
|
+
getServerConfig() {
|
|
87388
87393
|
return {
|
|
87389
87394
|
name: this.serverName,
|
|
87390
87395
|
command: "node",
|
|
@@ -87464,8 +87469,10 @@ var ToolProxyHost = class {
|
|
|
87464
87469
|
text: typeof result === "string" ? result : JSON.stringify(result)
|
|
87465
87470
|
}] };
|
|
87466
87471
|
this.sendResponse(socket, createResponse(request.id, toolResult));
|
|
87467
|
-
} else if (request.method === "getTools")
|
|
87468
|
-
|
|
87472
|
+
} else if (request.method === "getTools") {
|
|
87473
|
+
const definitions = this.getToolDefinitions();
|
|
87474
|
+
this.sendResponse(socket, createResponse(request.id, definitions));
|
|
87475
|
+
} else this.sendResponse(socket, createErrorResponse(request.id, JsonRpcErrorCode.METHOD_NOT_FOUND, `Unknown method: ${request.method}`));
|
|
87469
87476
|
} catch (error) {
|
|
87470
87477
|
this.sendResponse(socket, createErrorResponse(request.id, JsonRpcErrorCode.INTERNAL_ERROR, error instanceof Error ? error.message : String(error)));
|
|
87471
87478
|
}
|
|
@@ -87565,16 +87572,22 @@ function convertAiSdkMessagesToAcp(options, isFreshSession) {
|
|
|
87565
87572
|
}
|
|
87566
87573
|
return contentBlocks;
|
|
87567
87574
|
}
|
|
87568
|
-
function extractACPTools(tools) {
|
|
87575
|
+
function extractACPTools(tools, prepared = true) {
|
|
87569
87576
|
const acpTools2 = [];
|
|
87570
87577
|
if (!tools) return acpTools2;
|
|
87571
|
-
|
|
87578
|
+
const toolsArray = Array.isArray(tools) ? tools : Object.entries(tools).map(([name, tool2]) => ({
|
|
87579
|
+
type: "function",
|
|
87580
|
+
name,
|
|
87581
|
+
...tool2
|
|
87582
|
+
}));
|
|
87583
|
+
for (const t of toolsArray) if (t.type === "function") {
|
|
87572
87584
|
const toolInputSchema = t.inputSchema;
|
|
87573
87585
|
if (hasRegisteredExecute(t.name) && toolInputSchema) {
|
|
87574
87586
|
const execute = getExecuteByName(t.name);
|
|
87575
87587
|
if (execute) acpTools2.push({
|
|
87576
87588
|
...t,
|
|
87577
87589
|
name: t.name,
|
|
87590
|
+
inputSchema: prepared ? toolInputSchema : (0, ai.asSchema)(toolInputSchema).jsonSchema,
|
|
87578
87591
|
execute
|
|
87579
87592
|
});
|
|
87580
87593
|
}
|
|
@@ -87607,12 +87620,10 @@ var ACPAISDKClient = class {
|
|
|
87607
87620
|
optionId: params.options[0]?.optionId || "allow"
|
|
87608
87621
|
} };
|
|
87609
87622
|
}
|
|
87610
|
-
writeTextFile(
|
|
87611
|
-
console.log("[acp-ai-provider] Write file request (not implemented):", params.path);
|
|
87623
|
+
writeTextFile(_params) {
|
|
87612
87624
|
throw new Error("File operations not implemented in language model client");
|
|
87613
87625
|
}
|
|
87614
|
-
readTextFile(
|
|
87615
|
-
console.log("[acp-ai-provider] Read file request (not implemented):", params.path);
|
|
87626
|
+
readTextFile(_params) {
|
|
87616
87627
|
throw new Error("File operations not implemented in language model client");
|
|
87617
87628
|
}
|
|
87618
87629
|
};
|
|
@@ -87658,6 +87669,7 @@ var ACPLanguageModel = class {
|
|
|
87658
87669
|
*/
|
|
87659
87670
|
parseToolCall(update$1) {
|
|
87660
87671
|
if (update$1.sessionUpdate !== "tool_call") throw new Error("Invalid update type for parseToolCall");
|
|
87672
|
+
console.log("Parsing tool call update:", JSON.stringify(update$1, null, 2));
|
|
87661
87673
|
return {
|
|
87662
87674
|
toolCallId: update$1.toolCallId,
|
|
87663
87675
|
toolName: update$1.title || update$1.toolCallId,
|
|
@@ -87730,7 +87742,7 @@ var ACPLanguageModel = class {
|
|
|
87730
87742
|
if (initResult.authMethods?.length ?? false) {
|
|
87731
87743
|
if (!this.config.authMethodId || !validAuthMethods) console.log("[acp-ai-provider] Warning: No authMethodId specified in config, skipping authentication step. If this is not desired, please set one of the authMethodId in the ACPProviderSettings.", JSON.stringify(initResult.authMethods, null, 2));
|
|
87732
87744
|
if (this.config.authMethodId && validAuthMethods) await this.connection.authenticate({ methodId: this.config.authMethodId ?? initResult.authMethods?.[0].id });
|
|
87733
|
-
}
|
|
87745
|
+
}
|
|
87734
87746
|
}
|
|
87735
87747
|
/**
|
|
87736
87748
|
* Starts a new session or updates the existing one.
|
|
@@ -87738,19 +87750,19 @@ var ACPLanguageModel = class {
|
|
|
87738
87750
|
*/
|
|
87739
87751
|
async startSession(acpTools2) {
|
|
87740
87752
|
if (!this.connection) throw new Error("Not connected");
|
|
87741
|
-
console.log(`[acp-ai-provider] startSession called with ${acpTools2?.length ?? 0} tools`);
|
|
87742
87753
|
const mcpServers = [...this.config.session?.mcpServers ?? []];
|
|
87743
87754
|
let toolsAdded = false;
|
|
87744
87755
|
if (acpTools2 && acpTools2.length > 0 && !this.toolProxyHost) {
|
|
87745
|
-
console.log("[acp-ai-provider] Setting up tool proxy for client-side tools...");
|
|
87756
|
+
console.log("[acp-ai-provider] Setting up tool proxy for client-side tools...", acpTools2.map((t) => t.name));
|
|
87746
87757
|
this.toolProxyHost = new ToolProxyHost("acp-ai-sdk-tools");
|
|
87747
87758
|
for (const t of acpTools2) this.toolProxyHost.registerTool(t.name, t);
|
|
87759
|
+
toolsAdded = true;
|
|
87760
|
+
}
|
|
87761
|
+
if (this.toolProxyHost) {
|
|
87748
87762
|
const proxyConfig = await this.toolProxyHost.start();
|
|
87749
87763
|
mcpServers.push(proxyConfig);
|
|
87750
|
-
toolsAdded = true;
|
|
87751
87764
|
}
|
|
87752
87765
|
if (this.sessionId && toolsAdded) {
|
|
87753
|
-
console.log("[acp-ai-provider] Updating session to include new tools...");
|
|
87754
87766
|
this.sessionResponse = await this.connection.newSession({
|
|
87755
87767
|
...this.config.session,
|
|
87756
87768
|
cwd: this.config.session?.cwd ?? node_process.default.cwd(),
|
|
@@ -87795,7 +87807,7 @@ var ACPLanguageModel = class {
|
|
|
87795
87807
|
}
|
|
87796
87808
|
async applySessionDelay() {
|
|
87797
87809
|
if (this.config.sessionDelayMs) {
|
|
87798
|
-
console.log(`[acp-ai-provider] Waiting
|
|
87810
|
+
console.log(`[acp-ai-provider] Waiting ${this.config.sessionDelayMs}ms after session setup...`);
|
|
87799
87811
|
await new Promise((resolve$1) => setTimeout(resolve$1, this.config.sessionDelayMs));
|
|
87800
87812
|
}
|
|
87801
87813
|
}
|
|
@@ -87830,14 +87842,9 @@ var ACPLanguageModel = class {
|
|
|
87830
87842
|
*
|
|
87831
87843
|
* @param acpTools - Optional list of tools to register during session initialization.
|
|
87832
87844
|
*/
|
|
87833
|
-
async initSession(
|
|
87834
|
-
|
|
87835
|
-
|
|
87836
|
-
else toolsArray = Object.entries(acpTools2).map(([name, tool2]) => ({
|
|
87837
|
-
...tool2,
|
|
87838
|
-
name
|
|
87839
|
-
}));
|
|
87840
|
-
await this.ensureConnected(toolsArray);
|
|
87845
|
+
async initSession(tools) {
|
|
87846
|
+
const acpTools2 = extractACPTools(tools, false);
|
|
87847
|
+
await this.ensureConnected(acpTools2.length > 0 ? acpTools2 : void 0);
|
|
87841
87848
|
return this.sessionResponse;
|
|
87842
87849
|
}
|
|
87843
87850
|
/**
|
|
@@ -87964,6 +87971,11 @@ var ACPLanguageModel = class {
|
|
|
87964
87971
|
this.currentThinkingId = null;
|
|
87965
87972
|
}
|
|
87966
87973
|
const { toolCallId, toolName, toolInput } = this.parseToolCall(update$1);
|
|
87974
|
+
console.log(`Parsing tool call: ${JSON.stringify({
|
|
87975
|
+
toolCallId,
|
|
87976
|
+
toolName,
|
|
87977
|
+
toolInput
|
|
87978
|
+
}, null, 2)}`);
|
|
87967
87979
|
const existingToolCall = this.toolCallsMap.get(toolCallId);
|
|
87968
87980
|
const hasInput = toolInput && typeof toolInput === "object" && Object.keys(toolInput).length > 0;
|
|
87969
87981
|
if (!existingToolCall) {
|
|
@@ -88004,7 +88016,6 @@ var ACPLanguageModel = class {
|
|
|
88004
88016
|
break;
|
|
88005
88017
|
}
|
|
88006
88018
|
case "tool_call_update": {
|
|
88007
|
-
console.log(`###[acp-ai-provider] tool_call_update received:`, JSON.stringify(update$1, null, 2));
|
|
88008
88019
|
const { toolCallId, toolName, toolResult, isError, status } = this.parseToolResult(update$1);
|
|
88009
88020
|
let toolInfo = this.toolCallsMap.get(toolCallId);
|
|
88010
88021
|
if (status === "in_progress") {
|
|
@@ -88257,9 +88268,9 @@ var ACPProvider = class {
|
|
|
88257
88268
|
* Initializes the session and returns session info (models, modes, meta).
|
|
88258
88269
|
* Call this before prompting to discover available options.
|
|
88259
88270
|
*/
|
|
88260
|
-
initSession(
|
|
88271
|
+
initSession(tools) {
|
|
88261
88272
|
if (!this.model) this.languageModel();
|
|
88262
|
-
return this.model.initSession(
|
|
88273
|
+
return this.model.initSession(tools);
|
|
88263
88274
|
}
|
|
88264
88275
|
/**
|
|
88265
88276
|
* Initializes the connection to the agent process without starting a session.
|
|
@@ -88298,6 +88309,22 @@ function createACPProvider(config) {
|
|
|
88298
88309
|
//#endregion
|
|
88299
88310
|
//#region src/middleware/acp-middleware.ts
|
|
88300
88311
|
/**
|
|
88312
|
+
* Provider manager - stores one provider per agent config
|
|
88313
|
+
* Key: agentKey (command:args), Value: ProviderEntry
|
|
88314
|
+
*/
|
|
88315
|
+
const providerManager = /* @__PURE__ */ new Map();
|
|
88316
|
+
/**
|
|
88317
|
+
* Session to provider mapping for quick lookup
|
|
88318
|
+
* Key: sessionId, Value: agentKey
|
|
88319
|
+
*/
|
|
88320
|
+
const sessionToProvider = /* @__PURE__ */ new Map();
|
|
88321
|
+
/**
|
|
88322
|
+
* Generate a unique key for an agent configuration
|
|
88323
|
+
*/
|
|
88324
|
+
function getAgentKey(command, args) {
|
|
88325
|
+
return `${command}:${(args || []).join(",")}`;
|
|
88326
|
+
}
|
|
88327
|
+
/**
|
|
88301
88328
|
* Call MCP method via transport and wait for response
|
|
88302
88329
|
*/
|
|
88303
88330
|
function callMcpMethodViaTransport(transport, method, params) {
|
|
@@ -88355,6 +88382,163 @@ function getActiveTransport() {
|
|
|
88355
88382
|
return connectionManager.transports[sessionIds[0]];
|
|
88356
88383
|
}
|
|
88357
88384
|
function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
|
|
88385
|
+
/**
|
|
88386
|
+
* Initialize a session for an agent
|
|
88387
|
+
* POST /api/acp/init-session
|
|
88388
|
+
* Body: { agent, envVars }
|
|
88389
|
+
* Returns: { sessionId }
|
|
88390
|
+
*/
|
|
88391
|
+
middlewares.use("/api/acp/init-session", async (req, res) => {
|
|
88392
|
+
if (handleCors(res, req.method)) return;
|
|
88393
|
+
if (req.method !== "POST") {
|
|
88394
|
+
res.statusCode = 405;
|
|
88395
|
+
res.end("Method Not Allowed");
|
|
88396
|
+
return;
|
|
88397
|
+
}
|
|
88398
|
+
try {
|
|
88399
|
+
const body = await readBody(req);
|
|
88400
|
+
const { agent, envVars } = JSON.parse(body);
|
|
88401
|
+
const cwd$1 = process.cwd();
|
|
88402
|
+
const agentKey = getAgentKey(agent.command, agent.args);
|
|
88403
|
+
console.log(`[dev-inspector] [acp] Requesting session for agent: ${agent.name} (${agentKey})`);
|
|
88404
|
+
let providerEntry = providerManager.get(agentKey);
|
|
88405
|
+
let sessionId = "";
|
|
88406
|
+
if (providerEntry) {
|
|
88407
|
+
if (providerEntry.sessions.size > 0) {
|
|
88408
|
+
const firstSession = providerEntry.sessions.values().next().value;
|
|
88409
|
+
if (firstSession) {
|
|
88410
|
+
sessionId = firstSession.sessionId;
|
|
88411
|
+
console.log(`[dev-inspector] [acp] Reusing existing session: ${sessionId} for ${agent.name}`);
|
|
88412
|
+
}
|
|
88413
|
+
}
|
|
88414
|
+
if (!sessionId && providerEntry.initializationPromise) {
|
|
88415
|
+
console.log(`[dev-inspector] [acp] Joining pending initialization for ${agent.name}`);
|
|
88416
|
+
try {
|
|
88417
|
+
sessionId = await providerEntry.initializationPromise;
|
|
88418
|
+
} catch (e) {
|
|
88419
|
+
throw e;
|
|
88420
|
+
}
|
|
88421
|
+
}
|
|
88422
|
+
}
|
|
88423
|
+
if (!sessionId) {
|
|
88424
|
+
let provider;
|
|
88425
|
+
if (providerEntry) {
|
|
88426
|
+
console.log(`[dev-inspector] [acp] Reusing existing provider for ${agent.name}`);
|
|
88427
|
+
provider = providerEntry.provider;
|
|
88428
|
+
} else {
|
|
88429
|
+
console.log(`[dev-inspector] [acp] Creating new global provider for ${agent.name}`);
|
|
88430
|
+
provider = createACPProvider({
|
|
88431
|
+
command: agent.command,
|
|
88432
|
+
args: agent.args,
|
|
88433
|
+
env: {
|
|
88434
|
+
...process.env,
|
|
88435
|
+
...envVars
|
|
88436
|
+
},
|
|
88437
|
+
session: {
|
|
88438
|
+
cwd: cwd$1,
|
|
88439
|
+
mcpServers: []
|
|
88440
|
+
},
|
|
88441
|
+
authMethodId: agent.authMethodId,
|
|
88442
|
+
persistSession: true
|
|
88443
|
+
});
|
|
88444
|
+
providerEntry = {
|
|
88445
|
+
provider,
|
|
88446
|
+
agentKey,
|
|
88447
|
+
sessions: /* @__PURE__ */ new Map(),
|
|
88448
|
+
createdAt: Date.now(),
|
|
88449
|
+
initializationPromise: void 0
|
|
88450
|
+
};
|
|
88451
|
+
providerManager.set(agentKey, providerEntry);
|
|
88452
|
+
}
|
|
88453
|
+
console.log(`[dev-inspector] [acp] Spawning new process/session for ${agent.name}`);
|
|
88454
|
+
const initPromise = (async () => {
|
|
88455
|
+
const transport = getActiveTransport();
|
|
88456
|
+
let initialTools = {};
|
|
88457
|
+
if (transport) try {
|
|
88458
|
+
const rawTools = await loadMcpToolsV5(transport);
|
|
88459
|
+
initialTools = acpTools(rawTools);
|
|
88460
|
+
console.log(`[dev-inspector] [acp] Pre-loading ${Object.keys(rawTools).length} tools for session init`);
|
|
88461
|
+
} catch (e) {
|
|
88462
|
+
console.warn("[dev-inspector] [acp] Failed to pre-load tools:", e);
|
|
88463
|
+
}
|
|
88464
|
+
const sid = (await provider.initSession(initialTools)).sessionId || `session-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
88465
|
+
if (providerEntry) {
|
|
88466
|
+
providerEntry.sessions.set(sid, {
|
|
88467
|
+
sessionId: sid,
|
|
88468
|
+
createdAt: Date.now()
|
|
88469
|
+
});
|
|
88470
|
+
providerEntry.initializationPromise = void 0;
|
|
88471
|
+
}
|
|
88472
|
+
sessionToProvider.set(sid, agentKey);
|
|
88473
|
+
return sid;
|
|
88474
|
+
})();
|
|
88475
|
+
if (providerEntry) providerEntry.initializationPromise = initPromise;
|
|
88476
|
+
try {
|
|
88477
|
+
sessionId = await initPromise;
|
|
88478
|
+
console.log(`[dev-inspector] [acp] Session initialized: ${sessionId}`);
|
|
88479
|
+
} catch (error) {
|
|
88480
|
+
if (providerEntry) providerEntry.initializationPromise = void 0;
|
|
88481
|
+
throw error;
|
|
88482
|
+
}
|
|
88483
|
+
}
|
|
88484
|
+
res.setHeader("Content-Type", "application/json");
|
|
88485
|
+
res.end(JSON.stringify({ sessionId }));
|
|
88486
|
+
} catch (error) {
|
|
88487
|
+
console.error("ACP Init Session Error:", error);
|
|
88488
|
+
if (!res.headersSent) {
|
|
88489
|
+
res.statusCode = 500;
|
|
88490
|
+
res.end(JSON.stringify({ error: error instanceof Error ? error.message : "Internal Server Error" }));
|
|
88491
|
+
}
|
|
88492
|
+
}
|
|
88493
|
+
});
|
|
88494
|
+
/**
|
|
88495
|
+
* Cleanup a session
|
|
88496
|
+
* POST /api/acp/cleanup-session
|
|
88497
|
+
* Body: { sessionId }
|
|
88498
|
+
*/
|
|
88499
|
+
middlewares.use("/api/acp/cleanup-session", async (req, res) => {
|
|
88500
|
+
if (handleCors(res, req.method)) return;
|
|
88501
|
+
if (req.method !== "POST") {
|
|
88502
|
+
res.statusCode = 405;
|
|
88503
|
+
res.end("Method Not Allowed");
|
|
88504
|
+
return;
|
|
88505
|
+
}
|
|
88506
|
+
try {
|
|
88507
|
+
const body = await readBody(req);
|
|
88508
|
+
const { sessionId } = JSON.parse(body);
|
|
88509
|
+
const agentKey = sessionToProvider.get(sessionId);
|
|
88510
|
+
if (agentKey) {
|
|
88511
|
+
const providerEntry = providerManager.get(agentKey);
|
|
88512
|
+
if (providerEntry) {
|
|
88513
|
+
console.log(`[dev-inspector] [acp] Cleaning up session: ${sessionId} (Provider sessions left: ${providerEntry.sessions.size - 1})`);
|
|
88514
|
+
providerEntry.sessions.delete(sessionId);
|
|
88515
|
+
if (providerEntry.sessions.size === 0) {
|
|
88516
|
+
console.log(`[dev-inspector] [acp] No active sessions for ${agentKey}, cleaning up provider`);
|
|
88517
|
+
try {
|
|
88518
|
+
providerEntry.provider.cleanup();
|
|
88519
|
+
} catch (e) {
|
|
88520
|
+
console.error("Error cleaning up provider:", e);
|
|
88521
|
+
}
|
|
88522
|
+
providerManager.delete(agentKey);
|
|
88523
|
+
}
|
|
88524
|
+
}
|
|
88525
|
+
sessionToProvider.delete(sessionId);
|
|
88526
|
+
}
|
|
88527
|
+
res.setHeader("Content-Type", "application/json");
|
|
88528
|
+
res.end(JSON.stringify({ success: true }));
|
|
88529
|
+
} catch (error) {
|
|
88530
|
+
console.error("ACP Cleanup Session Error:", error);
|
|
88531
|
+
if (!res.headersSent) {
|
|
88532
|
+
res.statusCode = 500;
|
|
88533
|
+
res.end(JSON.stringify({ error: "Internal Server Error" }));
|
|
88534
|
+
}
|
|
88535
|
+
}
|
|
88536
|
+
});
|
|
88537
|
+
/**
|
|
88538
|
+
* Chat endpoint
|
|
88539
|
+
* POST /api/acp/chat
|
|
88540
|
+
* Body: { messages, agent, envVars, sessionId? }
|
|
88541
|
+
*/
|
|
88358
88542
|
middlewares.use("/api/acp/chat", async (req, res) => {
|
|
88359
88543
|
if (handleCors(res, req.method)) return;
|
|
88360
88544
|
if (req.method !== "POST") {
|
|
@@ -88364,18 +88548,36 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
|
|
|
88364
88548
|
}
|
|
88365
88549
|
try {
|
|
88366
88550
|
const body = await readBody(req);
|
|
88367
|
-
const { messages, agent, envVars } = JSON.parse(body);
|
|
88551
|
+
const { messages, agent, envVars, sessionId } = JSON.parse(body);
|
|
88368
88552
|
const cwd$1 = process.cwd();
|
|
88369
|
-
|
|
88370
|
-
|
|
88371
|
-
|
|
88372
|
-
|
|
88373
|
-
|
|
88374
|
-
|
|
88375
|
-
|
|
88376
|
-
|
|
88377
|
-
|
|
88378
|
-
|
|
88553
|
+
let provider;
|
|
88554
|
+
let shouldCleanupProvider = true;
|
|
88555
|
+
let existingProviderEntry;
|
|
88556
|
+
if (sessionId) {
|
|
88557
|
+
const agentKey = sessionToProvider.get(sessionId);
|
|
88558
|
+
if (agentKey) existingProviderEntry = providerManager.get(agentKey);
|
|
88559
|
+
}
|
|
88560
|
+
if (existingProviderEntry) {
|
|
88561
|
+
console.log(`[dev-inspector] [acp] Using existing global provider for session: ${sessionId}`);
|
|
88562
|
+
provider = existingProviderEntry.provider;
|
|
88563
|
+
shouldCleanupProvider = false;
|
|
88564
|
+
} else {
|
|
88565
|
+
console.log(`[dev-inspector] [acp] Creating new provider (no session found or provided)`);
|
|
88566
|
+
provider = createACPProvider({
|
|
88567
|
+
command: agent.command,
|
|
88568
|
+
args: agent.args,
|
|
88569
|
+
env: {
|
|
88570
|
+
...process.env,
|
|
88571
|
+
...envVars
|
|
88572
|
+
},
|
|
88573
|
+
session: {
|
|
88574
|
+
cwd: cwd$1,
|
|
88575
|
+
mcpServers: []
|
|
88576
|
+
},
|
|
88577
|
+
authMethodId: agent.authMethodId
|
|
88578
|
+
});
|
|
88579
|
+
await provider.initSession();
|
|
88580
|
+
}
|
|
88379
88581
|
const transport = getActiveTransport();
|
|
88380
88582
|
let mcpTools = {};
|
|
88381
88583
|
if (transport) mcpTools = await loadMcpToolsV5(transport);
|
|
@@ -88391,7 +88593,7 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
|
|
|
88391
88593
|
req.on("close", () => {
|
|
88392
88594
|
console.log("[dev-inspector] [acp] Client disconnected, aborting stream");
|
|
88393
88595
|
abortController.abort();
|
|
88394
|
-
provider.cleanup();
|
|
88596
|
+
if (shouldCleanupProvider) provider.cleanup();
|
|
88395
88597
|
});
|
|
88396
88598
|
const response = (0, ai.streamText)({
|
|
88397
88599
|
model: provider.languageModel(model, mode),
|