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