@librechat/agents 3.7.10 → 3.7.11
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/cjs/graphs/Graph.cjs +11 -1
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs +36 -3
- package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
- package/dist/cjs/langfuse.cjs +6 -2
- package/dist/cjs/langfuse.cjs.map +1 -1
- package/dist/cjs/run.cjs +5 -1
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +12 -2
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +11 -1
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs +36 -3
- package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
- package/dist/esm/langfuse.mjs +6 -2
- package/dist/esm/langfuse.mjs.map +1 -1
- package/dist/esm/run.mjs +5 -1
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +12 -2
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/types/langfuse.d.ts +5 -1
- package/dist/types/tools/ToolNode.d.ts +4 -1
- package/dist/types/types/tools.d.ts +5 -0
- package/package.json +1 -1
- package/src/graphs/Graph.ts +10 -0
- package/src/graphs/MultiAgentGraph.ts +71 -2
- package/src/langfuse.ts +12 -0
- package/src/run.ts +4 -0
- package/src/tools/ToolNode.ts +19 -0
- package/src/types/tools.ts +5 -0
|
@@ -101,6 +101,14 @@ function isTransferToolName(name: unknown): boolean {
|
|
|
101
101
|
);
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
function graphToolName(tool: unknown): string | undefined {
|
|
105
|
+
if (tool == null || typeof tool !== 'object' || !('name' in tool)) {
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
const { name } = tool;
|
|
109
|
+
return typeof name === 'string' ? name : undefined;
|
|
110
|
+
}
|
|
111
|
+
|
|
104
112
|
/**
|
|
105
113
|
* Drop transfer `tool_use` content blocks from an AI message's array content.
|
|
106
114
|
* Companion to the reception's tool-call filtering: array-content providers
|
|
@@ -287,6 +295,21 @@ function withHandoffGroupMetadata(
|
|
|
287
295
|
};
|
|
288
296
|
}
|
|
289
297
|
|
|
298
|
+
function withActiveAgentMetadata(
|
|
299
|
+
config: LangGraphRunnableConfig | undefined,
|
|
300
|
+
agentId: string,
|
|
301
|
+
agentName: string | undefined
|
|
302
|
+
): LangGraphRunnableConfig {
|
|
303
|
+
return {
|
|
304
|
+
...config,
|
|
305
|
+
metadata: {
|
|
306
|
+
...config?.metadata,
|
|
307
|
+
activeAgentId: agentId,
|
|
308
|
+
...(agentName == null ? {} : { activeAgentName: agentName }),
|
|
309
|
+
},
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
|
|
290
313
|
/**
|
|
291
314
|
* MultiAgentGraph extends StandardGraph to support dynamic multi-agent workflows
|
|
292
315
|
* with handoffs, fan-in/fan-out, and other composable patterns.
|
|
@@ -594,6 +617,24 @@ export class MultiAgentGraph extends StandardGraph {
|
|
|
594
617
|
private createHandoffTools(): void {
|
|
595
618
|
// Group handoff edges by source agent(s)
|
|
596
619
|
const handoffsByAgent = new Map<string, t.GraphEdge[]>();
|
|
620
|
+
const tokenAccountingRefresh = new Set<string>();
|
|
621
|
+
|
|
622
|
+
/** Transfer tool names are SDK-reserved. Remove externally supplied or
|
|
623
|
+
* stale transfer tools before deriving the source agent's allowed set
|
|
624
|
+
* from the graph edges below. */
|
|
625
|
+
for (const agentContext of this.agentContexts.values()) {
|
|
626
|
+
const originalTools = agentContext.graphTools;
|
|
627
|
+
const retainedTools = agentContext.graphTools?.filter(
|
|
628
|
+
(graphTool) => !isTransferToolName(graphToolName(graphTool))
|
|
629
|
+
);
|
|
630
|
+
if (retainedTools?.length !== originalTools?.length) {
|
|
631
|
+
tokenAccountingRefresh.add(agentContext.agentId);
|
|
632
|
+
}
|
|
633
|
+
agentContext.graphTools =
|
|
634
|
+
retainedTools != null && retainedTools.length > 0
|
|
635
|
+
? retainedTools
|
|
636
|
+
: undefined;
|
|
637
|
+
}
|
|
597
638
|
|
|
598
639
|
// Only process handoff edges for tool creation
|
|
599
640
|
for (const edge of this.handoffEdges) {
|
|
@@ -643,6 +684,29 @@ export class MultiAgentGraph extends StandardGraph {
|
|
|
643
684
|
for (const handoffTool of handoffTools) {
|
|
644
685
|
agentContext.graphTools.push(handoffTool);
|
|
645
686
|
}
|
|
687
|
+
if (handoffTools.length > 0) {
|
|
688
|
+
tokenAccountingRefresh.add(agentId);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
for (const agentId of tokenAccountingRefresh) {
|
|
693
|
+
const agentContext = this.agentContexts.get(agentId);
|
|
694
|
+
if (agentContext?.tokenCounter == null) {
|
|
695
|
+
continue;
|
|
696
|
+
}
|
|
697
|
+
const { tokenCounter, baseIndexTokenCountMap } = agentContext;
|
|
698
|
+
agentContext.tokenCalculationPromise = agentContext
|
|
699
|
+
.calculateInstructionTokens(tokenCounter)
|
|
700
|
+
.then(() => {
|
|
701
|
+
agentContext.updateTokenMapWithInstructions(baseIndexTokenCountMap);
|
|
702
|
+
})
|
|
703
|
+
.catch((err) => {
|
|
704
|
+
// eslint-disable-next-line no-console
|
|
705
|
+
console.error(
|
|
706
|
+
'Error recalculating instruction tokens after handoff tool updates:',
|
|
707
|
+
err
|
|
708
|
+
);
|
|
709
|
+
});
|
|
646
710
|
}
|
|
647
711
|
}
|
|
648
712
|
|
|
@@ -1239,10 +1303,16 @@ export class MultiAgentGraph extends StandardGraph {
|
|
|
1239
1303
|
): Promise<t.MultiAgentGraphState | Command> => {
|
|
1240
1304
|
let result: t.MultiAgentGraphState;
|
|
1241
1305
|
let inputMessages = state.messages;
|
|
1242
|
-
const
|
|
1306
|
+
const agentContext = this.agentContexts.get(agentId);
|
|
1307
|
+
const recursionLimitedConfig =
|
|
1243
1308
|
this.memberRecursionLimit == null
|
|
1244
1309
|
? config
|
|
1245
1310
|
: { ...config, recursionLimit: this.memberRecursionLimit };
|
|
1311
|
+
const memberConfig = withActiveAgentMetadata(
|
|
1312
|
+
recursionLimitedConfig,
|
|
1313
|
+
agentId,
|
|
1314
|
+
agentContext?.name
|
|
1315
|
+
);
|
|
1246
1316
|
|
|
1247
1317
|
/**
|
|
1248
1318
|
* Check if this agent is receiving a handoff.
|
|
@@ -1254,7 +1324,6 @@ export class MultiAgentGraph extends StandardGraph {
|
|
|
1254
1324
|
state.messages,
|
|
1255
1325
|
agentId
|
|
1256
1326
|
);
|
|
1257
|
-
const agentContext = this.agentContexts.get(agentId);
|
|
1258
1327
|
|
|
1259
1328
|
if (
|
|
1260
1329
|
handoffContext?.sourceAgentName != null &&
|
package/src/langfuse.ts
CHANGED
|
@@ -783,17 +783,29 @@ export function createLangfuseTraceMetadata({
|
|
|
783
783
|
parentMessageId,
|
|
784
784
|
agentId,
|
|
785
785
|
agentName,
|
|
786
|
+
rootAgentId,
|
|
787
|
+
rootAgentName,
|
|
788
|
+
activeAgentId,
|
|
789
|
+
activeAgentName,
|
|
786
790
|
}: {
|
|
787
791
|
messageId?: unknown;
|
|
788
792
|
parentMessageId?: unknown;
|
|
789
793
|
agentId?: unknown;
|
|
790
794
|
agentName?: unknown;
|
|
795
|
+
rootAgentId?: unknown;
|
|
796
|
+
rootAgentName?: unknown;
|
|
797
|
+
activeAgentId?: unknown;
|
|
798
|
+
activeAgentName?: unknown;
|
|
791
799
|
}): LangfuseTraceMetadata {
|
|
792
800
|
return createTraceMetadata({
|
|
793
801
|
messageId,
|
|
794
802
|
parentMessageId,
|
|
795
803
|
agentId,
|
|
796
804
|
agentName,
|
|
805
|
+
rootAgentId,
|
|
806
|
+
rootAgentName,
|
|
807
|
+
activeAgentId,
|
|
808
|
+
activeAgentName,
|
|
797
809
|
});
|
|
798
810
|
}
|
|
799
811
|
|
package/src/run.ts
CHANGED
|
@@ -1311,6 +1311,10 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
1311
1311
|
parentMessageId: config.configurable?.requestBody?.parentMessageId,
|
|
1312
1312
|
agentId: graph.defaultAgentId,
|
|
1313
1313
|
agentName: primaryContext?.name,
|
|
1314
|
+
rootAgentId: graph.defaultAgentId,
|
|
1315
|
+
rootAgentName: primaryContext?.name,
|
|
1316
|
+
activeAgentId: graph.defaultAgentId,
|
|
1317
|
+
activeAgentName: primaryContext?.name,
|
|
1314
1318
|
});
|
|
1315
1319
|
const traceName = config.runName ?? getLangfuseTraceName(traceMetadata);
|
|
1316
1320
|
const streamLangfuseConfig = this.getStreamLangfuseConfig(graph);
|
package/src/tools/ToolNode.ts
CHANGED
|
@@ -738,6 +738,9 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
738
738
|
* even where `agentId` (the subagent-scope marker) is undefined.
|
|
739
739
|
*/
|
|
740
740
|
private executingAgentId?: string;
|
|
741
|
+
private executingAgentName?: string;
|
|
742
|
+
private rootAgentId?: string;
|
|
743
|
+
private rootAgentName?: string;
|
|
741
744
|
/** Tool names that bypass event dispatch and execute directly (e.g., graph-managed handoff tools) */
|
|
742
745
|
private directToolNames?: Set<string>;
|
|
743
746
|
/**
|
|
@@ -823,6 +826,9 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
823
826
|
eagerEventToolSuppressions,
|
|
824
827
|
agentId,
|
|
825
828
|
executingAgentId,
|
|
829
|
+
executingAgentName,
|
|
830
|
+
rootAgentId,
|
|
831
|
+
rootAgentName,
|
|
826
832
|
directToolNames,
|
|
827
833
|
interruptingToolNames,
|
|
828
834
|
codeSessionToolNames,
|
|
@@ -902,6 +908,9 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
902
908
|
// Default to agentId so callers constructing ToolNode directly (who pass the
|
|
903
909
|
// existing agentId option) still get attribution without knowing the new option.
|
|
904
910
|
this.executingAgentId = executingAgentId ?? agentId;
|
|
911
|
+
this.executingAgentName = executingAgentName;
|
|
912
|
+
this.rootAgentId = rootAgentId;
|
|
913
|
+
this.rootAgentName = rootAgentName;
|
|
905
914
|
this.directToolNames = directToolNames;
|
|
906
915
|
this.interruptingToolNames =
|
|
907
916
|
interruptingToolNames != null && interruptingToolNames.size > 0
|
|
@@ -963,6 +972,16 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
963
972
|
metadata: {
|
|
964
973
|
...options?.metadata,
|
|
965
974
|
agentId: this.executingAgentId,
|
|
975
|
+
activeAgentId: this.executingAgentId,
|
|
976
|
+
...(this.executingAgentName == null
|
|
977
|
+
? {}
|
|
978
|
+
: { activeAgentName: this.executingAgentName }),
|
|
979
|
+
...(this.rootAgentId == null
|
|
980
|
+
? {}
|
|
981
|
+
: { rootAgentId: this.rootAgentId }),
|
|
982
|
+
...(this.rootAgentName == null
|
|
983
|
+
? {}
|
|
984
|
+
: { rootAgentName: this.rootAgentName }),
|
|
966
985
|
},
|
|
967
986
|
};
|
|
968
987
|
return withLangfuseRuntimeScope(
|
package/src/types/tools.ts
CHANGED
|
@@ -148,6 +148,11 @@ export type ToolNodeOptions = {
|
|
|
148
148
|
/** ID of the agent that owns this tool node, surfaced to hooks as `executingAgentId`
|
|
149
149
|
* so a batch can be attributed to a specific agent even where `agentId` is undefined. */
|
|
150
150
|
executingAgentId?: string;
|
|
151
|
+
/** Name of the agent that owns this tool node, used for active Langfuse attribution. */
|
|
152
|
+
executingAgentName?: string;
|
|
153
|
+
/** Root graph-agent identity retained alongside the currently executing tool owner. */
|
|
154
|
+
rootAgentId?: string;
|
|
155
|
+
rootAgentName?: string;
|
|
151
156
|
/** Tool names that must be executed directly (via runTool) even in event-driven mode (e.g., graph-managed handoff tools) */
|
|
152
157
|
directToolNames?: Set<string>;
|
|
153
158
|
/**
|