@iqai/adk 0.1.20 → 0.1.22
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/CHANGELOG.md +13 -0
- package/dist/index.d.mts +134 -22
- package/dist/index.d.ts +134 -22
- package/dist/index.js +576 -277
- package/dist/index.mjs +403 -104
- package/package.json +11 -1
package/dist/index.mjs
CHANGED
|
@@ -53,7 +53,7 @@ var init_logger = __esm({
|
|
|
53
53
|
}
|
|
54
54
|
info(message, ...args) {
|
|
55
55
|
const time = (/* @__PURE__ */ new Date()).toLocaleTimeString();
|
|
56
|
-
console.
|
|
56
|
+
console.debug(
|
|
57
57
|
this.colorize(`[${time}] \u2139\uFE0F [${this.name}] ${message}`),
|
|
58
58
|
...args
|
|
59
59
|
);
|
|
@@ -229,7 +229,7 @@ var init_base_tool = __esm({
|
|
|
229
229
|
* @param context The context of the tool
|
|
230
230
|
* @returns The result of running the tool
|
|
231
231
|
*/
|
|
232
|
-
async runAsync(args,
|
|
232
|
+
async runAsync(args, context4) {
|
|
233
233
|
throw new Error(`${this.constructor.name} runAsync is not implemented`);
|
|
234
234
|
}
|
|
235
235
|
/**
|
|
@@ -253,6 +253,12 @@ var init_base_tool = __esm({
|
|
|
253
253
|
if (!toolWithFunctionDeclarations.functionDeclarations) {
|
|
254
254
|
toolWithFunctionDeclarations.functionDeclarations = [];
|
|
255
255
|
}
|
|
256
|
+
const alreadyExists = toolWithFunctionDeclarations.functionDeclarations.some(
|
|
257
|
+
(fd) => fd?.name === functionDeclaration.name
|
|
258
|
+
);
|
|
259
|
+
if (alreadyExists) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
256
262
|
toolWithFunctionDeclarations.functionDeclarations.push(
|
|
257
263
|
functionDeclaration
|
|
258
264
|
);
|
|
@@ -281,7 +287,7 @@ var init_base_tool = __esm({
|
|
|
281
287
|
* @param context Tool execution context
|
|
282
288
|
* @returns Result of the tool execution or error information
|
|
283
289
|
*/
|
|
284
|
-
async safeExecute(args,
|
|
290
|
+
async safeExecute(args, context4) {
|
|
285
291
|
if (!this.validateArguments(args)) {
|
|
286
292
|
return {
|
|
287
293
|
error: "Invalid arguments",
|
|
@@ -302,7 +308,7 @@ var init_base_tool = __esm({
|
|
|
302
308
|
);
|
|
303
309
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
304
310
|
}
|
|
305
|
-
const result = await this.runAsync(args,
|
|
311
|
+
const result = await this.runAsync(args, context4);
|
|
306
312
|
return { result };
|
|
307
313
|
} catch (error) {
|
|
308
314
|
lastError = error instanceof Error ? error : new Error(String(error));
|
|
@@ -500,7 +506,7 @@ var init_function_tool = __esm({
|
|
|
500
506
|
/**
|
|
501
507
|
* Executes the wrapped function with the provided arguments.
|
|
502
508
|
*/
|
|
503
|
-
async runAsync(args,
|
|
509
|
+
async runAsync(args, context4) {
|
|
504
510
|
try {
|
|
505
511
|
const missingArgs = this.getMissingMandatoryArgs(args);
|
|
506
512
|
if (missingArgs.length > 0) {
|
|
@@ -513,13 +519,13 @@ You could retry calling this tool, but it is IMPORTANT for you to provide all th
|
|
|
513
519
|
}
|
|
514
520
|
const argsToCall = { ...args };
|
|
515
521
|
if (this.functionAcceptsToolContext()) {
|
|
516
|
-
argsToCall.toolContext =
|
|
522
|
+
argsToCall.toolContext = context4;
|
|
517
523
|
}
|
|
518
524
|
const funcParams = this.getFunctionParameters();
|
|
519
525
|
const argValues = [];
|
|
520
526
|
for (const paramName of funcParams) {
|
|
521
527
|
if (paramName === "toolContext" && this.functionAcceptsToolContext()) {
|
|
522
|
-
argValues.push(
|
|
528
|
+
argValues.push(context4);
|
|
523
529
|
} else if (paramName in argsToCall) {
|
|
524
530
|
const convertedValue = this.convertArgumentType(
|
|
525
531
|
argsToCall[paramName],
|
|
@@ -954,6 +960,7 @@ init_logger();
|
|
|
954
960
|
import {
|
|
955
961
|
DiagConsoleLogger,
|
|
956
962
|
DiagLogLevel,
|
|
963
|
+
context,
|
|
957
964
|
diag,
|
|
958
965
|
trace
|
|
959
966
|
} from "@opentelemetry/api";
|
|
@@ -994,13 +1001,24 @@ var TelemetryService = class {
|
|
|
994
1001
|
this.sdk = new NodeSDK({
|
|
995
1002
|
resource,
|
|
996
1003
|
traceExporter,
|
|
997
|
-
instrumentations: [
|
|
1004
|
+
instrumentations: [
|
|
1005
|
+
getNodeAutoInstrumentations({
|
|
1006
|
+
// Follow Python ADK approach: let all HTTP instrumentation through.
|
|
1007
|
+
// This provides transparency and aligns with standard OpenTelemetry behavior.
|
|
1008
|
+
// High-level LLM tracing is provided through dedicated ADK spans.
|
|
1009
|
+
"@opentelemetry/instrumentation-http": {
|
|
1010
|
+
ignoreIncomingRequestHook: (req) => {
|
|
1011
|
+
return true;
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
})
|
|
1015
|
+
]
|
|
998
1016
|
});
|
|
999
1017
|
try {
|
|
1000
1018
|
this.sdk.start();
|
|
1001
1019
|
this.isInitialized = true;
|
|
1002
1020
|
this.tracer = trace.getTracer("iqai-adk", config.appVersion || "0.1.0");
|
|
1003
|
-
diag.
|
|
1021
|
+
diag.debug("OpenTelemetry SDK started successfully.");
|
|
1004
1022
|
} catch (error) {
|
|
1005
1023
|
diag.error("Error starting OpenTelemetry SDK:", error);
|
|
1006
1024
|
throw error;
|
|
@@ -1043,7 +1061,7 @@ var TelemetryService = class {
|
|
|
1043
1061
|
});
|
|
1044
1062
|
await Promise.race([this.sdk.shutdown(), timeoutPromise]);
|
|
1045
1063
|
this.isInitialized = false;
|
|
1046
|
-
diag.
|
|
1064
|
+
diag.debug("Telemetry terminated successfully.");
|
|
1047
1065
|
} catch (error) {
|
|
1048
1066
|
if (error instanceof Error && error.message.includes("timeout")) {
|
|
1049
1067
|
diag.warn("Telemetry shutdown timed out, some traces may be lost");
|
|
@@ -1071,7 +1089,7 @@ var TelemetryService = class {
|
|
|
1071
1089
|
}
|
|
1072
1090
|
}
|
|
1073
1091
|
span.setAttributes({
|
|
1074
|
-
"gen_ai.system
|
|
1092
|
+
"gen_ai.system": "iqai-adk",
|
|
1075
1093
|
"gen_ai.operation.name": "execute_tool",
|
|
1076
1094
|
"gen_ai.tool.name": tool.name,
|
|
1077
1095
|
"gen_ai.tool.description": tool.description,
|
|
@@ -1085,7 +1103,7 @@ var TelemetryService = class {
|
|
|
1085
1103
|
...process.env.NODE_ENV && {
|
|
1086
1104
|
"deployment.environment.name": process.env.NODE_ENV
|
|
1087
1105
|
},
|
|
1088
|
-
//
|
|
1106
|
+
// ADK-specific attributes (matching Python namespace pattern)
|
|
1089
1107
|
"adk.tool_call_args": this._safeJsonStringify(args),
|
|
1090
1108
|
"adk.event_id": functionResponseEvent.invocationId,
|
|
1091
1109
|
"adk.tool_response": this._safeJsonStringify(toolResponse),
|
|
@@ -1101,9 +1119,8 @@ var TelemetryService = class {
|
|
|
1101
1119
|
if (!span) return;
|
|
1102
1120
|
const requestData = this._buildLlmRequestForTrace(llmRequest);
|
|
1103
1121
|
span.setAttributes({
|
|
1104
|
-
// Standard OpenTelemetry attributes
|
|
1105
|
-
"gen_ai.system
|
|
1106
|
-
"gen_ai.operation.name": "generate",
|
|
1122
|
+
// Standard OpenTelemetry attributes (following Python pattern)
|
|
1123
|
+
"gen_ai.system": "iqai-adk",
|
|
1107
1124
|
"gen_ai.request.model": llmRequest.model,
|
|
1108
1125
|
// Session and user tracking (maps to Langfuse sessionId, userId)
|
|
1109
1126
|
"session.id": invocationContext.session.id,
|
|
@@ -1116,15 +1133,21 @@ var TelemetryService = class {
|
|
|
1116
1133
|
"gen_ai.request.max_tokens": llmRequest.config.maxOutputTokens || 0,
|
|
1117
1134
|
"gen_ai.request.temperature": llmRequest.config.temperature || 0,
|
|
1118
1135
|
"gen_ai.request.top_p": llmRequest.config.topP || 0,
|
|
1119
|
-
// Legacy ADK attributes (keep for backward compatibility)
|
|
1120
1136
|
"adk.system_name": "iqai-adk",
|
|
1121
1137
|
"adk.request_model": llmRequest.model,
|
|
1122
|
-
|
|
1138
|
+
// ADK-specific attributes (matching Python namespace pattern)
|
|
1139
|
+
"adk.invocation_id": invocationContext.invocationId,
|
|
1123
1140
|
"adk.session_id": invocationContext.session.id,
|
|
1124
1141
|
"adk.event_id": eventId,
|
|
1125
1142
|
"adk.llm_request": this._safeJsonStringify(requestData),
|
|
1126
1143
|
"adk.llm_response": this._safeJsonStringify(llmResponse)
|
|
1127
1144
|
});
|
|
1145
|
+
if (llmResponse.usageMetadata) {
|
|
1146
|
+
span.setAttributes({
|
|
1147
|
+
"gen_ai.usage.input_tokens": llmResponse.usageMetadata.promptTokenCount || 0,
|
|
1148
|
+
"gen_ai.usage.output_tokens": llmResponse.usageMetadata.candidatesTokenCount || 0
|
|
1149
|
+
});
|
|
1150
|
+
}
|
|
1128
1151
|
span.addEvent("gen_ai.content.prompt", {
|
|
1129
1152
|
"gen_ai.prompt": this._safeJsonStringify(requestData.messages)
|
|
1130
1153
|
});
|
|
@@ -1137,9 +1160,14 @@ var TelemetryService = class {
|
|
|
1137
1160
|
*/
|
|
1138
1161
|
async *traceAsyncGenerator(spanName, generator) {
|
|
1139
1162
|
const span = this.tracer.startSpan(spanName);
|
|
1163
|
+
const spanContext = trace.setSpan(context.active(), span);
|
|
1140
1164
|
try {
|
|
1141
|
-
|
|
1142
|
-
|
|
1165
|
+
while (true) {
|
|
1166
|
+
const result = await context.with(spanContext, () => generator.next());
|
|
1167
|
+
if (result.done) {
|
|
1168
|
+
break;
|
|
1169
|
+
}
|
|
1170
|
+
yield result.value;
|
|
1143
1171
|
}
|
|
1144
1172
|
} catch (error) {
|
|
1145
1173
|
span.recordException(error);
|
|
@@ -1226,7 +1254,7 @@ var traceLlmCall = (invocationContext, eventId, llmRequest, llmResponse) => tele
|
|
|
1226
1254
|
// src/models/base-llm.ts
|
|
1227
1255
|
var BaseLlm = class {
|
|
1228
1256
|
/**
|
|
1229
|
-
* The name of the LLM, e.g. gemini-
|
|
1257
|
+
* The name of the LLM, e.g. gemini-2.5-flash or gemini-2.5-flash-001.
|
|
1230
1258
|
*/
|
|
1231
1259
|
model;
|
|
1232
1260
|
logger = new Logger({ name: "BaseLlm" });
|
|
@@ -1353,7 +1381,7 @@ var BaseLlm = class {
|
|
|
1353
1381
|
* @param llmRequest LlmRequest, the request to send to the LLM.
|
|
1354
1382
|
* @returns BaseLLMConnection, the connection to the LLM.
|
|
1355
1383
|
*/
|
|
1356
|
-
connect(
|
|
1384
|
+
connect(_llmRequest) {
|
|
1357
1385
|
throw new Error(`Live connection is not supported for ${this.model}.`);
|
|
1358
1386
|
}
|
|
1359
1387
|
};
|
|
@@ -1915,7 +1943,7 @@ var GoogleLlm = class extends BaseLlm {
|
|
|
1915
1943
|
/**
|
|
1916
1944
|
* Constructor for Gemini
|
|
1917
1945
|
*/
|
|
1918
|
-
constructor(model = "gemini-
|
|
1946
|
+
constructor(model = "gemini-2.5-flash") {
|
|
1919
1947
|
super(model);
|
|
1920
1948
|
}
|
|
1921
1949
|
/**
|
|
@@ -3954,10 +3982,10 @@ var CreatedTool = class extends BaseTool {
|
|
|
3954
3982
|
/**
|
|
3955
3983
|
* Executes the tool function with validation
|
|
3956
3984
|
*/
|
|
3957
|
-
async runAsync(args,
|
|
3985
|
+
async runAsync(args, context4) {
|
|
3958
3986
|
try {
|
|
3959
3987
|
const validatedArgs = this.schema.parse(args);
|
|
3960
|
-
const result = await Promise.resolve(this.func(validatedArgs,
|
|
3988
|
+
const result = await Promise.resolve(this.func(validatedArgs, context4));
|
|
3961
3989
|
return result ?? {};
|
|
3962
3990
|
} catch (error) {
|
|
3963
3991
|
if (error instanceof z.ZodError) {
|
|
@@ -4215,7 +4243,7 @@ var AgentTool = class extends BaseTool {
|
|
|
4215
4243
|
/**
|
|
4216
4244
|
* Execute the tool by running the agent with the provided input
|
|
4217
4245
|
*/
|
|
4218
|
-
async runAsync(params,
|
|
4246
|
+
async runAsync(params, context4) {
|
|
4219
4247
|
try {
|
|
4220
4248
|
const input = params.input || Object.values(params)[0];
|
|
4221
4249
|
if (!isLlmAgent(this.agent)) {
|
|
@@ -4223,7 +4251,7 @@ var AgentTool = class extends BaseTool {
|
|
|
4223
4251
|
`Agent ${this.name} does not support running as a tool`
|
|
4224
4252
|
);
|
|
4225
4253
|
}
|
|
4226
|
-
const parentInvocation =
|
|
4254
|
+
const parentInvocation = context4._invocationContext;
|
|
4227
4255
|
const childInvocationContext = new InvocationContext({
|
|
4228
4256
|
invocationId: uuidv42(),
|
|
4229
4257
|
agent: this.agent,
|
|
@@ -4260,8 +4288,8 @@ var AgentTool = class extends BaseTool {
|
|
|
4260
4288
|
} catch {
|
|
4261
4289
|
toolResult = mergedText;
|
|
4262
4290
|
}
|
|
4263
|
-
if (this.outputKey &&
|
|
4264
|
-
|
|
4291
|
+
if (this.outputKey && context4?.state) {
|
|
4292
|
+
context4.state[this.outputKey] = toolResult;
|
|
4265
4293
|
}
|
|
4266
4294
|
return toolResult;
|
|
4267
4295
|
} catch (error) {
|
|
@@ -4809,9 +4837,9 @@ var UserInteractionTool = class extends BaseTool {
|
|
|
4809
4837
|
/**
|
|
4810
4838
|
* Execute the user interaction
|
|
4811
4839
|
*/
|
|
4812
|
-
async runAsync(args,
|
|
4840
|
+
async runAsync(args, context4) {
|
|
4813
4841
|
try {
|
|
4814
|
-
const actions =
|
|
4842
|
+
const actions = context4.actions;
|
|
4815
4843
|
if (!actions || !actions.promptUser) {
|
|
4816
4844
|
return {
|
|
4817
4845
|
success: false,
|
|
@@ -4859,9 +4887,9 @@ var ExitLoopTool = class extends BaseTool {
|
|
|
4859
4887
|
/**
|
|
4860
4888
|
* Execute the exit loop action
|
|
4861
4889
|
*/
|
|
4862
|
-
async runAsync(_args,
|
|
4890
|
+
async runAsync(_args, context4) {
|
|
4863
4891
|
this.logger.debug("Executing exit loop tool");
|
|
4864
|
-
|
|
4892
|
+
context4.actions.escalate = true;
|
|
4865
4893
|
}
|
|
4866
4894
|
};
|
|
4867
4895
|
|
|
@@ -4912,14 +4940,14 @@ var GetUserChoiceTool = class extends BaseTool {
|
|
|
4912
4940
|
* This is a long running operation that will return null initially
|
|
4913
4941
|
* and the actual choice will be provided asynchronously
|
|
4914
4942
|
*/
|
|
4915
|
-
async runAsync(args,
|
|
4943
|
+
async runAsync(args, context4) {
|
|
4916
4944
|
this.logger.debug(
|
|
4917
4945
|
`Executing get_user_choice with options: ${args.options.join(", ")}`
|
|
4918
4946
|
);
|
|
4919
4947
|
if (args.question) {
|
|
4920
4948
|
this.logger.debug(`Question: ${args.question}`);
|
|
4921
4949
|
}
|
|
4922
|
-
|
|
4950
|
+
context4.actions.skipSummarization = true;
|
|
4923
4951
|
return null;
|
|
4924
4952
|
}
|
|
4925
4953
|
};
|
|
@@ -4961,9 +4989,9 @@ var TransferToAgentTool = class extends BaseTool {
|
|
|
4961
4989
|
/**
|
|
4962
4990
|
* Execute the transfer to agent action
|
|
4963
4991
|
*/
|
|
4964
|
-
async runAsync(args,
|
|
4992
|
+
async runAsync(args, context4) {
|
|
4965
4993
|
this.logger.debug(`Executing transfer to agent: ${args.agent_name}`);
|
|
4966
|
-
|
|
4994
|
+
context4.actions.transferToAgent = args.agent_name;
|
|
4967
4995
|
}
|
|
4968
4996
|
};
|
|
4969
4997
|
|
|
@@ -5004,10 +5032,10 @@ var LoadMemoryTool = class extends BaseTool {
|
|
|
5004
5032
|
/**
|
|
5005
5033
|
* Execute the memory loading action
|
|
5006
5034
|
*/
|
|
5007
|
-
async runAsync(args,
|
|
5035
|
+
async runAsync(args, context4) {
|
|
5008
5036
|
this.logger.debug(`Executing load_memory with query: ${args.query}`);
|
|
5009
5037
|
try {
|
|
5010
|
-
const searchResult = await
|
|
5038
|
+
const searchResult = await context4.searchMemory(args.query);
|
|
5011
5039
|
return {
|
|
5012
5040
|
memories: searchResult.memories || [],
|
|
5013
5041
|
count: searchResult.memories?.length || 0
|
|
@@ -5057,7 +5085,7 @@ var LoadArtifactsTool = class extends BaseTool {
|
|
|
5057
5085
|
/**
|
|
5058
5086
|
* Execute the load artifacts operation
|
|
5059
5087
|
*/
|
|
5060
|
-
async runAsync(args,
|
|
5088
|
+
async runAsync(args, context4) {
|
|
5061
5089
|
const artifactNames = args.artifact_names || [];
|
|
5062
5090
|
return { artifact_names: artifactNames };
|
|
5063
5091
|
}
|
|
@@ -6088,12 +6116,12 @@ var McpToolset = class {
|
|
|
6088
6116
|
* Checks if a tool should be included based on the tool filter.
|
|
6089
6117
|
* Similar to Python's _is_selected method.
|
|
6090
6118
|
*/
|
|
6091
|
-
isSelected(tool,
|
|
6119
|
+
isSelected(tool, context4) {
|
|
6092
6120
|
if (!this.toolFilter) {
|
|
6093
6121
|
return true;
|
|
6094
6122
|
}
|
|
6095
6123
|
if (typeof this.toolFilter === "function") {
|
|
6096
|
-
return this.toolFilter(tool,
|
|
6124
|
+
return this.toolFilter(tool, context4);
|
|
6097
6125
|
}
|
|
6098
6126
|
if (Array.isArray(this.toolFilter)) {
|
|
6099
6127
|
return this.toolFilter.includes(tool.name);
|
|
@@ -6146,7 +6174,7 @@ var McpToolset = class {
|
|
|
6146
6174
|
* Retrieves tools from the MCP server and converts them to BaseTool instances.
|
|
6147
6175
|
* Similar to Python's get_tools method.
|
|
6148
6176
|
*/
|
|
6149
|
-
async getTools(
|
|
6177
|
+
async getTools(context4) {
|
|
6150
6178
|
try {
|
|
6151
6179
|
if (this.isClosing) {
|
|
6152
6180
|
throw new McpError(
|
|
@@ -6168,7 +6196,7 @@ var McpToolset = class {
|
|
|
6168
6196
|
}
|
|
6169
6197
|
const tools = [];
|
|
6170
6198
|
for (const mcpTool of toolsResponse.tools) {
|
|
6171
|
-
if (this.isSelected(mcpTool,
|
|
6199
|
+
if (this.isSelected(mcpTool, context4)) {
|
|
6172
6200
|
try {
|
|
6173
6201
|
const tool = await createTool2(mcpTool, client);
|
|
6174
6202
|
tools.push(tool);
|
|
@@ -6205,9 +6233,9 @@ var McpToolset = class {
|
|
|
6205
6233
|
/**
|
|
6206
6234
|
* Refreshes the tool cache by clearing it and fetching tools again
|
|
6207
6235
|
*/
|
|
6208
|
-
async refreshTools(
|
|
6236
|
+
async refreshTools(context4) {
|
|
6209
6237
|
this.tools = [];
|
|
6210
|
-
return this.getTools(
|
|
6238
|
+
return this.getTools(context4);
|
|
6211
6239
|
}
|
|
6212
6240
|
/**
|
|
6213
6241
|
* Closes the connection to the MCP server.
|
|
@@ -6251,6 +6279,7 @@ async function getMcpTools(config, toolFilter) {
|
|
|
6251
6279
|
}
|
|
6252
6280
|
|
|
6253
6281
|
// src/flows/llm-flows/functions.ts
|
|
6282
|
+
import { context as context2, trace as trace2 } from "@opentelemetry/api";
|
|
6254
6283
|
var AF_FUNCTION_CALL_ID_PREFIX = "adk-";
|
|
6255
6284
|
var REQUEST_EUC_FUNCTION_CALL_NAME = "adk_request_credential";
|
|
6256
6285
|
function generateClientFunctionCallId() {
|
|
@@ -6340,23 +6369,40 @@ async function handleFunctionCallsAsync(invocationContext, functionCallEvent, to
|
|
|
6340
6369
|
toolsDict
|
|
6341
6370
|
);
|
|
6342
6371
|
const functionArgs = functionCall.args || {};
|
|
6343
|
-
const
|
|
6344
|
-
|
|
6345
|
-
|
|
6346
|
-
|
|
6347
|
-
|
|
6348
|
-
|
|
6372
|
+
const tracer2 = telemetryService.getTracer();
|
|
6373
|
+
const span = tracer2.startSpan(`execute_tool ${tool.name}`);
|
|
6374
|
+
const spanContext = trace2.setSpan(context2.active(), span);
|
|
6375
|
+
try {
|
|
6376
|
+
const functionResponse = await context2.with(spanContext, async () => {
|
|
6377
|
+
const result = await callToolAsync(tool, functionArgs, toolContext);
|
|
6378
|
+
if (tool.isLongRunning && !result) {
|
|
6379
|
+
return null;
|
|
6380
|
+
}
|
|
6381
|
+
const functionResponseEvent = buildResponseEvent(
|
|
6382
|
+
tool,
|
|
6383
|
+
result,
|
|
6384
|
+
toolContext,
|
|
6385
|
+
invocationContext
|
|
6386
|
+
);
|
|
6387
|
+
telemetryService.traceToolCall(
|
|
6388
|
+
tool,
|
|
6389
|
+
functionArgs,
|
|
6390
|
+
functionResponseEvent
|
|
6391
|
+
);
|
|
6392
|
+
return { result, event: functionResponseEvent };
|
|
6393
|
+
});
|
|
6349
6394
|
if (!functionResponse) {
|
|
6350
6395
|
continue;
|
|
6351
6396
|
}
|
|
6397
|
+
functionResponseEvents.push(functionResponse.event);
|
|
6398
|
+
span.setStatus({ code: 1 });
|
|
6399
|
+
} catch (error) {
|
|
6400
|
+
span.recordException(error);
|
|
6401
|
+
span.setStatus({ code: 2, message: error.message });
|
|
6402
|
+
throw error;
|
|
6403
|
+
} finally {
|
|
6404
|
+
span.end();
|
|
6352
6405
|
}
|
|
6353
|
-
const functionResponseEvent = buildResponseEvent(
|
|
6354
|
-
tool,
|
|
6355
|
-
functionResponse,
|
|
6356
|
-
toolContext,
|
|
6357
|
-
invocationContext
|
|
6358
|
-
);
|
|
6359
|
-
functionResponseEvents.push(functionResponseEvent);
|
|
6360
6406
|
}
|
|
6361
6407
|
if (!functionResponseEvents.length) {
|
|
6362
6408
|
return null;
|
|
@@ -6456,7 +6502,7 @@ var BaseLlmFlow = class {
|
|
|
6456
6502
|
responseProcessors = [];
|
|
6457
6503
|
logger = new Logger({ name: "BaseLlmFlow" });
|
|
6458
6504
|
async *runAsync(invocationContext) {
|
|
6459
|
-
this.logger.
|
|
6505
|
+
this.logger.debug(`Agent '${invocationContext.agent.name}' started.`);
|
|
6460
6506
|
let stepCount = 0;
|
|
6461
6507
|
while (true) {
|
|
6462
6508
|
stepCount++;
|
|
@@ -6466,7 +6512,7 @@ var BaseLlmFlow = class {
|
|
|
6466
6512
|
yield event;
|
|
6467
6513
|
}
|
|
6468
6514
|
if (!lastEvent || lastEvent.isFinalResponse()) {
|
|
6469
|
-
this.logger.
|
|
6515
|
+
this.logger.debug(
|
|
6470
6516
|
`Agent '${invocationContext.agent.name}' finished after ${stepCount} steps.`
|
|
6471
6517
|
);
|
|
6472
6518
|
break;
|
|
@@ -6496,7 +6542,7 @@ var BaseLlmFlow = class {
|
|
|
6496
6542
|
yield event;
|
|
6497
6543
|
}
|
|
6498
6544
|
if (invocationContext.endInvocation) {
|
|
6499
|
-
this.logger.
|
|
6545
|
+
this.logger.debug("Invocation ended during preprocessing.");
|
|
6500
6546
|
return;
|
|
6501
6547
|
}
|
|
6502
6548
|
const modelResponseEvent = new Event({
|
|
@@ -6611,7 +6657,7 @@ var BaseLlmFlow = class {
|
|
|
6611
6657
|
yield functionResponseEvent;
|
|
6612
6658
|
const transferToAgent = functionResponseEvent.actions?.transferToAgent;
|
|
6613
6659
|
if (transferToAgent) {
|
|
6614
|
-
this.logger.
|
|
6660
|
+
this.logger.debug(`\u{1F504} Live transfer to agent '${transferToAgent}'`);
|
|
6615
6661
|
const agentToRun = this._getAgentToRun(
|
|
6616
6662
|
invocationContext,
|
|
6617
6663
|
transferToAgent
|
|
@@ -6650,7 +6696,7 @@ var BaseLlmFlow = class {
|
|
|
6650
6696
|
yield functionResponseEvent;
|
|
6651
6697
|
const transferToAgent = functionResponseEvent.actions?.transferToAgent;
|
|
6652
6698
|
if (transferToAgent) {
|
|
6653
|
-
this.logger.
|
|
6699
|
+
this.logger.debug(`\u{1F504} Transferring to agent '${transferToAgent}'`);
|
|
6654
6700
|
const agentToRun = this._getAgentToRun(
|
|
6655
6701
|
invocationContext,
|
|
6656
6702
|
transferToAgent
|
|
@@ -7074,8 +7120,6 @@ var BasicLlmRequestProcessor = class extends BaseLlmRequestProcessor {
|
|
|
7074
7120
|
llmRequest.liveConnectConfig.realtimeInputConfig = runConfig.realtimeInputConfig;
|
|
7075
7121
|
llmRequest.liveConnectConfig.enableAffectiveDialog = runConfig.enableAffectiveDialog;
|
|
7076
7122
|
llmRequest.liveConnectConfig.proactivity = runConfig.proactivity;
|
|
7077
|
-
const tools = await agent.canonicalTools();
|
|
7078
|
-
llmRequest.appendTools(tools);
|
|
7079
7123
|
for await (const _ of []) {
|
|
7080
7124
|
yield _;
|
|
7081
7125
|
}
|
|
@@ -8088,6 +8132,9 @@ var IdentityLlmRequestProcessor = class extends BaseLlmRequestProcessor {
|
|
|
8088
8132
|
};
|
|
8089
8133
|
var requestProcessor5 = new IdentityLlmRequestProcessor();
|
|
8090
8134
|
|
|
8135
|
+
// src/flows/llm-flows/instructions.ts
|
|
8136
|
+
import { zodToJsonSchema as zodToJsonSchema2 } from "zod-to-json-schema";
|
|
8137
|
+
|
|
8091
8138
|
// src/utils/instructions-utils.ts
|
|
8092
8139
|
async function injectSessionState(template, readonlyContext) {
|
|
8093
8140
|
const invocationContext = readonlyContext._invocationContext;
|
|
@@ -8202,6 +8249,22 @@ var InstructionsLlmRequestProcessor = class extends BaseLlmRequestProcessor {
|
|
|
8202
8249
|
}
|
|
8203
8250
|
llmRequest.appendInstructions([instruction]);
|
|
8204
8251
|
}
|
|
8252
|
+
if (agent.outputSchema) {
|
|
8253
|
+
try {
|
|
8254
|
+
const raw = zodToJsonSchema2(agent.outputSchema, {
|
|
8255
|
+
target: "jsonSchema7",
|
|
8256
|
+
$refStrategy: "none"
|
|
8257
|
+
});
|
|
8258
|
+
const { $schema, ...json } = raw || {};
|
|
8259
|
+
llmRequest.appendInstructions([
|
|
8260
|
+
"You must respond with application/json that validates against this JSON Schema:",
|
|
8261
|
+
"```json",
|
|
8262
|
+
JSON.stringify(json, null, 2),
|
|
8263
|
+
"```"
|
|
8264
|
+
]);
|
|
8265
|
+
} catch {
|
|
8266
|
+
}
|
|
8267
|
+
}
|
|
8205
8268
|
for await (const _ of []) {
|
|
8206
8269
|
yield _;
|
|
8207
8270
|
}
|
|
@@ -8493,12 +8556,87 @@ function removeThoughtFromRequest(llmRequest) {
|
|
|
8493
8556
|
var requestProcessor7 = new NlPlanningRequestProcessor();
|
|
8494
8557
|
var responseProcessor2 = new NlPlanningResponseProcessor();
|
|
8495
8558
|
|
|
8559
|
+
// src/flows/llm-flows/output-schema.ts
|
|
8560
|
+
init_logger();
|
|
8561
|
+
var OutputSchemaResponseProcessor = class extends BaseLlmResponseProcessor {
|
|
8562
|
+
logger = new Logger({ name: "OutputSchemaResponseProcessor" });
|
|
8563
|
+
async *runAsync(invocationContext, llmResponse) {
|
|
8564
|
+
if (!llmResponse || !llmResponse.content || !llmResponse.content.parts || llmResponse.content.parts.length === 0) {
|
|
8565
|
+
return;
|
|
8566
|
+
}
|
|
8567
|
+
const agent = invocationContext.agent;
|
|
8568
|
+
if (!("outputSchema" in agent) || !agent.outputSchema) {
|
|
8569
|
+
return;
|
|
8570
|
+
}
|
|
8571
|
+
let textContent = llmResponse.content.parts.map((part) => {
|
|
8572
|
+
if (part && typeof part === "object" && "text" in part) {
|
|
8573
|
+
return part.text || "";
|
|
8574
|
+
}
|
|
8575
|
+
return "";
|
|
8576
|
+
}).join("");
|
|
8577
|
+
if (!textContent.trim()) {
|
|
8578
|
+
return;
|
|
8579
|
+
}
|
|
8580
|
+
try {
|
|
8581
|
+
const parsed = JSON.parse(textContent);
|
|
8582
|
+
const validated = agent.outputSchema.parse(parsed);
|
|
8583
|
+
textContent = JSON.stringify(validated, null, 2);
|
|
8584
|
+
llmResponse.content.parts = llmResponse.content.parts.map((part) => {
|
|
8585
|
+
if (part && typeof part === "object" && "text" in part) {
|
|
8586
|
+
return {
|
|
8587
|
+
...part,
|
|
8588
|
+
text: textContent
|
|
8589
|
+
};
|
|
8590
|
+
}
|
|
8591
|
+
return part;
|
|
8592
|
+
});
|
|
8593
|
+
this.logger.debug("Output schema validation successful", {
|
|
8594
|
+
agent: agent.name,
|
|
8595
|
+
originalLength: textContent.length,
|
|
8596
|
+
validatedKeys: Object.keys(validated)
|
|
8597
|
+
});
|
|
8598
|
+
} catch (error) {
|
|
8599
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
8600
|
+
const detailedError = `Output schema validation failed for agent '${agent.name}': ${errorMessage}`;
|
|
8601
|
+
this.logger.error(detailedError, {
|
|
8602
|
+
agent: agent.name,
|
|
8603
|
+
responseContent: textContent.substring(0, 200) + (textContent.length > 200 ? "..." : ""),
|
|
8604
|
+
error: errorMessage
|
|
8605
|
+
});
|
|
8606
|
+
llmResponse.errorCode = "OUTPUT_SCHEMA_VALIDATION_FAILED";
|
|
8607
|
+
llmResponse.errorMessage = detailedError;
|
|
8608
|
+
llmResponse.error = new Error(detailedError);
|
|
8609
|
+
const errorEvent = new Event({
|
|
8610
|
+
id: Event.newId(),
|
|
8611
|
+
invocationId: invocationContext.invocationId,
|
|
8612
|
+
author: agent.name,
|
|
8613
|
+
branch: invocationContext.branch,
|
|
8614
|
+
content: {
|
|
8615
|
+
role: "assistant",
|
|
8616
|
+
parts: [
|
|
8617
|
+
{
|
|
8618
|
+
text: `Error: ${detailedError}`
|
|
8619
|
+
}
|
|
8620
|
+
]
|
|
8621
|
+
}
|
|
8622
|
+
});
|
|
8623
|
+
errorEvent.errorCode = "OUTPUT_SCHEMA_VALIDATION_FAILED";
|
|
8624
|
+
errorEvent.errorMessage = detailedError;
|
|
8625
|
+
errorEvent.error = new Error(detailedError);
|
|
8626
|
+
yield errorEvent;
|
|
8627
|
+
}
|
|
8628
|
+
}
|
|
8629
|
+
};
|
|
8630
|
+
var responseProcessor3 = new OutputSchemaResponseProcessor();
|
|
8631
|
+
|
|
8496
8632
|
// src/flows/llm-flows/shared-memory.ts
|
|
8497
8633
|
var SharedMemoryRequestProcessor = class extends BaseLlmRequestProcessor {
|
|
8498
8634
|
async *runAsync(invocationContext, llmRequest) {
|
|
8499
8635
|
const memoryService = invocationContext.memoryService;
|
|
8500
8636
|
if (!memoryService) return;
|
|
8501
|
-
const lastUserEvent = invocationContext.session.events.findLast(
|
|
8637
|
+
const lastUserEvent = invocationContext.session.events.findLast(
|
|
8638
|
+
(e) => e.author === "user" && e.content?.parts?.length
|
|
8639
|
+
);
|
|
8502
8640
|
if (!lastUserEvent) return;
|
|
8503
8641
|
const query = (lastUserEvent.content.parts ?? []).map((p) => p.text || "").join(" ");
|
|
8504
8642
|
const results = await memoryService.searchMemory({
|
|
@@ -8557,8 +8695,10 @@ var SingleFlow = class extends BaseLlmFlow {
|
|
|
8557
8695
|
this.responseProcessors.push(
|
|
8558
8696
|
responseProcessor2,
|
|
8559
8697
|
// Phase 5: NL Planning
|
|
8698
|
+
responseProcessor3,
|
|
8699
|
+
// Phase 6: Output Schema validation and parsing - validates response against agent's output schema
|
|
8560
8700
|
responseProcessor
|
|
8561
|
-
// Phase
|
|
8701
|
+
// Phase 7: Code Execution (placeholder)
|
|
8562
8702
|
);
|
|
8563
8703
|
this.logger.debug("SingleFlow initialized with processors");
|
|
8564
8704
|
}
|
|
@@ -8731,12 +8871,26 @@ var LlmAgent = class _LlmAgent extends BaseAgent {
|
|
|
8731
8871
|
* The input schema when agent is used as a tool
|
|
8732
8872
|
*/
|
|
8733
8873
|
inputSchema;
|
|
8734
|
-
// Schema type - depends on specific implementation
|
|
8735
8874
|
/**
|
|
8736
8875
|
* The output schema when agent replies
|
|
8737
8876
|
*/
|
|
8738
8877
|
outputSchema;
|
|
8739
|
-
|
|
8878
|
+
/**
|
|
8879
|
+
* Callback or list of callbacks to be called before calling the LLM
|
|
8880
|
+
*/
|
|
8881
|
+
beforeModelCallback;
|
|
8882
|
+
/**
|
|
8883
|
+
* Callback or list of callbacks to be called after calling the LLM
|
|
8884
|
+
*/
|
|
8885
|
+
afterModelCallback;
|
|
8886
|
+
/**
|
|
8887
|
+
* Callback or list of callbacks to be called before calling a tool
|
|
8888
|
+
*/
|
|
8889
|
+
beforeToolCallback;
|
|
8890
|
+
/**
|
|
8891
|
+
* Callback or list of callbacks to be called after calling a tool
|
|
8892
|
+
*/
|
|
8893
|
+
afterToolCallback;
|
|
8740
8894
|
logger = new Logger({ name: "LlmAgent" });
|
|
8741
8895
|
/**
|
|
8742
8896
|
* Constructor for LlmAgent
|
|
@@ -8767,6 +8921,11 @@ var LlmAgent = class _LlmAgent extends BaseAgent {
|
|
|
8767
8921
|
this.generateContentConfig = config.generateContentConfig;
|
|
8768
8922
|
this.inputSchema = config.inputSchema;
|
|
8769
8923
|
this.outputSchema = config.outputSchema;
|
|
8924
|
+
this.beforeModelCallback = config.beforeModelCallback;
|
|
8925
|
+
this.afterModelCallback = config.afterModelCallback;
|
|
8926
|
+
this.beforeToolCallback = config.beforeToolCallback;
|
|
8927
|
+
this.afterToolCallback = config.afterToolCallback;
|
|
8928
|
+
this.validateOutputSchemaConfig();
|
|
8770
8929
|
}
|
|
8771
8930
|
/**
|
|
8772
8931
|
* The resolved model field as BaseLLM
|
|
@@ -8783,13 +8942,15 @@ var LlmAgent = class _LlmAgent extends BaseAgent {
|
|
|
8783
8942
|
return new AiSdkLlm(this.model);
|
|
8784
8943
|
}
|
|
8785
8944
|
let ancestorAgent = this.parentAgent;
|
|
8786
|
-
while (ancestorAgent !== null) {
|
|
8945
|
+
while (ancestorAgent !== null && ancestorAgent !== void 0) {
|
|
8787
8946
|
if (ancestorAgent instanceof _LlmAgent) {
|
|
8788
8947
|
return ancestorAgent.canonicalModel;
|
|
8789
8948
|
}
|
|
8790
8949
|
ancestorAgent = ancestorAgent.parentAgent;
|
|
8791
8950
|
}
|
|
8792
|
-
throw new Error(
|
|
8951
|
+
throw new Error(
|
|
8952
|
+
`No model found for agent "${this.name}". Please specify a model directly on this agent using the 'model' property`
|
|
8953
|
+
);
|
|
8793
8954
|
}
|
|
8794
8955
|
/**
|
|
8795
8956
|
* The resolved instruction field to construct instruction for this agent
|
|
@@ -8829,6 +8990,80 @@ var LlmAgent = class _LlmAgent extends BaseAgent {
|
|
|
8829
8990
|
}
|
|
8830
8991
|
return resolvedTools;
|
|
8831
8992
|
}
|
|
8993
|
+
/**
|
|
8994
|
+
* Gets the canonical before model callbacks as an array
|
|
8995
|
+
*/
|
|
8996
|
+
get canonicalBeforeModelCallbacks() {
|
|
8997
|
+
if (!this.beforeModelCallback) {
|
|
8998
|
+
return [];
|
|
8999
|
+
}
|
|
9000
|
+
if (Array.isArray(this.beforeModelCallback)) {
|
|
9001
|
+
return this.beforeModelCallback;
|
|
9002
|
+
}
|
|
9003
|
+
return [this.beforeModelCallback];
|
|
9004
|
+
}
|
|
9005
|
+
/**
|
|
9006
|
+
* Gets the canonical after model callbacks as an array
|
|
9007
|
+
*/
|
|
9008
|
+
get canonicalAfterModelCallbacks() {
|
|
9009
|
+
if (!this.afterModelCallback) {
|
|
9010
|
+
return [];
|
|
9011
|
+
}
|
|
9012
|
+
if (Array.isArray(this.afterModelCallback)) {
|
|
9013
|
+
return this.afterModelCallback;
|
|
9014
|
+
}
|
|
9015
|
+
return [this.afterModelCallback];
|
|
9016
|
+
}
|
|
9017
|
+
/**
|
|
9018
|
+
* Gets the canonical before tool callbacks as an array
|
|
9019
|
+
*/
|
|
9020
|
+
get canonicalBeforeToolCallbacks() {
|
|
9021
|
+
if (!this.beforeToolCallback) {
|
|
9022
|
+
return [];
|
|
9023
|
+
}
|
|
9024
|
+
if (Array.isArray(this.beforeToolCallback)) {
|
|
9025
|
+
return this.beforeToolCallback;
|
|
9026
|
+
}
|
|
9027
|
+
return [this.beforeToolCallback];
|
|
9028
|
+
}
|
|
9029
|
+
/**
|
|
9030
|
+
* Gets the canonical after tool callbacks as an array
|
|
9031
|
+
*/
|
|
9032
|
+
get canonicalAfterToolCallbacks() {
|
|
9033
|
+
if (!this.afterToolCallback) {
|
|
9034
|
+
return [];
|
|
9035
|
+
}
|
|
9036
|
+
if (Array.isArray(this.afterToolCallback)) {
|
|
9037
|
+
return this.afterToolCallback;
|
|
9038
|
+
}
|
|
9039
|
+
return [this.afterToolCallback];
|
|
9040
|
+
}
|
|
9041
|
+
/**
|
|
9042
|
+
* Validates output schema configuration
|
|
9043
|
+
* This matches the Python implementation's __check_output_schema
|
|
9044
|
+
*/
|
|
9045
|
+
validateOutputSchemaConfig() {
|
|
9046
|
+
if (!this.outputSchema) {
|
|
9047
|
+
return;
|
|
9048
|
+
}
|
|
9049
|
+
if (!this.disallowTransferToParent || !this.disallowTransferToPeers) {
|
|
9050
|
+
this.logger.warn(
|
|
9051
|
+
`Invalid config for agent ${this.name}: output_schema cannot co-exist with agent transfer configurations. Setting disallow_transfer_to_parent=true, disallow_transfer_to_peers=true`
|
|
9052
|
+
);
|
|
9053
|
+
this.disallowTransferToParent = true;
|
|
9054
|
+
this.disallowTransferToPeers = true;
|
|
9055
|
+
}
|
|
9056
|
+
if (this.subAgents && this.subAgents.length > 0) {
|
|
9057
|
+
throw new Error(
|
|
9058
|
+
`Invalid config for agent ${this.name}: if output_schema is set, sub_agents must be empty to disable agent transfer.`
|
|
9059
|
+
);
|
|
9060
|
+
}
|
|
9061
|
+
if (this.tools && this.tools.length > 0) {
|
|
9062
|
+
throw new Error(
|
|
9063
|
+
`Invalid config for agent ${this.name}: if output_schema is set, tools must be empty`
|
|
9064
|
+
);
|
|
9065
|
+
}
|
|
9066
|
+
}
|
|
8832
9067
|
/**
|
|
8833
9068
|
* Gets the appropriate LLM flow for this agent
|
|
8834
9069
|
* This matches the Python implementation's _llm_flow property
|
|
@@ -8844,8 +9079,28 @@ var LlmAgent = class _LlmAgent extends BaseAgent {
|
|
|
8844
9079
|
* This matches the Python implementation's __maybe_save_output_to_state
|
|
8845
9080
|
*/
|
|
8846
9081
|
maybeSaveOutputToState(event) {
|
|
9082
|
+
if (event.author !== this.name) {
|
|
9083
|
+
this.logger.debug(
|
|
9084
|
+
`Skipping output save for agent ${this.name}: event authored by ${event.author}`
|
|
9085
|
+
);
|
|
9086
|
+
return;
|
|
9087
|
+
}
|
|
8847
9088
|
if (this.outputKey && event.isFinalResponse() && event.content?.parts) {
|
|
8848
|
-
|
|
9089
|
+
let result = event.content.parts.map((part) => part.text || "").join("");
|
|
9090
|
+
if (this.outputSchema) {
|
|
9091
|
+
if (!result.trim()) {
|
|
9092
|
+
return;
|
|
9093
|
+
}
|
|
9094
|
+
try {
|
|
9095
|
+
const parsed = JSON.parse(result);
|
|
9096
|
+
result = this.outputSchema.parse(parsed);
|
|
9097
|
+
} catch (error) {
|
|
9098
|
+
this.logger.error("Failed to validate output with schema:", error);
|
|
9099
|
+
throw new Error(
|
|
9100
|
+
`Output validation failed: ${error instanceof Error ? error.message : String(error)}`
|
|
9101
|
+
);
|
|
9102
|
+
}
|
|
9103
|
+
}
|
|
8849
9104
|
if (result) {
|
|
8850
9105
|
if (!event.actions.stateDelta) {
|
|
8851
9106
|
event.actions.stateDelta = {};
|
|
@@ -8858,19 +9113,19 @@ var LlmAgent = class _LlmAgent extends BaseAgent {
|
|
|
8858
9113
|
* Core logic to run this agent via text-based conversation
|
|
8859
9114
|
* This matches the Python implementation's _run_async_impl
|
|
8860
9115
|
*/
|
|
8861
|
-
async *runAsyncImpl(
|
|
9116
|
+
async *runAsyncImpl(context4) {
|
|
8862
9117
|
this.logger.debug(`Starting LlmAgent execution for "${this.name}"`);
|
|
8863
9118
|
try {
|
|
8864
|
-
for await (const event of this.llmFlow.runAsync(
|
|
9119
|
+
for await (const event of this.llmFlow.runAsync(context4)) {
|
|
8865
9120
|
this.maybeSaveOutputToState(event);
|
|
8866
9121
|
yield event;
|
|
8867
9122
|
}
|
|
8868
9123
|
} catch (error) {
|
|
8869
9124
|
this.logger.error("Error in LlmAgent execution:", error);
|
|
8870
9125
|
const errorEvent = new Event({
|
|
8871
|
-
invocationId:
|
|
9126
|
+
invocationId: context4.invocationId,
|
|
8872
9127
|
author: this.name,
|
|
8873
|
-
branch:
|
|
9128
|
+
branch: context4.branch,
|
|
8874
9129
|
content: {
|
|
8875
9130
|
parts: [
|
|
8876
9131
|
{
|
|
@@ -9138,7 +9393,7 @@ var LangGraphAgent = class extends BaseAgent {
|
|
|
9138
9393
|
/**
|
|
9139
9394
|
* Gets the next nodes to execute based on the current node and its result
|
|
9140
9395
|
*/
|
|
9141
|
-
async getNextNodes(currentNode, lastEvent,
|
|
9396
|
+
async getNextNodes(currentNode, lastEvent, context4) {
|
|
9142
9397
|
if (!currentNode.targets || currentNode.targets.length === 0) {
|
|
9143
9398
|
return [];
|
|
9144
9399
|
}
|
|
@@ -9150,7 +9405,7 @@ var LangGraphAgent = class extends BaseAgent {
|
|
|
9150
9405
|
continue;
|
|
9151
9406
|
}
|
|
9152
9407
|
if (targetNode.condition) {
|
|
9153
|
-
const shouldExecute = await targetNode.condition(lastEvent,
|
|
9408
|
+
const shouldExecute = await targetNode.condition(lastEvent, context4);
|
|
9154
9409
|
if (!shouldExecute) {
|
|
9155
9410
|
this.logger.debug(`Skipping node "${targetName}" due to condition`);
|
|
9156
9411
|
continue;
|
|
@@ -9163,7 +9418,7 @@ var LangGraphAgent = class extends BaseAgent {
|
|
|
9163
9418
|
/**
|
|
9164
9419
|
* Core logic to run this agent via text-based conversation.
|
|
9165
9420
|
*/
|
|
9166
|
-
async *runAsyncImpl(
|
|
9421
|
+
async *runAsyncImpl(context4) {
|
|
9167
9422
|
this.logger.debug(
|
|
9168
9423
|
`Starting graph execution from root node "${this.rootNode}"`
|
|
9169
9424
|
);
|
|
@@ -9185,7 +9440,7 @@ var LangGraphAgent = class extends BaseAgent {
|
|
|
9185
9440
|
return;
|
|
9186
9441
|
}
|
|
9187
9442
|
let stepCount = 0;
|
|
9188
|
-
const nodesToExecute = [{ node: rootNode, context }];
|
|
9443
|
+
const nodesToExecute = [{ node: rootNode, context: context4 }];
|
|
9189
9444
|
const executedNodes = [];
|
|
9190
9445
|
let lastEvent = null;
|
|
9191
9446
|
while (nodesToExecute.length > 0 && stepCount < this.maxSteps) {
|
|
@@ -9193,7 +9448,7 @@ var LangGraphAgent = class extends BaseAgent {
|
|
|
9193
9448
|
const { node } = nodesToExecute.shift();
|
|
9194
9449
|
this.logger.debug(`Step ${stepCount}: Executing node "${node.name}"`);
|
|
9195
9450
|
executedNodes.push(node.name);
|
|
9196
|
-
const childContext =
|
|
9451
|
+
const childContext = context4.createChildContext(node.agent);
|
|
9197
9452
|
try {
|
|
9198
9453
|
const nodeEvents = [];
|
|
9199
9454
|
for await (const event of node.agent.runAsync(childContext)) {
|
|
@@ -9206,7 +9461,7 @@ var LangGraphAgent = class extends BaseAgent {
|
|
|
9206
9461
|
events: nodeEvents
|
|
9207
9462
|
});
|
|
9208
9463
|
if (lastEvent) {
|
|
9209
|
-
const nextNodes = await this.getNextNodes(node, lastEvent,
|
|
9464
|
+
const nextNodes = await this.getNextNodes(node, lastEvent, context4);
|
|
9210
9465
|
for (const nextNode of nextNodes) {
|
|
9211
9466
|
nodesToExecute.push({
|
|
9212
9467
|
node: nextNode,
|
|
@@ -9249,8 +9504,8 @@ var LangGraphAgent = class extends BaseAgent {
|
|
|
9249
9504
|
* Core logic to run this agent via video/audio-based conversation.
|
|
9250
9505
|
* For LangGraph, this follows the same execution pattern as text-based.
|
|
9251
9506
|
*/
|
|
9252
|
-
async *runLiveImpl(
|
|
9253
|
-
yield* this.runAsyncImpl(
|
|
9507
|
+
async *runLiveImpl(context4) {
|
|
9508
|
+
yield* this.runAsyncImpl(context4);
|
|
9254
9509
|
}
|
|
9255
9510
|
/**
|
|
9256
9511
|
* Gets the execution results from the last run
|
|
@@ -9303,7 +9558,7 @@ var LangGraphAgent = class extends BaseAgent {
|
|
|
9303
9558
|
import { generateId } from "ai";
|
|
9304
9559
|
|
|
9305
9560
|
// src/runners.ts
|
|
9306
|
-
import { SpanStatusCode } from "@opentelemetry/api";
|
|
9561
|
+
import { SpanStatusCode, context as context3, trace as trace3 } from "@opentelemetry/api";
|
|
9307
9562
|
|
|
9308
9563
|
// src/agents/run-config.ts
|
|
9309
9564
|
var StreamingMode = /* @__PURE__ */ ((StreamingMode2) => {
|
|
@@ -9963,11 +10218,11 @@ var Runner = class {
|
|
|
9963
10218
|
runConfig = new RunConfig()
|
|
9964
10219
|
}) {
|
|
9965
10220
|
const span = tracer.startSpan("invocation");
|
|
10221
|
+
const spanContext = trace3.setSpan(context3.active(), span);
|
|
9966
10222
|
try {
|
|
9967
|
-
const session = await
|
|
9968
|
-
|
|
9969
|
-
userId,
|
|
9970
|
-
sessionId
|
|
10223
|
+
const session = await context3.with(
|
|
10224
|
+
spanContext,
|
|
10225
|
+
() => this.sessionService.getSession(this.appName, userId, sessionId)
|
|
9971
10226
|
);
|
|
9972
10227
|
if (!session) {
|
|
9973
10228
|
throw new Error(`Session not found: ${sessionId}`);
|
|
@@ -9977,22 +10232,34 @@ var Runner = class {
|
|
|
9977
10232
|
runConfig
|
|
9978
10233
|
});
|
|
9979
10234
|
if (newMessage) {
|
|
9980
|
-
await
|
|
9981
|
-
|
|
9982
|
-
|
|
9983
|
-
|
|
9984
|
-
|
|
10235
|
+
await context3.with(
|
|
10236
|
+
spanContext,
|
|
10237
|
+
() => this._appendNewMessageToSession(
|
|
10238
|
+
session,
|
|
10239
|
+
newMessage,
|
|
10240
|
+
invocationContext,
|
|
10241
|
+
runConfig.saveInputBlobsAsArtifacts || false
|
|
10242
|
+
)
|
|
9985
10243
|
);
|
|
9986
10244
|
}
|
|
9987
10245
|
invocationContext.agent = this._findAgentToRun(session, this.agent);
|
|
9988
|
-
|
|
9989
|
-
|
|
9990
|
-
|
|
10246
|
+
const agentGenerator = invocationContext.agent.runAsync(invocationContext);
|
|
10247
|
+
while (true) {
|
|
10248
|
+
const result = await context3.with(
|
|
10249
|
+
spanContext,
|
|
10250
|
+
() => agentGenerator.next()
|
|
10251
|
+
);
|
|
10252
|
+
if (result.done) {
|
|
10253
|
+
break;
|
|
10254
|
+
}
|
|
10255
|
+
const event = result.value;
|
|
9991
10256
|
if (!event.partial) {
|
|
9992
|
-
await
|
|
9993
|
-
|
|
9994
|
-
|
|
9995
|
-
|
|
10257
|
+
await context3.with(spanContext, async () => {
|
|
10258
|
+
await this.sessionService.appendEvent(session, event);
|
|
10259
|
+
if (this.memoryService) {
|
|
10260
|
+
await this.memoryService.addSessionToMemory(session);
|
|
10261
|
+
}
|
|
10262
|
+
});
|
|
9996
10263
|
}
|
|
9997
10264
|
yield event;
|
|
9998
10265
|
}
|
|
@@ -10188,6 +10455,14 @@ var AgentBuilder = class _AgentBuilder {
|
|
|
10188
10455
|
this.config.instruction = instruction;
|
|
10189
10456
|
return this;
|
|
10190
10457
|
}
|
|
10458
|
+
withInputSchema(schema) {
|
|
10459
|
+
this.config.inputSchema = schema;
|
|
10460
|
+
return this;
|
|
10461
|
+
}
|
|
10462
|
+
withOutputSchema(schema) {
|
|
10463
|
+
this.config.outputSchema = schema;
|
|
10464
|
+
return this;
|
|
10465
|
+
}
|
|
10191
10466
|
/**
|
|
10192
10467
|
* Add tools to the agent
|
|
10193
10468
|
* @param tools Tools to add to the agent
|
|
@@ -10394,6 +10669,14 @@ var AgentBuilder = class _AgentBuilder {
|
|
|
10394
10669
|
}
|
|
10395
10670
|
return { agent, runner, session };
|
|
10396
10671
|
}
|
|
10672
|
+
/**
|
|
10673
|
+
* Type-safe build method for agents with output schemas
|
|
10674
|
+
* Provides better type inference for the ask method return type
|
|
10675
|
+
*/
|
|
10676
|
+
async buildWithSchema() {
|
|
10677
|
+
const result = await this.build();
|
|
10678
|
+
return result;
|
|
10679
|
+
}
|
|
10397
10680
|
/**
|
|
10398
10681
|
* Quick execution helper - build and run a message
|
|
10399
10682
|
* @param message Message to send to the agent (string or full message object)
|
|
@@ -10428,7 +10711,9 @@ var AgentBuilder = class _AgentBuilder {
|
|
|
10428
10711
|
memoryService: this.memoryService,
|
|
10429
10712
|
artifactService: this.artifactService,
|
|
10430
10713
|
outputKey: this.config.outputKey,
|
|
10431
|
-
sessionService: this.sessionService
|
|
10714
|
+
sessionService: this.sessionService,
|
|
10715
|
+
inputSchema: this.config.inputSchema,
|
|
10716
|
+
outputSchema: this.config.outputSchema
|
|
10432
10717
|
});
|
|
10433
10718
|
}
|
|
10434
10719
|
case "sequential":
|
|
@@ -10487,14 +10772,16 @@ var AgentBuilder = class _AgentBuilder {
|
|
|
10487
10772
|
return `app-${this.config.name}`;
|
|
10488
10773
|
}
|
|
10489
10774
|
/**
|
|
10490
|
-
* Create enhanced runner with simplified API
|
|
10775
|
+
* Create enhanced runner with simplified API and proper typing
|
|
10491
10776
|
* @param baseRunner The base runner instance
|
|
10492
10777
|
* @param session The session instance
|
|
10493
10778
|
* @returns Enhanced runner with simplified API
|
|
10494
10779
|
*/
|
|
10495
10780
|
createEnhancedRunner(baseRunner, session) {
|
|
10496
10781
|
const sessionOptions = this.sessionOptions;
|
|
10782
|
+
const outputSchema = this.config.outputSchema;
|
|
10497
10783
|
return {
|
|
10784
|
+
__outputSchema: outputSchema,
|
|
10498
10785
|
async ask(message) {
|
|
10499
10786
|
const newMessage = typeof message === "string" ? { parts: [{ text: message }] } : typeof message === "object" && "contents" in message ? { parts: message.contents[message.contents.length - 1].parts } : message;
|
|
10500
10787
|
let response = "";
|
|
@@ -10515,6 +10802,18 @@ var AgentBuilder = class _AgentBuilder {
|
|
|
10515
10802
|
}
|
|
10516
10803
|
}
|
|
10517
10804
|
}
|
|
10805
|
+
if (outputSchema) {
|
|
10806
|
+
try {
|
|
10807
|
+
const parsed = JSON.parse(response);
|
|
10808
|
+
return outputSchema.parse(parsed);
|
|
10809
|
+
} catch (parseError) {
|
|
10810
|
+
try {
|
|
10811
|
+
return outputSchema.parse(response);
|
|
10812
|
+
} catch (validationError) {
|
|
10813
|
+
return response.trim();
|
|
10814
|
+
}
|
|
10815
|
+
}
|
|
10816
|
+
}
|
|
10518
10817
|
return response.trim();
|
|
10519
10818
|
},
|
|
10520
10819
|
runAsync(params) {
|
|
@@ -10575,7 +10874,7 @@ var VertexAiSessionService = class extends BaseSessionService {
|
|
|
10575
10874
|
path: `reasoningEngines/${reasoningEngineId}/sessions`,
|
|
10576
10875
|
request_dict: sessionJsonDict
|
|
10577
10876
|
});
|
|
10578
|
-
console.
|
|
10877
|
+
console.debug("Create Session response", apiResponse);
|
|
10579
10878
|
const createdSessionId = apiResponse.name.split("/").slice(-3, -2)[0];
|
|
10580
10879
|
const operationId = apiResponse.name.split("/").pop();
|
|
10581
10880
|
let maxRetryAttempt = 5;
|