@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
|
@@ -47,15 +47,12 @@ function* parseEventBlocks(input) {
|
|
|
47
47
|
dataLines.push("");
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
|
-
if (dataLines.length === 0) {
|
|
50
|
+
if (!eventType || dataLines.length === 0) {
|
|
51
51
|
continue;
|
|
52
52
|
}
|
|
53
53
|
try {
|
|
54
54
|
const parsed = JSON.parse(dataLines.join("\n"));
|
|
55
|
-
|
|
56
|
-
const resolvedType = eventType || parsedType;
|
|
57
|
-
if (!resolvedType) continue;
|
|
58
|
-
yield { type: resolvedType, data: parsed };
|
|
55
|
+
yield { type: eventType, data: parsed };
|
|
59
56
|
} catch {
|
|
60
57
|
}
|
|
61
58
|
}
|
|
@@ -339,20 +336,6 @@ function buildScopedOAuthTokenStorageKey(cacheKey, authSessionKey) {
|
|
|
339
336
|
}
|
|
340
337
|
|
|
341
338
|
// src/core/EmcyAgent.ts
|
|
342
|
-
var AG_UI_EVENT = {
|
|
343
|
-
RUN_STARTED: "RUN_STARTED",
|
|
344
|
-
RUN_FINISHED: "RUN_FINISHED",
|
|
345
|
-
RUN_ERROR: "RUN_ERROR",
|
|
346
|
-
TEXT_MESSAGE_START: "TEXT_MESSAGE_START",
|
|
347
|
-
TEXT_MESSAGE_CONTENT: "TEXT_MESSAGE_CONTENT",
|
|
348
|
-
TEXT_MESSAGE_END: "TEXT_MESSAGE_END",
|
|
349
|
-
TOOL_CALL_START: "TOOL_CALL_START",
|
|
350
|
-
TOOL_CALL_ARGS: "TOOL_CALL_ARGS",
|
|
351
|
-
TOOL_CALL_END: "TOOL_CALL_END",
|
|
352
|
-
TOOL_CALL_RESULT: "TOOL_CALL_RESULT",
|
|
353
|
-
STATE_SNAPSHOT: "STATE_SNAPSHOT",
|
|
354
|
-
CUSTOM: "CUSTOM"
|
|
355
|
-
};
|
|
356
339
|
var DEFAULT_MCP_PROTOCOL_VERSION = "2025-11-25";
|
|
357
340
|
var DEFAULT_LOCAL_PUBLIC_APP_PORT = "3100";
|
|
358
341
|
var DEFAULT_OAUTH_CALLBACK_URL = "https://mcpstack.com/oauth/callback";
|
|
@@ -846,69 +829,6 @@ var McpStackAgent = class {
|
|
|
846
829
|
selection: def.selection
|
|
847
830
|
}));
|
|
848
831
|
}
|
|
849
|
-
clientToolsToAgUiTools() {
|
|
850
|
-
if (!this.config.clientTools) return [];
|
|
851
|
-
return Object.entries(this.config.clientTools).map(([name, def]) => {
|
|
852
|
-
const metadata = {};
|
|
853
|
-
if (def.selection) {
|
|
854
|
-
metadata.mcpstack = { selection: def.selection };
|
|
855
|
-
metadata["x-mcpstack-selection"] = def.selection;
|
|
856
|
-
}
|
|
857
|
-
return {
|
|
858
|
-
name,
|
|
859
|
-
description: def.description,
|
|
860
|
-
parameters: parametersToJsonSchema(def.parameters),
|
|
861
|
-
metadata: Object.keys(metadata).length > 0 ? metadata : void 0
|
|
862
|
-
};
|
|
863
|
-
});
|
|
864
|
-
}
|
|
865
|
-
buildAgUiContext() {
|
|
866
|
-
if (!this.config.context) return [];
|
|
867
|
-
return Object.entries(this.config.context).filter(([, value]) => value != null).map(([key, value]) => ({
|
|
868
|
-
description: key,
|
|
869
|
-
value: typeof value === "string" ? value : JSON.stringify(value)
|
|
870
|
-
}));
|
|
871
|
-
}
|
|
872
|
-
buildAgUiForwardedProps() {
|
|
873
|
-
const externalUser = this.buildExternalUserContext();
|
|
874
|
-
const mcpstack = {
|
|
875
|
-
conversationId: this.conversationId ?? void 0,
|
|
876
|
-
externalUserId: this.resolveExternalUserId(),
|
|
877
|
-
context: this.config.context
|
|
878
|
-
};
|
|
879
|
-
if (externalUser) {
|
|
880
|
-
mcpstack.externalUser = externalUser;
|
|
881
|
-
}
|
|
882
|
-
return { mcpstack };
|
|
883
|
-
}
|
|
884
|
-
buildAgUiUserRunInput(message) {
|
|
885
|
-
return {
|
|
886
|
-
threadId: this.conversationId ?? `thread_${crypto.randomUUID()}`,
|
|
887
|
-
runId: `run_${crypto.randomUUID()}`,
|
|
888
|
-
state: this.config.context ?? {},
|
|
889
|
-
messages: [{ id: crypto.randomUUID(), role: "user", content: message }],
|
|
890
|
-
tools: this.clientToolsToAgUiTools(),
|
|
891
|
-
context: this.buildAgUiContext(),
|
|
892
|
-
forwardedProps: this.buildAgUiForwardedProps()
|
|
893
|
-
};
|
|
894
|
-
}
|
|
895
|
-
buildAgUiToolResultRunInput(toolCall, content, error) {
|
|
896
|
-
return {
|
|
897
|
-
threadId: this.conversationId ?? `thread_${crypto.randomUUID()}`,
|
|
898
|
-
runId: `run_${crypto.randomUUID()}`,
|
|
899
|
-
state: this.config.context ?? {},
|
|
900
|
-
messages: [{
|
|
901
|
-
id: crypto.randomUUID(),
|
|
902
|
-
role: "tool",
|
|
903
|
-
toolCallId: toolCall.toolCallId,
|
|
904
|
-
content,
|
|
905
|
-
error
|
|
906
|
-
}],
|
|
907
|
-
tools: this.clientToolsToAgUiTools(),
|
|
908
|
-
context: this.buildAgUiContext(),
|
|
909
|
-
forwardedProps: this.buildAgUiForwardedProps()
|
|
910
|
-
};
|
|
911
|
-
}
|
|
912
832
|
resolveExternalUserId() {
|
|
913
833
|
const hostIdentity = this.config.embeddedAuth?.hostIdentity;
|
|
914
834
|
return this.config.externalUserId ?? hostIdentity?.subject ?? hostIdentity?.email ?? void 0;
|
|
@@ -2151,44 +2071,109 @@ var McpStackAgent = class {
|
|
|
2151
2071
|
// ================================================================
|
|
2152
2072
|
/**
|
|
2153
2073
|
* The core orchestration loop:
|
|
2154
|
-
* 1. Send message to
|
|
2155
|
-
* 2. Stream
|
|
2156
|
-
* 3. If
|
|
2157
|
-
* 4.
|
|
2074
|
+
* 1. Send message to chat API
|
|
2075
|
+
* 2. Stream response
|
|
2076
|
+
* 3. If tool_call → execute tool via MCP → send result → continue
|
|
2077
|
+
* 4. If message_end → done
|
|
2158
2078
|
*/
|
|
2159
2079
|
async runChatLoop(message) {
|
|
2160
2080
|
this.abortController = new AbortController();
|
|
2161
2081
|
this.emit("thinking", true);
|
|
2162
|
-
|
|
2082
|
+
const chatBody = {
|
|
2083
|
+
agentId: this.config.agentId,
|
|
2084
|
+
conversationId: this.conversationId,
|
|
2085
|
+
message,
|
|
2086
|
+
externalUserId: this.resolveExternalUserId(),
|
|
2087
|
+
context: this.config.context
|
|
2088
|
+
};
|
|
2089
|
+
const externalUser = this.buildExternalUserContext();
|
|
2090
|
+
if (externalUser) {
|
|
2091
|
+
chatBody.externalUser = externalUser;
|
|
2092
|
+
}
|
|
2093
|
+
const clientToolSchemas = this.clientToolsToSchemas();
|
|
2094
|
+
if (clientToolSchemas.length > 0) {
|
|
2095
|
+
chatBody.clientTools = clientToolSchemas;
|
|
2096
|
+
}
|
|
2097
|
+
let response = await this.callChatApi(chatBody, "chat");
|
|
2163
2098
|
while (true) {
|
|
2164
|
-
const result = await this.
|
|
2165
|
-
if (result.type === "
|
|
2099
|
+
const result = await this.processSseStream(response);
|
|
2100
|
+
if (result.type === "message_end") {
|
|
2166
2101
|
break;
|
|
2167
2102
|
}
|
|
2168
|
-
if (result.type === "
|
|
2103
|
+
if (result.type === "tool_call") {
|
|
2169
2104
|
const toolCall = result.data;
|
|
2170
2105
|
const startTime = Date.now();
|
|
2171
2106
|
try {
|
|
2172
|
-
const toolResult = await this.
|
|
2107
|
+
const toolResult = await this.executeTool(toolCall);
|
|
2173
2108
|
const duration = Date.now() - startTime;
|
|
2174
|
-
this.
|
|
2109
|
+
const toolCallMsg = this.messages.find(
|
|
2110
|
+
(m) => m.role === "tool_call" && m.toolCallId === toolCall.toolCallId
|
|
2111
|
+
);
|
|
2112
|
+
if (toolCallMsg) {
|
|
2113
|
+
toolCallMsg.toolCallStatus = "completed";
|
|
2114
|
+
toolCallMsg.toolCallDuration = duration;
|
|
2115
|
+
toolCallMsg.toolResult = typeof toolResult === "string" ? toolResult : JSON.stringify(toolResult);
|
|
2116
|
+
}
|
|
2117
|
+
this.emit("tool_result", { toolCallId: toolCall.toolCallId, result: toolResult, duration });
|
|
2118
|
+
const toolResultMsg = {
|
|
2119
|
+
id: crypto.randomUUID(),
|
|
2120
|
+
role: "tool_result",
|
|
2121
|
+
content: typeof toolResult === "string" ? toolResult : JSON.stringify(toolResult),
|
|
2122
|
+
toolCallId: toolCall.toolCallId,
|
|
2123
|
+
toolName: toolCall.toolName,
|
|
2124
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
2125
|
+
};
|
|
2126
|
+
this.messages.push(toolResultMsg);
|
|
2175
2127
|
this.emit("thinking", true);
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2128
|
+
const toolResultBody = {
|
|
2129
|
+
conversationId: this.conversationId,
|
|
2130
|
+
toolCallId: toolCall.toolCallId,
|
|
2131
|
+
result: toolResult,
|
|
2132
|
+
durationMs: duration,
|
|
2133
|
+
context: this.config.context
|
|
2134
|
+
};
|
|
2135
|
+
const clientToolSchemas2 = this.clientToolsToSchemas();
|
|
2136
|
+
if (clientToolSchemas2.length > 0) {
|
|
2137
|
+
toolResultBody.clientTools = clientToolSchemas2;
|
|
2138
|
+
}
|
|
2139
|
+
response = await this.callChatApi(toolResultBody, "chat/tool-result");
|
|
2180
2140
|
} catch (err) {
|
|
2181
2141
|
const duration = Date.now() - startTime;
|
|
2182
2142
|
const errorMsg = err instanceof Error ? err.message : "Tool execution failed";
|
|
2143
|
+
const toolCallMsg = this.messages.find(
|
|
2144
|
+
(m) => m.role === "tool_call" && m.toolCallId === toolCall.toolCallId
|
|
2145
|
+
);
|
|
2146
|
+
if (toolCallMsg) {
|
|
2147
|
+
toolCallMsg.toolCallStatus = "error";
|
|
2148
|
+
toolCallMsg.toolCallDuration = duration;
|
|
2149
|
+
toolCallMsg.toolError = errorMsg;
|
|
2150
|
+
}
|
|
2151
|
+
this.emit("tool_error", { toolCallId: toolCall.toolCallId, error: errorMsg, duration });
|
|
2183
2152
|
const errorResult = `Error: ${errorMsg}`;
|
|
2184
|
-
|
|
2153
|
+
const toolResultMsg = {
|
|
2154
|
+
id: crypto.randomUUID(),
|
|
2155
|
+
role: "tool_result",
|
|
2156
|
+
content: errorResult,
|
|
2157
|
+
toolCallId: toolCall.toolCallId,
|
|
2158
|
+
toolName: toolCall.toolName,
|
|
2159
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
2160
|
+
};
|
|
2161
|
+
this.messages.push(toolResultMsg);
|
|
2185
2162
|
this.emit("thinking", true);
|
|
2186
2163
|
try {
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2164
|
+
const toolResultBody = {
|
|
2165
|
+
conversationId: this.conversationId,
|
|
2166
|
+
toolCallId: toolCall.toolCallId,
|
|
2167
|
+
result: errorResult,
|
|
2168
|
+
isError: true,
|
|
2169
|
+
durationMs: duration,
|
|
2170
|
+
context: this.config.context
|
|
2171
|
+
};
|
|
2172
|
+
const clientToolSchemas2 = this.clientToolsToSchemas();
|
|
2173
|
+
if (clientToolSchemas2.length > 0) {
|
|
2174
|
+
toolResultBody.clientTools = clientToolSchemas2;
|
|
2175
|
+
}
|
|
2176
|
+
response = await this.callChatApi(toolResultBody, "chat/tool-result");
|
|
2192
2177
|
} catch {
|
|
2193
2178
|
this.emit("error", { code: "tool_error", message: errorMsg });
|
|
2194
2179
|
break;
|
|
@@ -2200,35 +2185,17 @@ var McpStackAgent = class {
|
|
|
2200
2185
|
}
|
|
2201
2186
|
}
|
|
2202
2187
|
}
|
|
2203
|
-
async
|
|
2204
|
-
const def = this.config.clientTools?.[toolCall.toolName];
|
|
2205
|
-
if (!def) {
|
|
2206
|
-
throw new Error(`Unknown client tool: ${toolCall.toolName}`);
|
|
2207
|
-
}
|
|
2208
|
-
return def.execute(toolCall.arguments ?? {});
|
|
2209
|
-
}
|
|
2210
|
-
async callAgUiApi(input) {
|
|
2188
|
+
async callChatApi(body, endpoint) {
|
|
2211
2189
|
const token = await this.resolveAuthToken();
|
|
2212
|
-
const headers = {
|
|
2213
|
-
"Content-Type": "application/json",
|
|
2214
|
-
Accept: "text/event-stream",
|
|
2215
|
-
Authorization: `Bearer ${token}`
|
|
2216
|
-
};
|
|
2217
|
-
if (this.config.auth?.mode === "app-token") {
|
|
2218
|
-
const appToken = await this.config.auth.getToken();
|
|
2219
|
-
if (appToken?.trim()) {
|
|
2220
|
-
headers["X-MCPStack-App-Token"] = appToken.trim();
|
|
2221
|
-
}
|
|
2222
|
-
if (this.config.auth.appId?.trim()) {
|
|
2223
|
-
headers["X-MCPStack-Embedded-App-Id"] = this.config.auth.appId.trim();
|
|
2224
|
-
}
|
|
2225
|
-
}
|
|
2226
2190
|
const response = await fetch(
|
|
2227
|
-
`${this.config.agentServiceUrl}/api/v1
|
|
2191
|
+
`${this.config.agentServiceUrl}/api/v1/${endpoint}`,
|
|
2228
2192
|
{
|
|
2229
2193
|
method: "POST",
|
|
2230
|
-
headers
|
|
2231
|
-
|
|
2194
|
+
headers: {
|
|
2195
|
+
"Content-Type": "application/json",
|
|
2196
|
+
Authorization: `Bearer ${token}`
|
|
2197
|
+
},
|
|
2198
|
+
body: JSON.stringify(body),
|
|
2232
2199
|
signal: this.abortController?.signal
|
|
2233
2200
|
}
|
|
2234
2201
|
);
|
|
@@ -2237,281 +2204,6 @@ var McpStackAgent = class {
|
|
|
2237
2204
|
}
|
|
2238
2205
|
return response;
|
|
2239
2206
|
}
|
|
2240
|
-
async processAgUiStream(response) {
|
|
2241
|
-
let assistantContent = "";
|
|
2242
|
-
let emittedThinkingFalse = false;
|
|
2243
|
-
let pendingFrontendTool = null;
|
|
2244
|
-
const toolCalls = /* @__PURE__ */ new Map();
|
|
2245
|
-
const stopThinking = () => {
|
|
2246
|
-
if (!emittedThinkingFalse) {
|
|
2247
|
-
this.emit("thinking", false);
|
|
2248
|
-
emittedThinkingFalse = true;
|
|
2249
|
-
}
|
|
2250
|
-
};
|
|
2251
|
-
const flushAssistantMessage = () => {
|
|
2252
|
-
if (!assistantContent) {
|
|
2253
|
-
return;
|
|
2254
|
-
}
|
|
2255
|
-
const assistantMsg = {
|
|
2256
|
-
id: crypto.randomUUID(),
|
|
2257
|
-
role: "assistant",
|
|
2258
|
-
content: assistantContent,
|
|
2259
|
-
timestamp: /* @__PURE__ */ new Date()
|
|
2260
|
-
};
|
|
2261
|
-
this.messages.push(assistantMsg);
|
|
2262
|
-
this.emit("message", assistantMsg);
|
|
2263
|
-
assistantContent = "";
|
|
2264
|
-
};
|
|
2265
|
-
for await (const event of parseSseStream(response, this.abortController?.signal)) {
|
|
2266
|
-
const data = event.data;
|
|
2267
|
-
switch (event.type) {
|
|
2268
|
-
case AG_UI_EVENT.RUN_STARTED: {
|
|
2269
|
-
const threadId = this.getStringField(data, "threadId");
|
|
2270
|
-
if (threadId) {
|
|
2271
|
-
this.conversationId = threadId;
|
|
2272
|
-
}
|
|
2273
|
-
break;
|
|
2274
|
-
}
|
|
2275
|
-
case AG_UI_EVENT.STATE_SNAPSHOT: {
|
|
2276
|
-
const snapshot = this.getRecordField(data, "snapshot");
|
|
2277
|
-
const conversationId = snapshot ? this.getStringField(snapshot, "conversationId") : void 0;
|
|
2278
|
-
if (conversationId) {
|
|
2279
|
-
this.conversationId = conversationId;
|
|
2280
|
-
}
|
|
2281
|
-
const budget = snapshot?.budget;
|
|
2282
|
-
if (budget && typeof budget === "object") {
|
|
2283
|
-
this.budgetSnapshot = budget;
|
|
2284
|
-
this.emit("budget_snapshot", this.budgetSnapshot);
|
|
2285
|
-
}
|
|
2286
|
-
break;
|
|
2287
|
-
}
|
|
2288
|
-
case AG_UI_EVENT.TEXT_MESSAGE_CONTENT: {
|
|
2289
|
-
stopThinking();
|
|
2290
|
-
const delta = this.getStringField(data, "delta") ?? "";
|
|
2291
|
-
assistantContent += delta;
|
|
2292
|
-
this.emit("content_delta", { text: delta });
|
|
2293
|
-
break;
|
|
2294
|
-
}
|
|
2295
|
-
case AG_UI_EVENT.TOOL_CALL_START: {
|
|
2296
|
-
stopThinking();
|
|
2297
|
-
const toolCallId = this.getStringField(data, "toolCallId");
|
|
2298
|
-
const toolName = this.getStringField(data, "toolCallName");
|
|
2299
|
-
if (!toolCallId || !toolName) {
|
|
2300
|
-
break;
|
|
2301
|
-
}
|
|
2302
|
-
const mcpstack = this.getRecordField(data, "mcpstack");
|
|
2303
|
-
const sourceValue = mcpstack ? this.getStringField(mcpstack, "source") : void 0;
|
|
2304
|
-
const source = sourceValue === "mcp" ? "mcp" : sourceValue === "client" ? "client" : void 0;
|
|
2305
|
-
toolCalls.set(toolCallId, {
|
|
2306
|
-
toolCallId,
|
|
2307
|
-
toolName,
|
|
2308
|
-
toolLabel: mcpstack ? this.getStringField(mcpstack, "label") : void 0,
|
|
2309
|
-
mcpServerName: mcpstack ? this.getStringField(mcpstack, "mcpServerName") : void 0,
|
|
2310
|
-
source,
|
|
2311
|
-
argumentsJson: "",
|
|
2312
|
-
startedAt: Date.now()
|
|
2313
|
-
});
|
|
2314
|
-
break;
|
|
2315
|
-
}
|
|
2316
|
-
case AG_UI_EVENT.TOOL_CALL_ARGS: {
|
|
2317
|
-
const toolCallId = this.getStringField(data, "toolCallId");
|
|
2318
|
-
const state = toolCallId ? toolCalls.get(toolCallId) : void 0;
|
|
2319
|
-
if (state) {
|
|
2320
|
-
state.argumentsJson += this.getStringField(data, "delta") ?? "";
|
|
2321
|
-
}
|
|
2322
|
-
break;
|
|
2323
|
-
}
|
|
2324
|
-
case AG_UI_EVENT.TOOL_CALL_END: {
|
|
2325
|
-
const toolCallId = this.getStringField(data, "toolCallId");
|
|
2326
|
-
const state = toolCallId ? toolCalls.get(toolCallId) : void 0;
|
|
2327
|
-
if (!state) {
|
|
2328
|
-
break;
|
|
2329
|
-
}
|
|
2330
|
-
flushAssistantMessage();
|
|
2331
|
-
const toolCall = {
|
|
2332
|
-
toolCallId: state.toolCallId,
|
|
2333
|
-
toolName: state.toolName,
|
|
2334
|
-
toolLabel: state.toolLabel,
|
|
2335
|
-
mcpServerName: state.mcpServerName,
|
|
2336
|
-
source: state.source,
|
|
2337
|
-
arguments: this.parseToolArguments(state.argumentsJson)
|
|
2338
|
-
};
|
|
2339
|
-
const toolCallMsg = {
|
|
2340
|
-
id: crypto.randomUUID(),
|
|
2341
|
-
role: "tool_call",
|
|
2342
|
-
content: `Calling ${toolCall.toolLabel ?? toolCall.toolName}...`,
|
|
2343
|
-
toolName: toolCall.toolName,
|
|
2344
|
-
toolLabel: toolCall.toolLabel,
|
|
2345
|
-
toolCallId: toolCall.toolCallId,
|
|
2346
|
-
timestamp: /* @__PURE__ */ new Date(),
|
|
2347
|
-
toolCallStatus: "calling",
|
|
2348
|
-
toolCallStartTime: state.startedAt
|
|
2349
|
-
};
|
|
2350
|
-
this.messages.push(toolCallMsg);
|
|
2351
|
-
this.emit("tool_call", toolCall);
|
|
2352
|
-
if (state.source !== "mcp") {
|
|
2353
|
-
pendingFrontendTool = toolCall;
|
|
2354
|
-
}
|
|
2355
|
-
break;
|
|
2356
|
-
}
|
|
2357
|
-
case AG_UI_EVENT.TOOL_CALL_RESULT: {
|
|
2358
|
-
const toolCallId = this.getStringField(data, "toolCallId");
|
|
2359
|
-
const state = toolCallId ? toolCalls.get(toolCallId) : void 0;
|
|
2360
|
-
if (!toolCallId) {
|
|
2361
|
-
break;
|
|
2362
|
-
}
|
|
2363
|
-
const content = this.getStringField(data, "content") ?? "";
|
|
2364
|
-
const toolCall = {
|
|
2365
|
-
toolCallId,
|
|
2366
|
-
toolName: state?.toolName ?? this.getStringField(data, "toolCallName") ?? toolCallId,
|
|
2367
|
-
toolLabel: state?.toolLabel,
|
|
2368
|
-
mcpServerName: state?.mcpServerName,
|
|
2369
|
-
source: state?.source,
|
|
2370
|
-
arguments: state ? this.parseToolArguments(state.argumentsJson) : {}
|
|
2371
|
-
};
|
|
2372
|
-
const duration = state ? Date.now() - state.startedAt : 0;
|
|
2373
|
-
this.recordToolResult(toolCall, this.parseToolContent(content), duration);
|
|
2374
|
-
if (pendingFrontendTool?.toolCallId === toolCallId) {
|
|
2375
|
-
pendingFrontendTool = null;
|
|
2376
|
-
}
|
|
2377
|
-
break;
|
|
2378
|
-
}
|
|
2379
|
-
case AG_UI_EVENT.CUSTOM: {
|
|
2380
|
-
const name = this.getStringField(data, "name");
|
|
2381
|
-
if (name === "mcpstack.budget_snapshot") {
|
|
2382
|
-
const value = data.value;
|
|
2383
|
-
if (value && typeof value === "object") {
|
|
2384
|
-
this.budgetSnapshot = value;
|
|
2385
|
-
this.emit("budget_snapshot", this.budgetSnapshot);
|
|
2386
|
-
}
|
|
2387
|
-
}
|
|
2388
|
-
break;
|
|
2389
|
-
}
|
|
2390
|
-
case AG_UI_EVENT.RUN_FINISHED: {
|
|
2391
|
-
const result = this.getRecordField(data, "result");
|
|
2392
|
-
const conversationId = result ? this.getStringField(result, "conversationId") : void 0;
|
|
2393
|
-
if (conversationId) {
|
|
2394
|
-
this.conversationId = conversationId;
|
|
2395
|
-
}
|
|
2396
|
-
if (pendingFrontendTool) {
|
|
2397
|
-
return { type: "frontend_tool", data: pendingFrontendTool };
|
|
2398
|
-
}
|
|
2399
|
-
flushAssistantMessage();
|
|
2400
|
-
const messageEnd2 = {
|
|
2401
|
-
inputTokens: this.getNumberField(result, "inputTokens") ?? 0,
|
|
2402
|
-
outputTokens: this.getNumberField(result, "outputTokens") ?? 0,
|
|
2403
|
-
toolCalls: this.getNumberField(result, "toolCalls") ?? toolCalls.size
|
|
2404
|
-
};
|
|
2405
|
-
this.emit("message_end", messageEnd2);
|
|
2406
|
-
return { type: "done" };
|
|
2407
|
-
}
|
|
2408
|
-
case AG_UI_EVENT.RUN_ERROR: {
|
|
2409
|
-
const error = {
|
|
2410
|
-
code: this.getStringField(data, "code") ?? "run_error",
|
|
2411
|
-
message: this.getStringField(data, "message") ?? "Agent run failed."
|
|
2412
|
-
};
|
|
2413
|
-
const errorMsg = {
|
|
2414
|
-
id: crypto.randomUUID(),
|
|
2415
|
-
role: "error",
|
|
2416
|
-
content: error.message,
|
|
2417
|
-
timestamp: /* @__PURE__ */ new Date(),
|
|
2418
|
-
errorCode: error.code
|
|
2419
|
-
};
|
|
2420
|
-
this.messages.push(errorMsg);
|
|
2421
|
-
this.emit("message", errorMsg);
|
|
2422
|
-
this.emit("error", error);
|
|
2423
|
-
return { type: "error", data: error };
|
|
2424
|
-
}
|
|
2425
|
-
}
|
|
2426
|
-
}
|
|
2427
|
-
flushAssistantMessage();
|
|
2428
|
-
const messageEnd = {
|
|
2429
|
-
inputTokens: 0,
|
|
2430
|
-
outputTokens: 0,
|
|
2431
|
-
toolCalls: toolCalls.size
|
|
2432
|
-
};
|
|
2433
|
-
this.emit("message_end", messageEnd);
|
|
2434
|
-
return { type: "done" };
|
|
2435
|
-
}
|
|
2436
|
-
recordToolResult(toolCall, result, duration) {
|
|
2437
|
-
const toolCallMsg = this.messages.find(
|
|
2438
|
-
(m) => m.role === "tool_call" && m.toolCallId === toolCall.toolCallId
|
|
2439
|
-
);
|
|
2440
|
-
if (toolCallMsg) {
|
|
2441
|
-
toolCallMsg.toolCallStatus = "completed";
|
|
2442
|
-
toolCallMsg.toolCallDuration = duration;
|
|
2443
|
-
toolCallMsg.toolResult = this.serializeToolContent(result);
|
|
2444
|
-
}
|
|
2445
|
-
this.emit("tool_result", { toolCallId: toolCall.toolCallId, result, duration });
|
|
2446
|
-
const toolResultMsg = {
|
|
2447
|
-
id: crypto.randomUUID(),
|
|
2448
|
-
role: "tool_result",
|
|
2449
|
-
content: this.serializeToolContent(result),
|
|
2450
|
-
toolCallId: toolCall.toolCallId,
|
|
2451
|
-
toolName: toolCall.toolName,
|
|
2452
|
-
timestamp: /* @__PURE__ */ new Date()
|
|
2453
|
-
};
|
|
2454
|
-
this.messages.push(toolResultMsg);
|
|
2455
|
-
}
|
|
2456
|
-
recordToolError(toolCall, error, resultContent, duration) {
|
|
2457
|
-
const toolCallMsg = this.messages.find(
|
|
2458
|
-
(m) => m.role === "tool_call" && m.toolCallId === toolCall.toolCallId
|
|
2459
|
-
);
|
|
2460
|
-
if (toolCallMsg) {
|
|
2461
|
-
toolCallMsg.toolCallStatus = "error";
|
|
2462
|
-
toolCallMsg.toolCallDuration = duration;
|
|
2463
|
-
toolCallMsg.toolError = error;
|
|
2464
|
-
}
|
|
2465
|
-
this.emit("tool_error", { toolCallId: toolCall.toolCallId, error, duration });
|
|
2466
|
-
const toolResultMsg = {
|
|
2467
|
-
id: crypto.randomUUID(),
|
|
2468
|
-
role: "tool_result",
|
|
2469
|
-
content: resultContent,
|
|
2470
|
-
toolCallId: toolCall.toolCallId,
|
|
2471
|
-
toolName: toolCall.toolName,
|
|
2472
|
-
timestamp: /* @__PURE__ */ new Date()
|
|
2473
|
-
};
|
|
2474
|
-
this.messages.push(toolResultMsg);
|
|
2475
|
-
}
|
|
2476
|
-
serializeToolContent(result) {
|
|
2477
|
-
if (result == null) {
|
|
2478
|
-
return "";
|
|
2479
|
-
}
|
|
2480
|
-
return typeof result === "string" ? result : JSON.stringify(result);
|
|
2481
|
-
}
|
|
2482
|
-
parseToolContent(content) {
|
|
2483
|
-
if (!content) {
|
|
2484
|
-
return "";
|
|
2485
|
-
}
|
|
2486
|
-
try {
|
|
2487
|
-
return JSON.parse(content);
|
|
2488
|
-
} catch {
|
|
2489
|
-
return content;
|
|
2490
|
-
}
|
|
2491
|
-
}
|
|
2492
|
-
parseToolArguments(argumentsJson) {
|
|
2493
|
-
if (!argumentsJson.trim()) {
|
|
2494
|
-
return {};
|
|
2495
|
-
}
|
|
2496
|
-
try {
|
|
2497
|
-
const parsed = JSON.parse(argumentsJson);
|
|
2498
|
-
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
2499
|
-
} catch {
|
|
2500
|
-
return {};
|
|
2501
|
-
}
|
|
2502
|
-
}
|
|
2503
|
-
getRecordField(record, key) {
|
|
2504
|
-
const value = record?.[key];
|
|
2505
|
-
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
2506
|
-
}
|
|
2507
|
-
getStringField(record, key) {
|
|
2508
|
-
const value = record?.[key];
|
|
2509
|
-
return typeof value === "string" && value ? value : void 0;
|
|
2510
|
-
}
|
|
2511
|
-
getNumberField(record, key) {
|
|
2512
|
-
const value = record?.[key];
|
|
2513
|
-
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
2514
|
-
}
|
|
2515
2207
|
async fetchConversationMessages(conversationId, cursor, pageSize = 50) {
|
|
2516
2208
|
const token = await this.resolveAuthToken();
|
|
2517
2209
|
const params = new URLSearchParams();
|
|
@@ -2559,7 +2251,7 @@ var McpStackAgent = class {
|
|
|
2559
2251
|
};
|
|
2560
2252
|
}
|
|
2561
2253
|
/**
|
|
2562
|
-
* Process
|
|
2254
|
+
* Process an SSE stream from the chat API.
|
|
2563
2255
|
* Returns when the stream ends (either message_end or tool_call).
|
|
2564
2256
|
*/
|
|
2565
2257
|
async processSseStream(response) {
|