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