@mcpstack/agent-sdk 1.0.0-pr.18.bbb0c016bc21.17.1 → 1.0.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 +23 -46
- package/dist/app/index.d.mts +9 -25
- package/dist/app/index.d.ts +9 -25
- package/dist/app/index.js +95 -403
- package/dist/app/index.js.map +1 -1
- package/dist/app/index.mjs +95 -403
- package/dist/app/index.mjs.map +1 -1
- package/dist/index.d.mts +9 -25
- package/dist/index.d.ts +9 -25
- package/dist/index.js +95 -403
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +95 -403
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.d.mts +9 -25
- package/dist/react/index.d.ts +9 -25
- package/dist/react/index.js +95 -403
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +95 -403
- package/dist/react/index.mjs.map +1 -1
- package/dist/react-embed/index.js +95 -403
- package/dist/react-embed/index.js.map +1 -1
- package/dist/react-embed/index.mjs +95 -403
- package/dist/react-embed/index.mjs.map +1 -1
- package/dist/react-native/index.d.mts +9 -25
- package/dist/react-native/index.d.ts +9 -25
- package/dist/react-native/index.js +95 -403
- package/dist/react-native/index.js.map +1 -1
- package/dist/react-native/index.mjs +95 -403
- package/dist/react-native/index.mjs.map +1 -1
- package/package.json +3 -6
package/dist/index.js
CHANGED
|
@@ -43,15 +43,12 @@ function* parseEventBlocks(input) {
|
|
|
43
43
|
dataLines.push("");
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
|
-
if (dataLines.length === 0) {
|
|
46
|
+
if (!eventType || dataLines.length === 0) {
|
|
47
47
|
continue;
|
|
48
48
|
}
|
|
49
49
|
try {
|
|
50
50
|
const parsed = JSON.parse(dataLines.join("\n"));
|
|
51
|
-
|
|
52
|
-
const resolvedType = eventType || parsedType;
|
|
53
|
-
if (!resolvedType) continue;
|
|
54
|
-
yield { type: resolvedType, data: parsed };
|
|
51
|
+
yield { type: eventType, data: parsed };
|
|
55
52
|
} catch {
|
|
56
53
|
}
|
|
57
54
|
}
|
|
@@ -379,20 +376,6 @@ function clearPersistedMcpAuth() {
|
|
|
379
376
|
}
|
|
380
377
|
|
|
381
378
|
// src/core/EmcyAgent.ts
|
|
382
|
-
var AG_UI_EVENT = {
|
|
383
|
-
RUN_STARTED: "RUN_STARTED",
|
|
384
|
-
RUN_FINISHED: "RUN_FINISHED",
|
|
385
|
-
RUN_ERROR: "RUN_ERROR",
|
|
386
|
-
TEXT_MESSAGE_START: "TEXT_MESSAGE_START",
|
|
387
|
-
TEXT_MESSAGE_CONTENT: "TEXT_MESSAGE_CONTENT",
|
|
388
|
-
TEXT_MESSAGE_END: "TEXT_MESSAGE_END",
|
|
389
|
-
TOOL_CALL_START: "TOOL_CALL_START",
|
|
390
|
-
TOOL_CALL_ARGS: "TOOL_CALL_ARGS",
|
|
391
|
-
TOOL_CALL_END: "TOOL_CALL_END",
|
|
392
|
-
TOOL_CALL_RESULT: "TOOL_CALL_RESULT",
|
|
393
|
-
STATE_SNAPSHOT: "STATE_SNAPSHOT",
|
|
394
|
-
CUSTOM: "CUSTOM"
|
|
395
|
-
};
|
|
396
379
|
var DEFAULT_MCP_PROTOCOL_VERSION = "2025-11-25";
|
|
397
380
|
var DEFAULT_LOCAL_PUBLIC_APP_PORT = "3100";
|
|
398
381
|
var DEFAULT_OAUTH_CALLBACK_URL = "https://mcpstack.com/oauth/callback";
|
|
@@ -886,69 +869,6 @@ var McpStackAgent = class {
|
|
|
886
869
|
selection: def.selection
|
|
887
870
|
}));
|
|
888
871
|
}
|
|
889
|
-
clientToolsToAgUiTools() {
|
|
890
|
-
if (!this.config.clientTools) return [];
|
|
891
|
-
return Object.entries(this.config.clientTools).map(([name, def]) => {
|
|
892
|
-
const metadata = {};
|
|
893
|
-
if (def.selection) {
|
|
894
|
-
metadata.mcpstack = { selection: def.selection };
|
|
895
|
-
metadata["x-mcpstack-selection"] = def.selection;
|
|
896
|
-
}
|
|
897
|
-
return {
|
|
898
|
-
name,
|
|
899
|
-
description: def.description,
|
|
900
|
-
parameters: parametersToJsonSchema(def.parameters),
|
|
901
|
-
metadata: Object.keys(metadata).length > 0 ? metadata : void 0
|
|
902
|
-
};
|
|
903
|
-
});
|
|
904
|
-
}
|
|
905
|
-
buildAgUiContext() {
|
|
906
|
-
if (!this.config.context) return [];
|
|
907
|
-
return Object.entries(this.config.context).filter(([, value]) => value != null).map(([key, value]) => ({
|
|
908
|
-
description: key,
|
|
909
|
-
value: typeof value === "string" ? value : JSON.stringify(value)
|
|
910
|
-
}));
|
|
911
|
-
}
|
|
912
|
-
buildAgUiForwardedProps() {
|
|
913
|
-
const externalUser = this.buildExternalUserContext();
|
|
914
|
-
const mcpstack = {
|
|
915
|
-
conversationId: this.conversationId ?? void 0,
|
|
916
|
-
externalUserId: this.resolveExternalUserId(),
|
|
917
|
-
context: this.config.context
|
|
918
|
-
};
|
|
919
|
-
if (externalUser) {
|
|
920
|
-
mcpstack.externalUser = externalUser;
|
|
921
|
-
}
|
|
922
|
-
return { mcpstack };
|
|
923
|
-
}
|
|
924
|
-
buildAgUiUserRunInput(message) {
|
|
925
|
-
return {
|
|
926
|
-
threadId: this.conversationId ?? `thread_${crypto.randomUUID()}`,
|
|
927
|
-
runId: `run_${crypto.randomUUID()}`,
|
|
928
|
-
state: this.config.context ?? {},
|
|
929
|
-
messages: [{ id: crypto.randomUUID(), role: "user", content: message }],
|
|
930
|
-
tools: this.clientToolsToAgUiTools(),
|
|
931
|
-
context: this.buildAgUiContext(),
|
|
932
|
-
forwardedProps: this.buildAgUiForwardedProps()
|
|
933
|
-
};
|
|
934
|
-
}
|
|
935
|
-
buildAgUiToolResultRunInput(toolCall, content, error) {
|
|
936
|
-
return {
|
|
937
|
-
threadId: this.conversationId ?? `thread_${crypto.randomUUID()}`,
|
|
938
|
-
runId: `run_${crypto.randomUUID()}`,
|
|
939
|
-
state: this.config.context ?? {},
|
|
940
|
-
messages: [{
|
|
941
|
-
id: crypto.randomUUID(),
|
|
942
|
-
role: "tool",
|
|
943
|
-
toolCallId: toolCall.toolCallId,
|
|
944
|
-
content,
|
|
945
|
-
error
|
|
946
|
-
}],
|
|
947
|
-
tools: this.clientToolsToAgUiTools(),
|
|
948
|
-
context: this.buildAgUiContext(),
|
|
949
|
-
forwardedProps: this.buildAgUiForwardedProps()
|
|
950
|
-
};
|
|
951
|
-
}
|
|
952
872
|
resolveExternalUserId() {
|
|
953
873
|
const hostIdentity = this.config.embeddedAuth?.hostIdentity;
|
|
954
874
|
return this.config.externalUserId ?? hostIdentity?.subject ?? hostIdentity?.email ?? void 0;
|
|
@@ -2191,44 +2111,109 @@ var McpStackAgent = class {
|
|
|
2191
2111
|
// ================================================================
|
|
2192
2112
|
/**
|
|
2193
2113
|
* The core orchestration loop:
|
|
2194
|
-
* 1. Send message to
|
|
2195
|
-
* 2. Stream
|
|
2196
|
-
* 3. If
|
|
2197
|
-
* 4.
|
|
2114
|
+
* 1. Send message to chat API
|
|
2115
|
+
* 2. Stream response
|
|
2116
|
+
* 3. If tool_call → execute tool via MCP → send result → continue
|
|
2117
|
+
* 4. If message_end → done
|
|
2198
2118
|
*/
|
|
2199
2119
|
async runChatLoop(message) {
|
|
2200
2120
|
this.abortController = new AbortController();
|
|
2201
2121
|
this.emit("thinking", true);
|
|
2202
|
-
|
|
2122
|
+
const chatBody = {
|
|
2123
|
+
agentId: this.config.agentId,
|
|
2124
|
+
conversationId: this.conversationId,
|
|
2125
|
+
message,
|
|
2126
|
+
externalUserId: this.resolveExternalUserId(),
|
|
2127
|
+
context: this.config.context
|
|
2128
|
+
};
|
|
2129
|
+
const externalUser = this.buildExternalUserContext();
|
|
2130
|
+
if (externalUser) {
|
|
2131
|
+
chatBody.externalUser = externalUser;
|
|
2132
|
+
}
|
|
2133
|
+
const clientToolSchemas = this.clientToolsToSchemas();
|
|
2134
|
+
if (clientToolSchemas.length > 0) {
|
|
2135
|
+
chatBody.clientTools = clientToolSchemas;
|
|
2136
|
+
}
|
|
2137
|
+
let response = await this.callChatApi(chatBody, "chat");
|
|
2203
2138
|
while (true) {
|
|
2204
|
-
const result = await this.
|
|
2205
|
-
if (result.type === "
|
|
2139
|
+
const result = await this.processSseStream(response);
|
|
2140
|
+
if (result.type === "message_end") {
|
|
2206
2141
|
break;
|
|
2207
2142
|
}
|
|
2208
|
-
if (result.type === "
|
|
2143
|
+
if (result.type === "tool_call") {
|
|
2209
2144
|
const toolCall = result.data;
|
|
2210
2145
|
const startTime = Date.now();
|
|
2211
2146
|
try {
|
|
2212
|
-
const toolResult = await this.
|
|
2147
|
+
const toolResult = await this.executeTool(toolCall);
|
|
2213
2148
|
const duration = Date.now() - startTime;
|
|
2214
|
-
this.
|
|
2149
|
+
const toolCallMsg = this.messages.find(
|
|
2150
|
+
(m) => m.role === "tool_call" && m.toolCallId === toolCall.toolCallId
|
|
2151
|
+
);
|
|
2152
|
+
if (toolCallMsg) {
|
|
2153
|
+
toolCallMsg.toolCallStatus = "completed";
|
|
2154
|
+
toolCallMsg.toolCallDuration = duration;
|
|
2155
|
+
toolCallMsg.toolResult = typeof toolResult === "string" ? toolResult : JSON.stringify(toolResult);
|
|
2156
|
+
}
|
|
2157
|
+
this.emit("tool_result", { toolCallId: toolCall.toolCallId, result: toolResult, duration });
|
|
2158
|
+
const toolResultMsg = {
|
|
2159
|
+
id: crypto.randomUUID(),
|
|
2160
|
+
role: "tool_result",
|
|
2161
|
+
content: typeof toolResult === "string" ? toolResult : JSON.stringify(toolResult),
|
|
2162
|
+
toolCallId: toolCall.toolCallId,
|
|
2163
|
+
toolName: toolCall.toolName,
|
|
2164
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
2165
|
+
};
|
|
2166
|
+
this.messages.push(toolResultMsg);
|
|
2215
2167
|
this.emit("thinking", true);
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2168
|
+
const toolResultBody = {
|
|
2169
|
+
conversationId: this.conversationId,
|
|
2170
|
+
toolCallId: toolCall.toolCallId,
|
|
2171
|
+
result: toolResult,
|
|
2172
|
+
durationMs: duration,
|
|
2173
|
+
context: this.config.context
|
|
2174
|
+
};
|
|
2175
|
+
const clientToolSchemas2 = this.clientToolsToSchemas();
|
|
2176
|
+
if (clientToolSchemas2.length > 0) {
|
|
2177
|
+
toolResultBody.clientTools = clientToolSchemas2;
|
|
2178
|
+
}
|
|
2179
|
+
response = await this.callChatApi(toolResultBody, "chat/tool-result");
|
|
2220
2180
|
} catch (err) {
|
|
2221
2181
|
const duration = Date.now() - startTime;
|
|
2222
2182
|
const errorMsg = err instanceof Error ? err.message : "Tool execution failed";
|
|
2183
|
+
const toolCallMsg = this.messages.find(
|
|
2184
|
+
(m) => m.role === "tool_call" && m.toolCallId === toolCall.toolCallId
|
|
2185
|
+
);
|
|
2186
|
+
if (toolCallMsg) {
|
|
2187
|
+
toolCallMsg.toolCallStatus = "error";
|
|
2188
|
+
toolCallMsg.toolCallDuration = duration;
|
|
2189
|
+
toolCallMsg.toolError = errorMsg;
|
|
2190
|
+
}
|
|
2191
|
+
this.emit("tool_error", { toolCallId: toolCall.toolCallId, error: errorMsg, duration });
|
|
2223
2192
|
const errorResult = `Error: ${errorMsg}`;
|
|
2224
|
-
|
|
2193
|
+
const toolResultMsg = {
|
|
2194
|
+
id: crypto.randomUUID(),
|
|
2195
|
+
role: "tool_result",
|
|
2196
|
+
content: errorResult,
|
|
2197
|
+
toolCallId: toolCall.toolCallId,
|
|
2198
|
+
toolName: toolCall.toolName,
|
|
2199
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
2200
|
+
};
|
|
2201
|
+
this.messages.push(toolResultMsg);
|
|
2225
2202
|
this.emit("thinking", true);
|
|
2226
2203
|
try {
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2204
|
+
const toolResultBody = {
|
|
2205
|
+
conversationId: this.conversationId,
|
|
2206
|
+
toolCallId: toolCall.toolCallId,
|
|
2207
|
+
result: errorResult,
|
|
2208
|
+
isError: true,
|
|
2209
|
+
durationMs: duration,
|
|
2210
|
+
context: this.config.context
|
|
2211
|
+
};
|
|
2212
|
+
const clientToolSchemas2 = this.clientToolsToSchemas();
|
|
2213
|
+
if (clientToolSchemas2.length > 0) {
|
|
2214
|
+
toolResultBody.clientTools = clientToolSchemas2;
|
|
2215
|
+
}
|
|
2216
|
+
response = await this.callChatApi(toolResultBody, "chat/tool-result");
|
|
2232
2217
|
} catch {
|
|
2233
2218
|
this.emit("error", { code: "tool_error", message: errorMsg });
|
|
2234
2219
|
break;
|
|
@@ -2240,35 +2225,17 @@ var McpStackAgent = class {
|
|
|
2240
2225
|
}
|
|
2241
2226
|
}
|
|
2242
2227
|
}
|
|
2243
|
-
async
|
|
2244
|
-
const def = this.config.clientTools?.[toolCall.toolName];
|
|
2245
|
-
if (!def) {
|
|
2246
|
-
throw new Error(`Unknown client tool: ${toolCall.toolName}`);
|
|
2247
|
-
}
|
|
2248
|
-
return def.execute(toolCall.arguments ?? {});
|
|
2249
|
-
}
|
|
2250
|
-
async callAgUiApi(input) {
|
|
2228
|
+
async callChatApi(body, endpoint) {
|
|
2251
2229
|
const token = await this.resolveAuthToken();
|
|
2252
|
-
const headers = {
|
|
2253
|
-
"Content-Type": "application/json",
|
|
2254
|
-
Accept: "text/event-stream",
|
|
2255
|
-
Authorization: `Bearer ${token}`
|
|
2256
|
-
};
|
|
2257
|
-
if (this.config.auth?.mode === "app-token") {
|
|
2258
|
-
const appToken = await this.config.auth.getToken();
|
|
2259
|
-
if (appToken?.trim()) {
|
|
2260
|
-
headers["X-MCPStack-App-Token"] = appToken.trim();
|
|
2261
|
-
}
|
|
2262
|
-
if (this.config.auth.appId?.trim()) {
|
|
2263
|
-
headers["X-MCPStack-Embedded-App-Id"] = this.config.auth.appId.trim();
|
|
2264
|
-
}
|
|
2265
|
-
}
|
|
2266
2230
|
const response = await fetch(
|
|
2267
|
-
`${this.config.agentServiceUrl}/api/v1
|
|
2231
|
+
`${this.config.agentServiceUrl}/api/v1/${endpoint}`,
|
|
2268
2232
|
{
|
|
2269
2233
|
method: "POST",
|
|
2270
|
-
headers
|
|
2271
|
-
|
|
2234
|
+
headers: {
|
|
2235
|
+
"Content-Type": "application/json",
|
|
2236
|
+
Authorization: `Bearer ${token}`
|
|
2237
|
+
},
|
|
2238
|
+
body: JSON.stringify(body),
|
|
2272
2239
|
signal: this.abortController?.signal
|
|
2273
2240
|
}
|
|
2274
2241
|
);
|
|
@@ -2277,281 +2244,6 @@ var McpStackAgent = class {
|
|
|
2277
2244
|
}
|
|
2278
2245
|
return response;
|
|
2279
2246
|
}
|
|
2280
|
-
async processAgUiStream(response) {
|
|
2281
|
-
let assistantContent = "";
|
|
2282
|
-
let emittedThinkingFalse = false;
|
|
2283
|
-
let pendingFrontendTool = null;
|
|
2284
|
-
const toolCalls = /* @__PURE__ */ new Map();
|
|
2285
|
-
const stopThinking = () => {
|
|
2286
|
-
if (!emittedThinkingFalse) {
|
|
2287
|
-
this.emit("thinking", false);
|
|
2288
|
-
emittedThinkingFalse = true;
|
|
2289
|
-
}
|
|
2290
|
-
};
|
|
2291
|
-
const flushAssistantMessage = () => {
|
|
2292
|
-
if (!assistantContent) {
|
|
2293
|
-
return;
|
|
2294
|
-
}
|
|
2295
|
-
const assistantMsg = {
|
|
2296
|
-
id: crypto.randomUUID(),
|
|
2297
|
-
role: "assistant",
|
|
2298
|
-
content: assistantContent,
|
|
2299
|
-
timestamp: /* @__PURE__ */ new Date()
|
|
2300
|
-
};
|
|
2301
|
-
this.messages.push(assistantMsg);
|
|
2302
|
-
this.emit("message", assistantMsg);
|
|
2303
|
-
assistantContent = "";
|
|
2304
|
-
};
|
|
2305
|
-
for await (const event of parseSseStream(response, this.abortController?.signal)) {
|
|
2306
|
-
const data = event.data;
|
|
2307
|
-
switch (event.type) {
|
|
2308
|
-
case AG_UI_EVENT.RUN_STARTED: {
|
|
2309
|
-
const threadId = this.getStringField(data, "threadId");
|
|
2310
|
-
if (threadId) {
|
|
2311
|
-
this.conversationId = threadId;
|
|
2312
|
-
}
|
|
2313
|
-
break;
|
|
2314
|
-
}
|
|
2315
|
-
case AG_UI_EVENT.STATE_SNAPSHOT: {
|
|
2316
|
-
const snapshot = this.getRecordField(data, "snapshot");
|
|
2317
|
-
const conversationId = snapshot ? this.getStringField(snapshot, "conversationId") : void 0;
|
|
2318
|
-
if (conversationId) {
|
|
2319
|
-
this.conversationId = conversationId;
|
|
2320
|
-
}
|
|
2321
|
-
const budget = snapshot?.budget;
|
|
2322
|
-
if (budget && typeof budget === "object") {
|
|
2323
|
-
this.budgetSnapshot = budget;
|
|
2324
|
-
this.emit("budget_snapshot", this.budgetSnapshot);
|
|
2325
|
-
}
|
|
2326
|
-
break;
|
|
2327
|
-
}
|
|
2328
|
-
case AG_UI_EVENT.TEXT_MESSAGE_CONTENT: {
|
|
2329
|
-
stopThinking();
|
|
2330
|
-
const delta = this.getStringField(data, "delta") ?? "";
|
|
2331
|
-
assistantContent += delta;
|
|
2332
|
-
this.emit("content_delta", { text: delta });
|
|
2333
|
-
break;
|
|
2334
|
-
}
|
|
2335
|
-
case AG_UI_EVENT.TOOL_CALL_START: {
|
|
2336
|
-
stopThinking();
|
|
2337
|
-
const toolCallId = this.getStringField(data, "toolCallId");
|
|
2338
|
-
const toolName = this.getStringField(data, "toolCallName");
|
|
2339
|
-
if (!toolCallId || !toolName) {
|
|
2340
|
-
break;
|
|
2341
|
-
}
|
|
2342
|
-
const mcpstack = this.getRecordField(data, "mcpstack");
|
|
2343
|
-
const sourceValue = mcpstack ? this.getStringField(mcpstack, "source") : void 0;
|
|
2344
|
-
const source = sourceValue === "mcp" ? "mcp" : sourceValue === "client" ? "client" : void 0;
|
|
2345
|
-
toolCalls.set(toolCallId, {
|
|
2346
|
-
toolCallId,
|
|
2347
|
-
toolName,
|
|
2348
|
-
toolLabel: mcpstack ? this.getStringField(mcpstack, "label") : void 0,
|
|
2349
|
-
mcpServerName: mcpstack ? this.getStringField(mcpstack, "mcpServerName") : void 0,
|
|
2350
|
-
source,
|
|
2351
|
-
argumentsJson: "",
|
|
2352
|
-
startedAt: Date.now()
|
|
2353
|
-
});
|
|
2354
|
-
break;
|
|
2355
|
-
}
|
|
2356
|
-
case AG_UI_EVENT.TOOL_CALL_ARGS: {
|
|
2357
|
-
const toolCallId = this.getStringField(data, "toolCallId");
|
|
2358
|
-
const state = toolCallId ? toolCalls.get(toolCallId) : void 0;
|
|
2359
|
-
if (state) {
|
|
2360
|
-
state.argumentsJson += this.getStringField(data, "delta") ?? "";
|
|
2361
|
-
}
|
|
2362
|
-
break;
|
|
2363
|
-
}
|
|
2364
|
-
case AG_UI_EVENT.TOOL_CALL_END: {
|
|
2365
|
-
const toolCallId = this.getStringField(data, "toolCallId");
|
|
2366
|
-
const state = toolCallId ? toolCalls.get(toolCallId) : void 0;
|
|
2367
|
-
if (!state) {
|
|
2368
|
-
break;
|
|
2369
|
-
}
|
|
2370
|
-
flushAssistantMessage();
|
|
2371
|
-
const toolCall = {
|
|
2372
|
-
toolCallId: state.toolCallId,
|
|
2373
|
-
toolName: state.toolName,
|
|
2374
|
-
toolLabel: state.toolLabel,
|
|
2375
|
-
mcpServerName: state.mcpServerName,
|
|
2376
|
-
source: state.source,
|
|
2377
|
-
arguments: this.parseToolArguments(state.argumentsJson)
|
|
2378
|
-
};
|
|
2379
|
-
const toolCallMsg = {
|
|
2380
|
-
id: crypto.randomUUID(),
|
|
2381
|
-
role: "tool_call",
|
|
2382
|
-
content: `Calling ${toolCall.toolLabel ?? toolCall.toolName}...`,
|
|
2383
|
-
toolName: toolCall.toolName,
|
|
2384
|
-
toolLabel: toolCall.toolLabel,
|
|
2385
|
-
toolCallId: toolCall.toolCallId,
|
|
2386
|
-
timestamp: /* @__PURE__ */ new Date(),
|
|
2387
|
-
toolCallStatus: "calling",
|
|
2388
|
-
toolCallStartTime: state.startedAt
|
|
2389
|
-
};
|
|
2390
|
-
this.messages.push(toolCallMsg);
|
|
2391
|
-
this.emit("tool_call", toolCall);
|
|
2392
|
-
if (state.source !== "mcp") {
|
|
2393
|
-
pendingFrontendTool = toolCall;
|
|
2394
|
-
}
|
|
2395
|
-
break;
|
|
2396
|
-
}
|
|
2397
|
-
case AG_UI_EVENT.TOOL_CALL_RESULT: {
|
|
2398
|
-
const toolCallId = this.getStringField(data, "toolCallId");
|
|
2399
|
-
const state = toolCallId ? toolCalls.get(toolCallId) : void 0;
|
|
2400
|
-
if (!toolCallId) {
|
|
2401
|
-
break;
|
|
2402
|
-
}
|
|
2403
|
-
const content = this.getStringField(data, "content") ?? "";
|
|
2404
|
-
const toolCall = {
|
|
2405
|
-
toolCallId,
|
|
2406
|
-
toolName: state?.toolName ?? this.getStringField(data, "toolCallName") ?? toolCallId,
|
|
2407
|
-
toolLabel: state?.toolLabel,
|
|
2408
|
-
mcpServerName: state?.mcpServerName,
|
|
2409
|
-
source: state?.source,
|
|
2410
|
-
arguments: state ? this.parseToolArguments(state.argumentsJson) : {}
|
|
2411
|
-
};
|
|
2412
|
-
const duration = state ? Date.now() - state.startedAt : 0;
|
|
2413
|
-
this.recordToolResult(toolCall, this.parseToolContent(content), duration);
|
|
2414
|
-
if (pendingFrontendTool?.toolCallId === toolCallId) {
|
|
2415
|
-
pendingFrontendTool = null;
|
|
2416
|
-
}
|
|
2417
|
-
break;
|
|
2418
|
-
}
|
|
2419
|
-
case AG_UI_EVENT.CUSTOM: {
|
|
2420
|
-
const name = this.getStringField(data, "name");
|
|
2421
|
-
if (name === "mcpstack.budget_snapshot") {
|
|
2422
|
-
const value = data.value;
|
|
2423
|
-
if (value && typeof value === "object") {
|
|
2424
|
-
this.budgetSnapshot = value;
|
|
2425
|
-
this.emit("budget_snapshot", this.budgetSnapshot);
|
|
2426
|
-
}
|
|
2427
|
-
}
|
|
2428
|
-
break;
|
|
2429
|
-
}
|
|
2430
|
-
case AG_UI_EVENT.RUN_FINISHED: {
|
|
2431
|
-
const result = this.getRecordField(data, "result");
|
|
2432
|
-
const conversationId = result ? this.getStringField(result, "conversationId") : void 0;
|
|
2433
|
-
if (conversationId) {
|
|
2434
|
-
this.conversationId = conversationId;
|
|
2435
|
-
}
|
|
2436
|
-
if (pendingFrontendTool) {
|
|
2437
|
-
return { type: "frontend_tool", data: pendingFrontendTool };
|
|
2438
|
-
}
|
|
2439
|
-
flushAssistantMessage();
|
|
2440
|
-
const messageEnd2 = {
|
|
2441
|
-
inputTokens: this.getNumberField(result, "inputTokens") ?? 0,
|
|
2442
|
-
outputTokens: this.getNumberField(result, "outputTokens") ?? 0,
|
|
2443
|
-
toolCalls: this.getNumberField(result, "toolCalls") ?? toolCalls.size
|
|
2444
|
-
};
|
|
2445
|
-
this.emit("message_end", messageEnd2);
|
|
2446
|
-
return { type: "done" };
|
|
2447
|
-
}
|
|
2448
|
-
case AG_UI_EVENT.RUN_ERROR: {
|
|
2449
|
-
const error = {
|
|
2450
|
-
code: this.getStringField(data, "code") ?? "run_error",
|
|
2451
|
-
message: this.getStringField(data, "message") ?? "Agent run failed."
|
|
2452
|
-
};
|
|
2453
|
-
const errorMsg = {
|
|
2454
|
-
id: crypto.randomUUID(),
|
|
2455
|
-
role: "error",
|
|
2456
|
-
content: error.message,
|
|
2457
|
-
timestamp: /* @__PURE__ */ new Date(),
|
|
2458
|
-
errorCode: error.code
|
|
2459
|
-
};
|
|
2460
|
-
this.messages.push(errorMsg);
|
|
2461
|
-
this.emit("message", errorMsg);
|
|
2462
|
-
this.emit("error", error);
|
|
2463
|
-
return { type: "error", data: error };
|
|
2464
|
-
}
|
|
2465
|
-
}
|
|
2466
|
-
}
|
|
2467
|
-
flushAssistantMessage();
|
|
2468
|
-
const messageEnd = {
|
|
2469
|
-
inputTokens: 0,
|
|
2470
|
-
outputTokens: 0,
|
|
2471
|
-
toolCalls: toolCalls.size
|
|
2472
|
-
};
|
|
2473
|
-
this.emit("message_end", messageEnd);
|
|
2474
|
-
return { type: "done" };
|
|
2475
|
-
}
|
|
2476
|
-
recordToolResult(toolCall, result, duration) {
|
|
2477
|
-
const toolCallMsg = this.messages.find(
|
|
2478
|
-
(m) => m.role === "tool_call" && m.toolCallId === toolCall.toolCallId
|
|
2479
|
-
);
|
|
2480
|
-
if (toolCallMsg) {
|
|
2481
|
-
toolCallMsg.toolCallStatus = "completed";
|
|
2482
|
-
toolCallMsg.toolCallDuration = duration;
|
|
2483
|
-
toolCallMsg.toolResult = this.serializeToolContent(result);
|
|
2484
|
-
}
|
|
2485
|
-
this.emit("tool_result", { toolCallId: toolCall.toolCallId, result, duration });
|
|
2486
|
-
const toolResultMsg = {
|
|
2487
|
-
id: crypto.randomUUID(),
|
|
2488
|
-
role: "tool_result",
|
|
2489
|
-
content: this.serializeToolContent(result),
|
|
2490
|
-
toolCallId: toolCall.toolCallId,
|
|
2491
|
-
toolName: toolCall.toolName,
|
|
2492
|
-
timestamp: /* @__PURE__ */ new Date()
|
|
2493
|
-
};
|
|
2494
|
-
this.messages.push(toolResultMsg);
|
|
2495
|
-
}
|
|
2496
|
-
recordToolError(toolCall, error, resultContent, duration) {
|
|
2497
|
-
const toolCallMsg = this.messages.find(
|
|
2498
|
-
(m) => m.role === "tool_call" && m.toolCallId === toolCall.toolCallId
|
|
2499
|
-
);
|
|
2500
|
-
if (toolCallMsg) {
|
|
2501
|
-
toolCallMsg.toolCallStatus = "error";
|
|
2502
|
-
toolCallMsg.toolCallDuration = duration;
|
|
2503
|
-
toolCallMsg.toolError = error;
|
|
2504
|
-
}
|
|
2505
|
-
this.emit("tool_error", { toolCallId: toolCall.toolCallId, error, duration });
|
|
2506
|
-
const toolResultMsg = {
|
|
2507
|
-
id: crypto.randomUUID(),
|
|
2508
|
-
role: "tool_result",
|
|
2509
|
-
content: resultContent,
|
|
2510
|
-
toolCallId: toolCall.toolCallId,
|
|
2511
|
-
toolName: toolCall.toolName,
|
|
2512
|
-
timestamp: /* @__PURE__ */ new Date()
|
|
2513
|
-
};
|
|
2514
|
-
this.messages.push(toolResultMsg);
|
|
2515
|
-
}
|
|
2516
|
-
serializeToolContent(result) {
|
|
2517
|
-
if (result == null) {
|
|
2518
|
-
return "";
|
|
2519
|
-
}
|
|
2520
|
-
return typeof result === "string" ? result : JSON.stringify(result);
|
|
2521
|
-
}
|
|
2522
|
-
parseToolContent(content) {
|
|
2523
|
-
if (!content) {
|
|
2524
|
-
return "";
|
|
2525
|
-
}
|
|
2526
|
-
try {
|
|
2527
|
-
return JSON.parse(content);
|
|
2528
|
-
} catch {
|
|
2529
|
-
return content;
|
|
2530
|
-
}
|
|
2531
|
-
}
|
|
2532
|
-
parseToolArguments(argumentsJson) {
|
|
2533
|
-
if (!argumentsJson.trim()) {
|
|
2534
|
-
return {};
|
|
2535
|
-
}
|
|
2536
|
-
try {
|
|
2537
|
-
const parsed = JSON.parse(argumentsJson);
|
|
2538
|
-
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
2539
|
-
} catch {
|
|
2540
|
-
return {};
|
|
2541
|
-
}
|
|
2542
|
-
}
|
|
2543
|
-
getRecordField(record, key) {
|
|
2544
|
-
const value = record?.[key];
|
|
2545
|
-
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
2546
|
-
}
|
|
2547
|
-
getStringField(record, key) {
|
|
2548
|
-
const value = record?.[key];
|
|
2549
|
-
return typeof value === "string" && value ? value : void 0;
|
|
2550
|
-
}
|
|
2551
|
-
getNumberField(record, key) {
|
|
2552
|
-
const value = record?.[key];
|
|
2553
|
-
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
2554
|
-
}
|
|
2555
2247
|
async fetchConversationMessages(conversationId, cursor, pageSize = 50) {
|
|
2556
2248
|
const token = await this.resolveAuthToken();
|
|
2557
2249
|
const params = new URLSearchParams();
|
|
@@ -2599,7 +2291,7 @@ var McpStackAgent = class {
|
|
|
2599
2291
|
};
|
|
2600
2292
|
}
|
|
2601
2293
|
/**
|
|
2602
|
-
* Process
|
|
2294
|
+
* Process an SSE stream from the chat API.
|
|
2603
2295
|
* Returns when the stream ends (either message_end or tool_call).
|
|
2604
2296
|
*/
|
|
2605
2297
|
async processSseStream(response) {
|