@wingman-ai/gateway 0.5.0 → 0.5.1
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/dist/cli/core/agentInvoker.cjs +351 -12
- package/dist/cli/core/agentInvoker.d.ts +18 -1
- package/dist/cli/core/agentInvoker.js +319 -4
- package/dist/cli/core/outputManager.cjs +22 -1
- package/dist/cli/core/outputManager.d.ts +17 -1
- package/dist/cli/core/outputManager.js +22 -1
- package/dist/cli/types.d.ts +18 -1
- package/dist/cli/ui/App.cjs +2 -0
- package/dist/cli/ui/App.js +2 -0
- package/dist/gateway/server.cjs +1 -0
- package/dist/gateway/server.js +1 -0
- package/dist/tests/agentInvokerSummarization.test.cjs +139 -0
- package/dist/tests/agentInvokerSummarization.test.js +140 -1
- package/dist/tests/agentInvokerTokenUsage.test.cjs +124 -0
- package/dist/tests/agentInvokerTokenUsage.test.d.ts +1 -0
- package/dist/tests/agentInvokerTokenUsage.test.js +118 -0
- package/dist/tests/gateway-http-security.test.cjs +20 -0
- package/dist/tests/gateway-http-security.test.js +20 -0
- package/dist/tests/integration/summarization-e2e.integration.test.cjs +127 -0
- package/dist/tests/integration/summarization-e2e.integration.test.d.ts +1 -0
- package/dist/tests/integration/summarization-e2e.integration.test.js +121 -0
- package/dist/tests/outputManagerContextSummarized.test.cjs +43 -0
- package/dist/tests/outputManagerContextSummarized.test.d.ts +1 -0
- package/dist/tests/outputManagerContextSummarized.test.js +37 -0
- package/dist/webui/assets/index-B6qyPEtp.css +11 -0
- package/dist/webui/assets/index-KjBVmiHF.js +215 -0
- package/dist/webui/index.html +2 -2
- package/package.json +2 -1
- package/dist/webui/assets/index-_GQBoNDx.js +0 -215
- package/dist/webui/assets/index-tPN3uQMb.css +0 -11
|
@@ -24,27 +24,35 @@ var __webpack_require__ = {};
|
|
|
24
24
|
var __webpack_exports__ = {};
|
|
25
25
|
__webpack_require__.r(__webpack_exports__);
|
|
26
26
|
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
chunkSignalsActiveSummarization: ()=>chunkSignalsActiveSummarization,
|
|
28
|
+
resolveAgentMemorySources: ()=>resolveAgentMemorySources,
|
|
29
|
+
emitCompletionAndContinuePostProcessing: ()=>emitCompletionAndContinuePostProcessing,
|
|
30
|
+
buildUserContent: ()=>buildUserContent,
|
|
31
|
+
mergeTokenUsageSnapshots: ()=>mergeTokenUsageSnapshots,
|
|
32
|
+
toWorkspaceAliasVirtualPath: ()=>toWorkspaceAliasVirtualPath,
|
|
33
|
+
detectContextSummarizationTransition: ()=>detectContextSummarizationTransition,
|
|
34
|
+
AgentInvoker: ()=>AgentInvoker,
|
|
35
|
+
configureDeepAgentSummarizationMiddleware: ()=>configureDeepAgentSummarizationMiddleware,
|
|
36
|
+
resolveHumanInTheLoopSettings: ()=>resolveHumanInTheLoopSettings,
|
|
37
|
+
isRootLangGraphTerminalEvent: ()=>isRootLangGraphTerminalEvent,
|
|
27
38
|
resolveToolRetryMiddlewareSettings: ()=>resolveToolRetryMiddlewareSettings,
|
|
28
39
|
resolveSummarizationMiddlewareSettings: ()=>resolveSummarizationMiddlewareSettings,
|
|
29
|
-
|
|
40
|
+
chunkBelongsToSummarizationMiddleware: ()=>chunkBelongsToSummarizationMiddleware,
|
|
41
|
+
recompileDeepAgentWithMiddlewareOverrides: ()=>recompileDeepAgentWithMiddlewareOverrides,
|
|
42
|
+
chunkHasBuiltInSummarizationSignal: ()=>chunkHasBuiltInSummarizationSignal,
|
|
30
43
|
OUTPUT_VIRTUAL_PATH: ()=>OUTPUT_VIRTUAL_PATH,
|
|
31
|
-
emitCompletionAndContinuePostProcessing: ()=>emitCompletionAndContinuePostProcessing,
|
|
32
44
|
resolveExecutionWorkspace: ()=>resolveExecutionWorkspace,
|
|
33
|
-
buildUserContent: ()=>buildUserContent,
|
|
34
45
|
detectStreamErrorMessage: ()=>detectStreamErrorMessage,
|
|
35
|
-
|
|
46
|
+
trackRootLangGraphRunId: ()=>trackRootLangGraphRunId,
|
|
36
47
|
chunkHasAssistantText: ()=>chunkHasAssistantText,
|
|
37
48
|
resolveModelRetryMiddlewareSettings: ()=>resolveModelRetryMiddlewareSettings,
|
|
38
|
-
AgentInvoker: ()=>AgentInvoker,
|
|
39
|
-
configureDeepAgentSummarizationMiddleware: ()=>configureDeepAgentSummarizationMiddleware,
|
|
40
49
|
WORKDIR_VIRTUAL_PATH: ()=>WORKDIR_VIRTUAL_PATH,
|
|
41
50
|
detectToolEventContext: ()=>detectToolEventContext,
|
|
42
51
|
resolveExternalOutputMount: ()=>resolveExternalOutputMount,
|
|
43
|
-
|
|
44
|
-
trackRootLangGraphRunId: ()=>trackRootLangGraphRunId,
|
|
45
|
-
isRootLangGraphTerminalEvent: ()=>isRootLangGraphTerminalEvent,
|
|
52
|
+
extractTokenUsageSnapshot: ()=>extractTokenUsageSnapshot,
|
|
46
53
|
selectStreamingFallbackText: ()=>selectStreamingFallbackText,
|
|
47
54
|
AGENTS_MEMORY_VIRTUAL_PATHS: ()=>AGENTS_MEMORY_VIRTUAL_PATHS,
|
|
55
|
+
estimateContextTokensFromChunk: ()=>estimateContextTokensFromChunk,
|
|
48
56
|
resolveAgentExecutionWorkspace: ()=>resolveAgentExecutionWorkspace
|
|
49
57
|
});
|
|
50
58
|
const external_node_fs_namespaceObject = require("node:fs");
|
|
@@ -173,6 +181,13 @@ const configureDeepAgentSummarizationMiddleware = (agent, settings, model)=>{
|
|
|
173
181
|
}
|
|
174
182
|
});
|
|
175
183
|
};
|
|
184
|
+
const recompileDeepAgentWithMiddlewareOverrides = (agent)=>{
|
|
185
|
+
if (agent && "object" == typeof agent) {
|
|
186
|
+
const maybeWithConfig = agent.withConfig;
|
|
187
|
+
if ("function" == typeof maybeWithConfig) return maybeWithConfig.call(agent, {});
|
|
188
|
+
}
|
|
189
|
+
return agent;
|
|
190
|
+
};
|
|
176
191
|
const detectToolEventContext = (chunk)=>{
|
|
177
192
|
if (!chunk || "object" != typeof chunk || Array.isArray(chunk)) return null;
|
|
178
193
|
const eventChunk = chunk;
|
|
@@ -183,6 +198,85 @@ const detectToolEventContext = (chunk)=>{
|
|
|
183
198
|
toolName
|
|
184
199
|
};
|
|
185
200
|
};
|
|
201
|
+
const chunkHasBuiltInSummarizationSignal = (chunk)=>{
|
|
202
|
+
if (!chunk || "object" != typeof chunk || Array.isArray(chunk)) return false;
|
|
203
|
+
const eventChunk = chunk;
|
|
204
|
+
if ("on_chain_end" !== eventChunk.event || "SummarizationMiddleware.before_model" !== eventChunk.name) return false;
|
|
205
|
+
const data = eventChunk.data && "object" == typeof eventChunk.data && !Array.isArray(eventChunk.data) ? eventChunk.data : null;
|
|
206
|
+
const output = data?.output && "object" == typeof data.output && !Array.isArray(data.output) ? data.output : null;
|
|
207
|
+
const outputMessages = Array.isArray(output?.messages) ? output.messages : [];
|
|
208
|
+
return outputMessages.some((message)=>{
|
|
209
|
+
if (!message || "object" != typeof message || Array.isArray(message)) return false;
|
|
210
|
+
const messageRecord = message;
|
|
211
|
+
const additionalKwargs = messageRecord.additional_kwargs && "object" == typeof messageRecord.additional_kwargs && !Array.isArray(messageRecord.additional_kwargs) ? messageRecord.additional_kwargs : null;
|
|
212
|
+
return additionalKwargs?.lc_source === "summarization";
|
|
213
|
+
});
|
|
214
|
+
};
|
|
215
|
+
const SUMMARIZATION_MIDDLEWARE_NODE = "summarizationmiddleware.before_model";
|
|
216
|
+
const normalizeNodeMarker = (value)=>{
|
|
217
|
+
if ("string" != typeof value) return null;
|
|
218
|
+
const normalized = value.trim().toLowerCase();
|
|
219
|
+
return normalized.length > 0 ? normalized : null;
|
|
220
|
+
};
|
|
221
|
+
const extractSummarizationNodeCandidate = (value)=>{
|
|
222
|
+
if (!value || "object" != typeof value || Array.isArray(value)) return null;
|
|
223
|
+
const record = value;
|
|
224
|
+
const directCandidates = [
|
|
225
|
+
record.langgraph_node,
|
|
226
|
+
record.langgraphNode,
|
|
227
|
+
record.node,
|
|
228
|
+
record.node_id,
|
|
229
|
+
record.nodeId
|
|
230
|
+
];
|
|
231
|
+
for (const candidate of directCandidates){
|
|
232
|
+
const normalized = normalizeNodeMarker(candidate);
|
|
233
|
+
if (normalized) return normalized;
|
|
234
|
+
}
|
|
235
|
+
const tagCandidates = [
|
|
236
|
+
record.tags,
|
|
237
|
+
record.ls_tags
|
|
238
|
+
];
|
|
239
|
+
for (const tags of tagCandidates)if (Array.isArray(tags)) for (const tag of tags){
|
|
240
|
+
if ("string" != typeof tag) continue;
|
|
241
|
+
const normalizedTag = tag.trim().toLowerCase();
|
|
242
|
+
if (normalizedTag) {
|
|
243
|
+
if (normalizedTag === `langgraph_node:${SUMMARIZATION_MIDDLEWARE_NODE}`) return SUMMARIZATION_MIDDLEWARE_NODE;
|
|
244
|
+
if (normalizedTag === `langgraph_node=${SUMMARIZATION_MIDDLEWARE_NODE}`) return SUMMARIZATION_MIDDLEWARE_NODE;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return null;
|
|
248
|
+
};
|
|
249
|
+
const chunkBelongsToSummarizationMiddleware = (chunk)=>{
|
|
250
|
+
if (!chunk || "object" != typeof chunk || Array.isArray(chunk)) return false;
|
|
251
|
+
const eventChunk = chunk;
|
|
252
|
+
const nameNode = normalizeNodeMarker(eventChunk.name);
|
|
253
|
+
if (nameNode === SUMMARIZATION_MIDDLEWARE_NODE) return true;
|
|
254
|
+
const metadataCandidates = [
|
|
255
|
+
eventChunk.metadata,
|
|
256
|
+
eventChunk.data?.metadata,
|
|
257
|
+
eventChunk.data?.chunk,
|
|
258
|
+
eventChunk.data?.message
|
|
259
|
+
];
|
|
260
|
+
for (const candidate of metadataCandidates){
|
|
261
|
+
const node = extractSummarizationNodeCandidate(candidate);
|
|
262
|
+
if (node === SUMMARIZATION_MIDDLEWARE_NODE) return true;
|
|
263
|
+
}
|
|
264
|
+
return false;
|
|
265
|
+
};
|
|
266
|
+
const SUMMARIZATION_ACTIVE_EVENTS = new Set([
|
|
267
|
+
"on_chat_model_start",
|
|
268
|
+
"on_chat_model_stream",
|
|
269
|
+
"on_chat_model_end",
|
|
270
|
+
"on_llm_start",
|
|
271
|
+
"on_llm_stream",
|
|
272
|
+
"on_llm_end"
|
|
273
|
+
]);
|
|
274
|
+
const chunkSignalsActiveSummarization = (chunk)=>{
|
|
275
|
+
if (!chunkBelongsToSummarizationMiddleware(chunk)) return false;
|
|
276
|
+
if (!chunk || "object" != typeof chunk || Array.isArray(chunk)) return false;
|
|
277
|
+
const eventName = chunk.event;
|
|
278
|
+
return "string" == typeof eventName && SUMMARIZATION_ACTIVE_EVENTS.has(eventName);
|
|
279
|
+
};
|
|
186
280
|
const chunkHasAssistantText = (chunk)=>{
|
|
187
281
|
if (!chunk || "object" != typeof chunk || Array.isArray(chunk)) return false;
|
|
188
282
|
const eventChunk = chunk;
|
|
@@ -244,6 +338,202 @@ const detectStreamErrorMessage = (chunk)=>{
|
|
|
244
338
|
if (null != errorPayload) return String(errorPayload);
|
|
245
339
|
return eventName;
|
|
246
340
|
};
|
|
341
|
+
const getFiniteTokenNumber = (value)=>"number" == typeof value && Number.isFinite(value) ? value : 0;
|
|
342
|
+
const asRecord = (value)=>value && "object" == typeof value && !Array.isArray(value) ? value : null;
|
|
343
|
+
const collectTokenUsageSnapshot = (target, payload, visited, depth)=>{
|
|
344
|
+
if (depth > 8 || !payload || "object" != typeof payload) return;
|
|
345
|
+
if (visited.has(payload)) return;
|
|
346
|
+
visited.add(payload);
|
|
347
|
+
const record = payload;
|
|
348
|
+
const directInput = getFiniteTokenNumber(record.input_tokens) || getFiniteTokenNumber(record.inputTokens) || getFiniteTokenNumber(record.prompt_tokens) || getFiniteTokenNumber(record.promptTokens);
|
|
349
|
+
const directOutput = getFiniteTokenNumber(record.output_tokens) || getFiniteTokenNumber(record.outputTokens) || getFiniteTokenNumber(record.completion_tokens) || getFiniteTokenNumber(record.completionTokens);
|
|
350
|
+
const directTotal = getFiniteTokenNumber(record.total_tokens) || getFiniteTokenNumber(record.totalTokens);
|
|
351
|
+
if (directInput > 0) target.inputTokens = Math.max(target.inputTokens, directInput);
|
|
352
|
+
if (directOutput > 0) target.outputTokens = Math.max(target.outputTokens, directOutput);
|
|
353
|
+
if (directTotal > 0) target.totalTokens = Math.max(target.totalTokens, directTotal);
|
|
354
|
+
const nestedCandidates = [
|
|
355
|
+
record.usage,
|
|
356
|
+
record.usage_metadata,
|
|
357
|
+
record.usageMetadata,
|
|
358
|
+
record.tokenUsage,
|
|
359
|
+
record.response_metadata,
|
|
360
|
+
record.responseMetadata,
|
|
361
|
+
record.additional_kwargs,
|
|
362
|
+
record.additionalKwargs,
|
|
363
|
+
record.metadata,
|
|
364
|
+
record.data,
|
|
365
|
+
record.output,
|
|
366
|
+
record.message,
|
|
367
|
+
record.chunk
|
|
368
|
+
];
|
|
369
|
+
for (const nested of nestedCandidates)collectTokenUsageSnapshot(target, nested, visited, depth + 1);
|
|
370
|
+
};
|
|
371
|
+
const extractTokenUsageSnapshot = (payload)=>{
|
|
372
|
+
const snapshot = {
|
|
373
|
+
inputTokens: 0,
|
|
374
|
+
outputTokens: 0,
|
|
375
|
+
totalTokens: 0
|
|
376
|
+
};
|
|
377
|
+
const visited = new WeakSet();
|
|
378
|
+
collectTokenUsageSnapshot(snapshot, payload, visited, 0);
|
|
379
|
+
if (0 === snapshot.totalTokens) snapshot.totalTokens = snapshot.inputTokens + snapshot.outputTokens;
|
|
380
|
+
if (snapshot.inputTokens <= 0 && snapshot.outputTokens <= 0 && snapshot.totalTokens <= 0) return null;
|
|
381
|
+
return snapshot;
|
|
382
|
+
};
|
|
383
|
+
const getMessageClassName = (message)=>{
|
|
384
|
+
const id = message.id;
|
|
385
|
+
if (Array.isArray(id) && id.length > 0) {
|
|
386
|
+
const tail = id[id.length - 1];
|
|
387
|
+
if ("string" == typeof tail) return tail.trim().toLowerCase();
|
|
388
|
+
}
|
|
389
|
+
const type = "string" == typeof message.type ? message.type : "";
|
|
390
|
+
return type.trim().toLowerCase();
|
|
391
|
+
};
|
|
392
|
+
const getMessageRole = (message)=>{
|
|
393
|
+
const kwargs = asRecord(message.kwargs);
|
|
394
|
+
const additionalKwargs = asRecord(message.additional_kwargs);
|
|
395
|
+
const additionalKwargsCamel = asRecord(message.additionalKwargs);
|
|
396
|
+
const candidates = [
|
|
397
|
+
message.role,
|
|
398
|
+
kwargs?.role,
|
|
399
|
+
additionalKwargs?.role,
|
|
400
|
+
additionalKwargsCamel?.role
|
|
401
|
+
];
|
|
402
|
+
for (const candidate of candidates)if ("string" == typeof candidate && candidate.trim()) return candidate.trim().toLowerCase();
|
|
403
|
+
return "";
|
|
404
|
+
};
|
|
405
|
+
const isMessageLikeRecord = (value)=>{
|
|
406
|
+
const record = asRecord(value);
|
|
407
|
+
if (!record) return false;
|
|
408
|
+
const role = getMessageRole(record);
|
|
409
|
+
if ("user" === role || "human" === role || "assistant" === role || "ai" === role || "system" === role || "tool" === role) return true;
|
|
410
|
+
const className = getMessageClassName(record);
|
|
411
|
+
if (className.includes("humanmessage") || className.includes("aimessage") || className.includes("toolmessage") || className.includes("systemmessage")) return true;
|
|
412
|
+
return "human" === className || "user" === className || "assistant" === className || "ai" === className || "system" === className || "tool" === className;
|
|
413
|
+
};
|
|
414
|
+
const extractTextFromContent = (content)=>{
|
|
415
|
+
if ("string" == typeof content) return content;
|
|
416
|
+
if (!Array.isArray(content)) return "";
|
|
417
|
+
return content.map((item)=>{
|
|
418
|
+
if ("string" == typeof item) return item;
|
|
419
|
+
const record = asRecord(item);
|
|
420
|
+
if (!record) return "";
|
|
421
|
+
if ("text" === record.type && "string" == typeof record.text) return record.text;
|
|
422
|
+
return "string" == typeof record.text ? record.text : "";
|
|
423
|
+
}).join("");
|
|
424
|
+
};
|
|
425
|
+
const extractMessageContent = (message)=>{
|
|
426
|
+
const kwargs = asRecord(message.kwargs);
|
|
427
|
+
const additionalKwargs = asRecord(message.additional_kwargs);
|
|
428
|
+
const additionalKwargsCamel = asRecord(message.additionalKwargs);
|
|
429
|
+
const candidates = [
|
|
430
|
+
message.content,
|
|
431
|
+
kwargs?.content,
|
|
432
|
+
additionalKwargs?.content,
|
|
433
|
+
additionalKwargsCamel?.content
|
|
434
|
+
];
|
|
435
|
+
for (const candidate of candidates){
|
|
436
|
+
const extracted = extractTextFromContent(candidate);
|
|
437
|
+
if (extracted.length > 0) return extracted;
|
|
438
|
+
}
|
|
439
|
+
return "";
|
|
440
|
+
};
|
|
441
|
+
const extractToolCalls = (message)=>{
|
|
442
|
+
const kwargs = asRecord(message.kwargs);
|
|
443
|
+
const candidates = [
|
|
444
|
+
message.tool_calls,
|
|
445
|
+
message.toolCalls,
|
|
446
|
+
kwargs?.tool_calls,
|
|
447
|
+
kwargs?.toolCalls
|
|
448
|
+
];
|
|
449
|
+
for (const candidate of candidates)if (Array.isArray(candidate) && candidate.length > 0) return candidate;
|
|
450
|
+
return [];
|
|
451
|
+
};
|
|
452
|
+
const extractToolCallId = (message)=>{
|
|
453
|
+
const kwargs = asRecord(message.kwargs);
|
|
454
|
+
const candidates = [
|
|
455
|
+
message.tool_call_id,
|
|
456
|
+
message.toolCallId,
|
|
457
|
+
kwargs?.tool_call_id,
|
|
458
|
+
kwargs?.toolCallId
|
|
459
|
+
];
|
|
460
|
+
for (const candidate of candidates)if ("string" == typeof candidate && candidate.trim()) return candidate.trim();
|
|
461
|
+
return "";
|
|
462
|
+
};
|
|
463
|
+
const isAiMessageRecord = (message)=>{
|
|
464
|
+
const role = getMessageRole(message);
|
|
465
|
+
if ("assistant" === role || "ai" === role) return true;
|
|
466
|
+
const className = getMessageClassName(message);
|
|
467
|
+
return "ai" === className || "assistant" === className || className.includes("aimessage");
|
|
468
|
+
};
|
|
469
|
+
const isToolMessageRecord = (message)=>{
|
|
470
|
+
const role = getMessageRole(message);
|
|
471
|
+
if ("tool" === role) return true;
|
|
472
|
+
const className = getMessageClassName(message);
|
|
473
|
+
return "tool" === className || className.includes("toolmessage");
|
|
474
|
+
};
|
|
475
|
+
const estimateTokensForMessageArray = (messages)=>{
|
|
476
|
+
if (0 === messages.length) return 0;
|
|
477
|
+
let totalChars = 0;
|
|
478
|
+
for (const message of messages){
|
|
479
|
+
let textContent = extractMessageContent(message);
|
|
480
|
+
if (isAiMessageRecord(message)) {
|
|
481
|
+
const toolCalls = extractToolCalls(message);
|
|
482
|
+
if (toolCalls.length > 0) textContent += JSON.stringify(toolCalls);
|
|
483
|
+
}
|
|
484
|
+
if (isToolMessageRecord(message)) textContent += extractToolCallId(message);
|
|
485
|
+
totalChars += textContent.length;
|
|
486
|
+
}
|
|
487
|
+
return Math.ceil(totalChars / 4);
|
|
488
|
+
};
|
|
489
|
+
const collectMessageArraysFromPayload = (target, payload, visited, depth)=>{
|
|
490
|
+
if (depth > 7 || !payload || "object" != typeof payload) return;
|
|
491
|
+
if (visited.has(payload)) return;
|
|
492
|
+
visited.add(payload);
|
|
493
|
+
if (Array.isArray(payload)) {
|
|
494
|
+
const messageRecords = payload.filter(isMessageLikeRecord);
|
|
495
|
+
if (messageRecords.length > 0) target.push(messageRecords);
|
|
496
|
+
for (const item of payload)collectMessageArraysFromPayload(target, item, visited, depth + 1);
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
const record = payload;
|
|
500
|
+
const directMessages = record.messages;
|
|
501
|
+
if (Array.isArray(directMessages)) {
|
|
502
|
+
const messageRecords = directMessages.filter(isMessageLikeRecord);
|
|
503
|
+
if (messageRecords.length > 0) target.push(messageRecords);
|
|
504
|
+
}
|
|
505
|
+
for (const nested of Object.values(record))if (nested && "object" == typeof nested) collectMessageArraysFromPayload(target, nested, visited, depth + 1);
|
|
506
|
+
};
|
|
507
|
+
const estimateContextTokensFromChunk = (chunk)=>{
|
|
508
|
+
const candidates = [];
|
|
509
|
+
collectMessageArraysFromPayload(candidates, chunk, new WeakSet(), 0);
|
|
510
|
+
if (0 === candidates.length) return null;
|
|
511
|
+
let estimate = 0;
|
|
512
|
+
for (const candidate of candidates){
|
|
513
|
+
const tokens = estimateTokensForMessageArray(candidate);
|
|
514
|
+
if (tokens > estimate) estimate = tokens;
|
|
515
|
+
}
|
|
516
|
+
return estimate > 0 ? estimate : null;
|
|
517
|
+
};
|
|
518
|
+
const detectContextSummarizationTransition = ({ thresholdTokens, peakInputTokens, currentInputTokens })=>{
|
|
519
|
+
if (!Number.isFinite(thresholdTokens) || !Number.isFinite(peakInputTokens) || !Number.isFinite(currentInputTokens)) return false;
|
|
520
|
+
if (thresholdTokens <= 0 || peakInputTokens <= 0 || currentInputTokens <= 0) return false;
|
|
521
|
+
if (peakInputTokens < 0.9 * thresholdTokens) return false;
|
|
522
|
+
if (currentInputTokens > 0.65 * thresholdTokens) return false;
|
|
523
|
+
if (currentInputTokens > 0.75 * peakInputTokens) return false;
|
|
524
|
+
return true;
|
|
525
|
+
};
|
|
526
|
+
const mergeTokenUsageSnapshots = (current, next)=>{
|
|
527
|
+
if (!next) return current;
|
|
528
|
+
if (!current) return next;
|
|
529
|
+
const merged = {
|
|
530
|
+
inputTokens: Math.max(current.inputTokens, next.inputTokens),
|
|
531
|
+
outputTokens: Math.max(current.outputTokens, next.outputTokens),
|
|
532
|
+
totalTokens: Math.max(current.totalTokens, next.totalTokens)
|
|
533
|
+
};
|
|
534
|
+
if (0 === merged.totalTokens) merged.totalTokens = merged.inputTokens + merged.outputTokens;
|
|
535
|
+
return merged;
|
|
536
|
+
};
|
|
247
537
|
const extractStreamEventRecord = (chunk)=>{
|
|
248
538
|
if (!chunk || "object" != typeof chunk || Array.isArray(chunk)) return null;
|
|
249
539
|
const record = chunk;
|
|
@@ -483,7 +773,7 @@ class AgentInvoker {
|
|
|
483
773
|
rootDir: outputMount.absolutePath,
|
|
484
774
|
virtualMode: true
|
|
485
775
|
});
|
|
486
|
-
|
|
776
|
+
let standaloneAgent = (0, external_deepagents_namespaceObject.createDeepAgent)({
|
|
487
777
|
systemPrompt: targetAgent.systemPrompt,
|
|
488
778
|
tools: targetAgent.tools,
|
|
489
779
|
model: targetAgent.model,
|
|
@@ -499,10 +789,15 @@ class AgentInvoker {
|
|
|
499
789
|
checkpointer: checkpointer
|
|
500
790
|
});
|
|
501
791
|
configureDeepAgentSummarizationMiddleware(standaloneAgent, summarizationSettings, targetAgent.model);
|
|
792
|
+
standaloneAgent = recompileDeepAgentWithMiddlewareOverrides(standaloneAgent);
|
|
502
793
|
this.logger.debug("Agent created, sending message");
|
|
503
794
|
const userContent = buildUserContent(prompt, attachments, targetAgent.model);
|
|
504
795
|
if (this.sessionManager && sessionId) {
|
|
505
796
|
this.logger.debug(`Using streaming with session: ${sessionId}`);
|
|
797
|
+
let streamTokenUsage = null;
|
|
798
|
+
let streamEstimatedContextTokens = 0;
|
|
799
|
+
let contextSummarizationStarted = false;
|
|
800
|
+
let contextSummarizationEmitted = false;
|
|
506
801
|
const stream = await standaloneAgent.streamEvents({
|
|
507
802
|
messages: [
|
|
508
803
|
{
|
|
@@ -535,7 +830,32 @@ class AgentInvoker {
|
|
|
535
830
|
cancelled: true
|
|
536
831
|
};
|
|
537
832
|
}
|
|
538
|
-
|
|
833
|
+
const chunkTokenUsage = extractTokenUsageSnapshot(chunk);
|
|
834
|
+
streamTokenUsage = mergeTokenUsageSnapshots(streamTokenUsage, chunkTokenUsage);
|
|
835
|
+
const isSummarizationChunk = chunkBelongsToSummarizationMiddleware(chunk);
|
|
836
|
+
const isActiveSummarizationChunk = chunkSignalsActiveSummarization(chunk);
|
|
837
|
+
if (isActiveSummarizationChunk && !contextSummarizationStarted) {
|
|
838
|
+
contextSummarizationStarted = true;
|
|
839
|
+
this.outputManager.emitContextSummarizing();
|
|
840
|
+
}
|
|
841
|
+
if (!isSummarizationChunk) {
|
|
842
|
+
const chunkEstimatedContextTokens = estimateContextTokensFromChunk(chunk);
|
|
843
|
+
if ("number" == typeof chunkEstimatedContextTokens && Number.isFinite(chunkEstimatedContextTokens) && chunkEstimatedContextTokens > streamEstimatedContextTokens) streamEstimatedContextTokens = chunkEstimatedContextTokens;
|
|
844
|
+
this.outputManager.emitAgentStream(chunk, chunkTokenUsage || void 0, streamEstimatedContextTokens > 0 ? streamEstimatedContextTokens : void 0);
|
|
845
|
+
}
|
|
846
|
+
if (!contextSummarizationEmitted && summarizationSettings && chunkHasBuiltInSummarizationSignal(chunk)) {
|
|
847
|
+
if (!contextSummarizationStarted) {
|
|
848
|
+
contextSummarizationStarted = true;
|
|
849
|
+
this.outputManager.emitContextSummarizing();
|
|
850
|
+
}
|
|
851
|
+
contextSummarizationEmitted = true;
|
|
852
|
+
const observedInputTokens = chunkTokenUsage?.inputTokens || 0;
|
|
853
|
+
this.outputManager.emitContextSummarized({
|
|
854
|
+
inputTokens: observedInputTokens,
|
|
855
|
+
peakInputTokens: observedInputTokens,
|
|
856
|
+
thresholdTokens: summarizationSettings.maxTokensBeforeSummary
|
|
857
|
+
});
|
|
858
|
+
}
|
|
539
859
|
if (isRootLangGraphTerminalEvent(chunk, rootLangGraphRunId)) {
|
|
540
860
|
this.logger.debug("Detected root LangGraph on_chain_end event; finalizing stream without waiting for iterator shutdown");
|
|
541
861
|
break;
|
|
@@ -550,7 +870,10 @@ class AgentInvoker {
|
|
|
550
870
|
};
|
|
551
871
|
}
|
|
552
872
|
this.logger.info("Agent streaming completed successfully");
|
|
553
|
-
const completionPayload = {
|
|
873
|
+
const completionPayload = streamTokenUsage ? {
|
|
874
|
+
streaming: true,
|
|
875
|
+
tokenUsage: streamTokenUsage
|
|
876
|
+
} : {
|
|
554
877
|
streaming: true
|
|
555
878
|
};
|
|
556
879
|
emitCompletionAndContinuePostProcessing({
|
|
@@ -869,12 +1192,20 @@ exports.AgentInvoker = __webpack_exports__.AgentInvoker;
|
|
|
869
1192
|
exports.OUTPUT_VIRTUAL_PATH = __webpack_exports__.OUTPUT_VIRTUAL_PATH;
|
|
870
1193
|
exports.WORKDIR_VIRTUAL_PATH = __webpack_exports__.WORKDIR_VIRTUAL_PATH;
|
|
871
1194
|
exports.buildUserContent = __webpack_exports__.buildUserContent;
|
|
1195
|
+
exports.chunkBelongsToSummarizationMiddleware = __webpack_exports__.chunkBelongsToSummarizationMiddleware;
|
|
872
1196
|
exports.chunkHasAssistantText = __webpack_exports__.chunkHasAssistantText;
|
|
1197
|
+
exports.chunkHasBuiltInSummarizationSignal = __webpack_exports__.chunkHasBuiltInSummarizationSignal;
|
|
1198
|
+
exports.chunkSignalsActiveSummarization = __webpack_exports__.chunkSignalsActiveSummarization;
|
|
873
1199
|
exports.configureDeepAgentSummarizationMiddleware = __webpack_exports__.configureDeepAgentSummarizationMiddleware;
|
|
1200
|
+
exports.detectContextSummarizationTransition = __webpack_exports__.detectContextSummarizationTransition;
|
|
874
1201
|
exports.detectStreamErrorMessage = __webpack_exports__.detectStreamErrorMessage;
|
|
875
1202
|
exports.detectToolEventContext = __webpack_exports__.detectToolEventContext;
|
|
876
1203
|
exports.emitCompletionAndContinuePostProcessing = __webpack_exports__.emitCompletionAndContinuePostProcessing;
|
|
1204
|
+
exports.estimateContextTokensFromChunk = __webpack_exports__.estimateContextTokensFromChunk;
|
|
1205
|
+
exports.extractTokenUsageSnapshot = __webpack_exports__.extractTokenUsageSnapshot;
|
|
877
1206
|
exports.isRootLangGraphTerminalEvent = __webpack_exports__.isRootLangGraphTerminalEvent;
|
|
1207
|
+
exports.mergeTokenUsageSnapshots = __webpack_exports__.mergeTokenUsageSnapshots;
|
|
1208
|
+
exports.recompileDeepAgentWithMiddlewareOverrides = __webpack_exports__.recompileDeepAgentWithMiddlewareOverrides;
|
|
878
1209
|
exports.resolveAgentExecutionWorkspace = __webpack_exports__.resolveAgentExecutionWorkspace;
|
|
879
1210
|
exports.resolveAgentMemorySources = __webpack_exports__.resolveAgentMemorySources;
|
|
880
1211
|
exports.resolveExecutionWorkspace = __webpack_exports__.resolveExecutionWorkspace;
|
|
@@ -892,12 +1223,20 @@ for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
|
892
1223
|
"OUTPUT_VIRTUAL_PATH",
|
|
893
1224
|
"WORKDIR_VIRTUAL_PATH",
|
|
894
1225
|
"buildUserContent",
|
|
1226
|
+
"chunkBelongsToSummarizationMiddleware",
|
|
895
1227
|
"chunkHasAssistantText",
|
|
1228
|
+
"chunkHasBuiltInSummarizationSignal",
|
|
1229
|
+
"chunkSignalsActiveSummarization",
|
|
896
1230
|
"configureDeepAgentSummarizationMiddleware",
|
|
1231
|
+
"detectContextSummarizationTransition",
|
|
897
1232
|
"detectStreamErrorMessage",
|
|
898
1233
|
"detectToolEventContext",
|
|
899
1234
|
"emitCompletionAndContinuePostProcessing",
|
|
1235
|
+
"estimateContextTokensFromChunk",
|
|
1236
|
+
"extractTokenUsageSnapshot",
|
|
900
1237
|
"isRootLangGraphTerminalEvent",
|
|
1238
|
+
"mergeTokenUsageSnapshots",
|
|
1239
|
+
"recompileDeepAgentWithMiddlewareOverrides",
|
|
901
1240
|
"resolveAgentExecutionWorkspace",
|
|
902
1241
|
"resolveAgentMemorySources",
|
|
903
1242
|
"resolveExecutionWorkspace",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { WingmanAgentConfig } from "@/agent/config/agentConfig.js";
|
|
2
2
|
import { type MCPProxyConfig } from "@/agent/config/mcpClientManager.js";
|
|
3
3
|
import { type ConnectedNodeTarget } from "@/agent/middleware/additional-messages.js";
|
|
4
|
-
import { type TerminalSessionManager } from "@/agent/tools/terminal_session_manager.js";
|
|
5
4
|
import type { NodeInvokeRequest, NodeInvokeResult } from "@/agent/tools/node_invoke.js";
|
|
5
|
+
import { type TerminalSessionManager } from "@/agent/tools/terminal_session_manager.js";
|
|
6
6
|
import type { WingmanAgent } from "@/types/agents.js";
|
|
7
7
|
import type { Logger } from "../../logger.js";
|
|
8
8
|
import type { WingmanConfigType } from "../config/schema.js";
|
|
@@ -114,6 +114,11 @@ export type HumanInTheLoopSettings = {
|
|
|
114
114
|
argsSchema?: Record<string, any>;
|
|
115
115
|
}>;
|
|
116
116
|
};
|
|
117
|
+
export type TokenUsageSnapshot = {
|
|
118
|
+
inputTokens: number;
|
|
119
|
+
outputTokens: number;
|
|
120
|
+
totalTokens: number;
|
|
121
|
+
};
|
|
117
122
|
export declare const resolveExecutionWorkspace: (workspace: string, workdir?: string | null) => string;
|
|
118
123
|
export declare const resolveAgentExecutionWorkspace: (workspace: string, workdir?: string | null, defaultOutputDir?: string | null) => string;
|
|
119
124
|
export declare const resolveAgentMemorySources: (executionWorkspace: string) => string[];
|
|
@@ -124,11 +129,15 @@ export declare const resolveModelRetryMiddlewareSettings: (config: WingmanConfig
|
|
|
124
129
|
export declare const resolveToolRetryMiddlewareSettings: (config: WingmanConfigType) => ToolRetryMiddlewareSettings | null;
|
|
125
130
|
export declare const resolveHumanInTheLoopSettings: (config: WingmanConfigType) => HumanInTheLoopSettings | null;
|
|
126
131
|
export declare const configureDeepAgentSummarizationMiddleware: (agent: any, settings: SummarizationMiddlewareSettings | null, model?: any) => void;
|
|
132
|
+
export declare const recompileDeepAgentWithMiddlewareOverrides: <T>(agent: T) => T;
|
|
127
133
|
type ToolEventContext = {
|
|
128
134
|
event: "on_tool_start" | "on_tool_end" | "on_tool_error";
|
|
129
135
|
toolName: string;
|
|
130
136
|
};
|
|
131
137
|
export declare const detectToolEventContext: (chunk: unknown) => ToolEventContext | null;
|
|
138
|
+
export declare const chunkHasBuiltInSummarizationSignal: (chunk: unknown) => boolean;
|
|
139
|
+
export declare const chunkBelongsToSummarizationMiddleware: (chunk: unknown) => boolean;
|
|
140
|
+
export declare const chunkSignalsActiveSummarization: (chunk: unknown) => boolean;
|
|
132
141
|
export declare const chunkHasAssistantText: (chunk: unknown) => boolean;
|
|
133
142
|
export declare const selectStreamingFallbackText: (previousMessages: Array<{
|
|
134
143
|
role?: unknown;
|
|
@@ -138,6 +147,14 @@ export declare const selectStreamingFallbackText: (previousMessages: Array<{
|
|
|
138
147
|
content?: unknown;
|
|
139
148
|
}>) => string | undefined;
|
|
140
149
|
export declare const detectStreamErrorMessage: (chunk: unknown) => string | undefined;
|
|
150
|
+
export declare const extractTokenUsageSnapshot: (payload: unknown) => TokenUsageSnapshot | null;
|
|
151
|
+
export declare const estimateContextTokensFromChunk: (chunk: unknown) => number | null;
|
|
152
|
+
export declare const detectContextSummarizationTransition: ({ thresholdTokens, peakInputTokens, currentInputTokens, }: {
|
|
153
|
+
thresholdTokens: number;
|
|
154
|
+
peakInputTokens: number;
|
|
155
|
+
currentInputTokens: number;
|
|
156
|
+
}) => boolean;
|
|
157
|
+
export declare const mergeTokenUsageSnapshots: (current: TokenUsageSnapshot | null, next: TokenUsageSnapshot | null) => TokenUsageSnapshot | null;
|
|
141
158
|
export declare const trackRootLangGraphRunId: (currentRootLangGraphRunId: string | undefined, chunk: unknown) => string | undefined;
|
|
142
159
|
export declare const isRootLangGraphTerminalEvent: (chunk: unknown, rootLangGraphRunId?: string) => boolean;
|
|
143
160
|
export declare const emitCompletionAndContinuePostProcessing: (input: {
|