@google/adk 0.2.0 → 0.2.2
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 +1 -7
- package/dist/cjs/agents/base_agent.js +14 -2
- package/dist/cjs/agents/content_processor_utils.js +2 -2
- package/dist/cjs/agents/functions.js +6 -3
- package/dist/cjs/agents/llm_agent.js +331 -4
- package/dist/cjs/auth/exchanger/base_credential_exchanger.js +40 -0
- package/dist/cjs/auth/exchanger/credential_exchanger_registry.js +59 -0
- package/dist/cjs/code_executors/code_execution_utils.js +2 -2
- package/dist/cjs/code_executors/code_executor_context.js +2 -2
- package/dist/cjs/common.js +7 -0
- package/dist/cjs/index.js +63 -5
- package/dist/cjs/index.js.map +4 -4
- package/dist/cjs/models/base_llm.js +16 -4
- package/dist/cjs/runner/runner.js +10 -1
- package/dist/cjs/sessions/in_memory_session_service.js +3 -3
- package/dist/cjs/sessions/state.js +1 -1
- package/dist/cjs/tools/agent_tool.js +2 -2
- package/dist/cjs/tools/mcp/mcp_session_manager.js +7 -1
- package/dist/cjs/utils/gemini_schema_util.js +16 -0
- package/dist/cjs/version.js +2 -2
- package/dist/esm/agents/base_agent.js +12 -1
- package/dist/esm/agents/content_processor_utils.js +2 -2
- package/dist/esm/agents/functions.js +6 -3
- package/dist/esm/agents/llm_agent.js +330 -4
- package/dist/esm/auth/exchanger/base_credential_exchanger.js +10 -0
- package/dist/esm/auth/exchanger/credential_exchanger_registry.js +29 -0
- package/dist/esm/code_executors/code_execution_utils.js +2 -2
- package/dist/esm/code_executors/code_executor_context.js +2 -2
- package/dist/esm/common.js +6 -2
- package/dist/esm/index.js +63 -5
- package/dist/esm/index.js.map +4 -4
- package/dist/esm/models/base_llm.js +14 -3
- package/dist/esm/runner/runner.js +10 -1
- package/dist/esm/sessions/in_memory_session_service.js +3 -3
- package/dist/esm/sessions/state.js +1 -1
- package/dist/esm/tools/agent_tool.js +2 -2
- package/dist/esm/tools/function_tool.js +3 -1
- package/dist/esm/tools/mcp/mcp_session_manager.js +7 -1
- package/dist/esm/utils/gemini_schema_util.js +16 -0
- package/dist/esm/version.js +2 -2
- package/dist/types/agents/base_agent.d.ts +15 -0
- package/dist/types/agents/functions.d.ts +2 -0
- package/dist/types/agents/llm_agent.d.ts +23 -0
- package/dist/types/auth/exchanger/base_credential_exchanger.d.ts +32 -0
- package/dist/types/auth/exchanger/credential_exchanger_registry.d.ts +28 -0
- package/dist/types/code_executors/code_executor_context.d.ts +0 -5
- package/dist/types/common.d.ts +3 -2
- package/dist/types/models/base_llm.d.ts +16 -0
- package/dist/types/sessions/in_memory_session_service.d.ts +0 -5
- package/dist/types/sessions/state.d.ts +2 -2
- package/dist/types/tools/function_tool.d.ts +3 -3
- package/dist/types/tools/tool_confirmation.d.ts +1 -1
- package/dist/types/utils/gemini_schema_util.d.ts +2 -2
- package/dist/types/version.d.ts +2 -2
- package/dist/web/agents/base_agent.js +12 -1
- package/dist/web/agents/content_processor_utils.js +2 -2
- package/dist/web/agents/functions.js +6 -3
- package/dist/web/agents/llm_agent.js +315 -4
- package/dist/web/auth/exchanger/base_credential_exchanger.js +10 -0
- package/dist/web/auth/exchanger/credential_exchanger_registry.js +29 -0
- package/dist/web/code_executors/code_execution_utils.js +2 -2
- package/dist/web/code_executors/code_executor_context.js +2 -2
- package/dist/web/common.js +6 -2
- package/dist/web/index.js +6 -1
- package/dist/web/index.js.map +4 -4
- package/dist/web/models/base_llm.js +14 -3
- package/dist/web/runner/runner.js +10 -1
- package/dist/web/sessions/in_memory_session_service.js +3 -3
- package/dist/web/sessions/state.js +1 -1
- package/dist/web/tools/agent_tool.js +2 -2
- package/dist/web/tools/function_tool.js +3 -1
- package/dist/web/tools/mcp/mcp_session_manager.js +7 -1
- package/dist/web/utils/gemini_schema_util.js +16 -0
- package/dist/web/version.js +2 -2
- package/package.json +3 -1
|
@@ -24,7 +24,8 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
24
24
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
25
25
|
var base_llm_exports = {};
|
|
26
26
|
__export(base_llm_exports, {
|
|
27
|
-
BaseLlm: () => BaseLlm
|
|
27
|
+
BaseLlm: () => BaseLlm,
|
|
28
|
+
isBaseLlm: () => isBaseLlm
|
|
28
29
|
});
|
|
29
30
|
module.exports = __toCommonJS(base_llm_exports);
|
|
30
31
|
var import_client_labels = require("../utils/client_labels.js");
|
|
@@ -33,6 +34,12 @@ var import_client_labels = require("../utils/client_labels.js");
|
|
|
33
34
|
* Copyright 2025 Google LLC
|
|
34
35
|
* SPDX-License-Identifier: Apache-2.0
|
|
35
36
|
*/
|
|
37
|
+
var _a;
|
|
38
|
+
const BASE_MODEL_SYMBOL = Symbol.for("google.adk.baseModel");
|
|
39
|
+
function isBaseLlm(obj) {
|
|
40
|
+
return typeof obj === "object" && obj !== null && BASE_MODEL_SYMBOL in obj && obj[BASE_MODEL_SYMBOL] === true;
|
|
41
|
+
}
|
|
42
|
+
_a = BASE_MODEL_SYMBOL;
|
|
36
43
|
class BaseLlm {
|
|
37
44
|
/**
|
|
38
45
|
* Creates an instance of BaseLLM.
|
|
@@ -41,6 +48,10 @@ class BaseLlm {
|
|
|
41
48
|
* gemini-1.5-flash-001.
|
|
42
49
|
*/
|
|
43
50
|
constructor({ model }) {
|
|
51
|
+
/**
|
|
52
|
+
* A unique symbol to identify BaseLlm classes.
|
|
53
|
+
*/
|
|
54
|
+
this[_a] = true;
|
|
44
55
|
this.model = model;
|
|
45
56
|
}
|
|
46
57
|
get trackingHeaders() {
|
|
@@ -57,7 +68,7 @@ class BaseLlm {
|
|
|
57
68
|
* @param llmRequest LlmRequest, the request to send to the LLM.
|
|
58
69
|
*/
|
|
59
70
|
maybeAppendUserContent(llmRequest) {
|
|
60
|
-
var
|
|
71
|
+
var _a2;
|
|
61
72
|
if (llmRequest.contents.length === 0) {
|
|
62
73
|
llmRequest.contents.push({
|
|
63
74
|
role: "user",
|
|
@@ -66,7 +77,7 @@ class BaseLlm {
|
|
|
66
77
|
]
|
|
67
78
|
});
|
|
68
79
|
}
|
|
69
|
-
if (((
|
|
80
|
+
if (((_a2 = llmRequest.contents[llmRequest.contents.length - 1]) == null ? void 0 : _a2.role) !== "user") {
|
|
70
81
|
llmRequest.contents.push({
|
|
71
82
|
role: "user",
|
|
72
83
|
parts: [{
|
|
@@ -82,5 +93,6 @@ class BaseLlm {
|
|
|
82
93
|
BaseLlm.supportedModels = [];
|
|
83
94
|
// Annotate the CommonJS export names for ESM import in node:
|
|
84
95
|
0 && (module.exports = {
|
|
85
|
-
BaseLlm
|
|
96
|
+
BaseLlm,
|
|
97
|
+
isBaseLlm
|
|
86
98
|
});
|
|
@@ -32,6 +32,7 @@ var import_api = require("@opentelemetry/api");
|
|
|
32
32
|
var import_invocation_context = require("../agents/invocation_context.js");
|
|
33
33
|
var import_llm_agent = require("../agents/llm_agent.js");
|
|
34
34
|
var import_run_config = require("../agents/run_config.js");
|
|
35
|
+
var import_built_in_code_executor = require("../code_executors/built_in_code_executor.js");
|
|
35
36
|
var import_event = require("../events/event.js");
|
|
36
37
|
var import_event_actions = require("../events/event_actions.js");
|
|
37
38
|
var import_plugin_manager = require("../plugins/plugin_manager.js");
|
|
@@ -77,6 +78,11 @@ class Runner {
|
|
|
77
78
|
try {
|
|
78
79
|
const session = await this.sessionService.getSession({ appName: this.appName, userId, sessionId });
|
|
79
80
|
if (!session) {
|
|
81
|
+
if (!this.appName) {
|
|
82
|
+
throw new Error(
|
|
83
|
+
`Session lookup failed: appName must be provided in runner constructor`
|
|
84
|
+
);
|
|
85
|
+
}
|
|
80
86
|
throw new Error(`Session not found: ${sessionId}`);
|
|
81
87
|
}
|
|
82
88
|
if (runConfig.supportCfc && this.agent instanceof import_llm_agent.LlmAgent) {
|
|
@@ -85,6 +91,9 @@ class Runner {
|
|
|
85
91
|
throw new Error(`CFC is not supported for model: ${modelName} in agent: ${this.agent.name}`);
|
|
86
92
|
}
|
|
87
93
|
}
|
|
94
|
+
if (this.agent instanceof import_llm_agent.LlmAgent && !(this.agent.codeExecutor instanceof import_built_in_code_executor.BuiltInCodeExecutor)) {
|
|
95
|
+
this.agent.codeExecutor = new import_built_in_code_executor.BuiltInCodeExecutor();
|
|
96
|
+
}
|
|
88
97
|
const invocationContext = new import_invocation_context.InvocationContext({
|
|
89
98
|
artifactService: this.artifactService,
|
|
90
99
|
sessionService: this.sessionService,
|
|
@@ -106,7 +115,7 @@ class Runner {
|
|
|
106
115
|
}
|
|
107
116
|
if (newMessage) {
|
|
108
117
|
if (!((_a = newMessage.parts) == null ? void 0 : _a.length)) {
|
|
109
|
-
throw new Error("No parts in the
|
|
118
|
+
throw new Error("No parts in the newMessage.");
|
|
110
119
|
}
|
|
111
120
|
if (runConfig.saveInputBlobsAsArtifacts) {
|
|
112
121
|
await this.saveArtifacts(
|
|
@@ -27,7 +27,7 @@ __export(in_memory_session_service_exports, {
|
|
|
27
27
|
InMemorySessionService: () => InMemorySessionService
|
|
28
28
|
});
|
|
29
29
|
module.exports = __toCommonJS(in_memory_session_service_exports);
|
|
30
|
-
var
|
|
30
|
+
var import_lodash = require("lodash");
|
|
31
31
|
var import_env_aware_utils = require("../utils/env_aware_utils.js");
|
|
32
32
|
var import_logger = require("../utils/logger.js");
|
|
33
33
|
var import_base_session_service = require("./base_session_service.js");
|
|
@@ -72,7 +72,7 @@ class InMemorySessionService extends import_base_session_service.BaseSessionServ
|
|
|
72
72
|
}
|
|
73
73
|
this.sessions[appName][userId][session.id] = session;
|
|
74
74
|
return Promise.resolve(
|
|
75
|
-
this.mergeState(appName, userId, (0,
|
|
75
|
+
this.mergeState(appName, userId, (0, import_lodash.cloneDeep)(session))
|
|
76
76
|
);
|
|
77
77
|
}
|
|
78
78
|
getSession({ appName, userId, sessionId, config }) {
|
|
@@ -80,7 +80,7 @@ class InMemorySessionService extends import_base_session_service.BaseSessionServ
|
|
|
80
80
|
return Promise.resolve(void 0);
|
|
81
81
|
}
|
|
82
82
|
const session = this.sessions[appName][userId][sessionId];
|
|
83
|
-
const copiedSession = (0,
|
|
83
|
+
const copiedSession = (0, import_lodash.cloneDeep)(session);
|
|
84
84
|
if (config) {
|
|
85
85
|
if (config.numRecentEvents) {
|
|
86
86
|
copiedSession.events = copiedSession.events.slice(-config.numRecentEvents);
|
|
@@ -124,8 +124,8 @@ class AgentTool extends import_base_tool.BaseTool {
|
|
|
124
124
|
return "";
|
|
125
125
|
}
|
|
126
126
|
const hasOutputSchema = this.agent instanceof import_llm_agent.LlmAgent && this.agent.outputSchema;
|
|
127
|
-
const
|
|
128
|
-
return hasOutputSchema ? JSON.parse(
|
|
127
|
+
const mergedText = lastEvent.content.parts.map((part) => part.text).filter((text) => text).join("\n");
|
|
128
|
+
return hasOutputSchema ? JSON.parse(mergedText) : mergedText;
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -48,8 +48,14 @@ class MCPSessionManager {
|
|
|
48
48
|
);
|
|
49
49
|
break;
|
|
50
50
|
case "StreamableHTTPConnectionParams":
|
|
51
|
+
const transportOptions = this.connectionParams.header ? {
|
|
52
|
+
requestInit: {
|
|
53
|
+
headers: this.connectionParams.header
|
|
54
|
+
}
|
|
55
|
+
} : void 0;
|
|
51
56
|
await client.connect(new import_streamableHttp.StreamableHTTPClientTransport(
|
|
52
|
-
new URL(this.connectionParams.url)
|
|
57
|
+
new URL(this.connectionParams.url),
|
|
58
|
+
transportOptions
|
|
53
59
|
));
|
|
54
60
|
break;
|
|
55
61
|
default:
|
|
@@ -63,6 +63,22 @@ function toGeminiSchema(mcpSchema) {
|
|
|
63
63
|
return void 0;
|
|
64
64
|
}
|
|
65
65
|
function recursiveConvert(mcp) {
|
|
66
|
+
if (!mcp.type && mcp.anyOf && Array.isArray(mcp.anyOf)) {
|
|
67
|
+
const nonNullOption = mcp.anyOf.find((opt) => {
|
|
68
|
+
const t = opt.type;
|
|
69
|
+
return t !== "null" && t !== "NULL";
|
|
70
|
+
});
|
|
71
|
+
if (nonNullOption) {
|
|
72
|
+
mcp = nonNullOption;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (!mcp.type) {
|
|
76
|
+
if (mcp.properties || mcp.$ref) {
|
|
77
|
+
mcp.type = "object";
|
|
78
|
+
} else if (mcp.items) {
|
|
79
|
+
mcp.type = "array";
|
|
80
|
+
}
|
|
81
|
+
}
|
|
66
82
|
const geminiType = toGeminiType(mcp.type);
|
|
67
83
|
const geminiSchema = { type: geminiType, description: mcp.description };
|
|
68
84
|
if (geminiType === import_genai.Type.OBJECT) {
|
package/dist/cjs/version.js
CHANGED
|
@@ -29,10 +29,10 @@ __export(version_exports, {
|
|
|
29
29
|
module.exports = __toCommonJS(version_exports);
|
|
30
30
|
/**
|
|
31
31
|
* @license
|
|
32
|
-
* Copyright
|
|
32
|
+
* Copyright 2026 Google LLC
|
|
33
33
|
* SPDX-License-Identifier: Apache-2.0
|
|
34
34
|
*/
|
|
35
|
-
const version = "0.2.
|
|
35
|
+
const version = "0.2.3";
|
|
36
36
|
// Annotate the CommonJS export names for ESM import in node:
|
|
37
37
|
0 && (module.exports = {
|
|
38
38
|
version
|
|
@@ -3,12 +3,22 @@
|
|
|
3
3
|
* Copyright 2025 Google LLC
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
+
var _a;
|
|
6
7
|
import { trace } from "@opentelemetry/api";
|
|
7
8
|
import { createEvent } from "../events/event.js";
|
|
8
9
|
import { CallbackContext } from "./callback_context.js";
|
|
9
10
|
import { InvocationContext } from "./invocation_context.js";
|
|
11
|
+
const BASE_AGENT_SIGNATURE_SYMBOL = Symbol.for("google.adk.baseAgent");
|
|
12
|
+
function isBaseAgent(obj) {
|
|
13
|
+
return typeof obj === "object" && obj !== null && BASE_AGENT_SIGNATURE_SYMBOL in obj && obj[BASE_AGENT_SIGNATURE_SYMBOL] === true;
|
|
14
|
+
}
|
|
15
|
+
_a = BASE_AGENT_SIGNATURE_SYMBOL;
|
|
10
16
|
class BaseAgent {
|
|
11
17
|
constructor(config) {
|
|
18
|
+
/**
|
|
19
|
+
* A unique symbol to identify ADK agent classes.
|
|
20
|
+
*/
|
|
21
|
+
this[_a] = true;
|
|
12
22
|
this.name = validateAgentName(config.name);
|
|
13
23
|
this.description = config.description;
|
|
14
24
|
this.parentAgent = config.parentAgent;
|
|
@@ -210,5 +220,6 @@ function getCannonicalCallback(callbacks) {
|
|
|
210
220
|
}
|
|
211
221
|
export {
|
|
212
222
|
BaseAgent,
|
|
213
|
-
getCannonicalCallback
|
|
223
|
+
getCannonicalCallback,
|
|
224
|
+
isBaseAgent
|
|
214
225
|
};
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* Copyright 2025 Google LLC
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
+
import { cloneDeep } from "lodash";
|
|
6
7
|
import { createEvent, getFunctionCalls, getFunctionResponses } from "../events/event.js";
|
|
7
|
-
import { deepClone } from "../utils/deep_clone.js";
|
|
8
8
|
import { removeClientFunctionCallId, REQUEST_CONFIRMATION_FUNCTION_CALL_NAME, REQUEST_EUC_FUNCTION_CALL_NAME } from "./functions.js";
|
|
9
9
|
function getContents(events, agentName, currentBranch) {
|
|
10
10
|
var _a, _b, _c;
|
|
@@ -30,7 +30,7 @@ function getContents(events, agentName, currentBranch) {
|
|
|
30
30
|
resultEvents = rearrangeEventsForAsyncFunctionResponsesInHistory(resultEvents);
|
|
31
31
|
const contents = [];
|
|
32
32
|
for (const event of resultEvents) {
|
|
33
|
-
const content =
|
|
33
|
+
const content = cloneDeep(event.content);
|
|
34
34
|
removeClientFunctionCallId(content);
|
|
35
35
|
contents.push(content);
|
|
36
36
|
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
import { createUserContent } from "@google/genai";
|
|
7
|
+
import { isEmpty } from "lodash";
|
|
7
8
|
import { createEvent, getFunctionCalls } from "../events/event.js";
|
|
8
9
|
import { mergeEventActions } from "../events/event_actions.js";
|
|
9
10
|
import { ToolContext } from "../tools/tool_context.js";
|
|
@@ -13,7 +14,9 @@ const AF_FUNCTION_CALL_ID_PREFIX = "adk-";
|
|
|
13
14
|
const REQUEST_EUC_FUNCTION_CALL_NAME = "adk_request_credential";
|
|
14
15
|
const REQUEST_CONFIRMATION_FUNCTION_CALL_NAME = "adk_request_confirmation";
|
|
15
16
|
const functionsExportedForTestingOnly = {
|
|
16
|
-
handleFunctionCallList
|
|
17
|
+
handleFunctionCallList,
|
|
18
|
+
generateAuthEvent,
|
|
19
|
+
generateRequestConfirmationEvent
|
|
17
20
|
};
|
|
18
21
|
function generateClientFunctionCallId() {
|
|
19
22
|
return `${AF_FUNCTION_CALL_ID_PREFIX}${randomUUID()}`;
|
|
@@ -52,7 +55,7 @@ function getLongRunningFunctionCalls(functionCalls, toolsDict) {
|
|
|
52
55
|
}
|
|
53
56
|
function generateAuthEvent(invocationContext, functionResponseEvent) {
|
|
54
57
|
var _a;
|
|
55
|
-
if (!((_a = functionResponseEvent.actions) == null ? void 0 : _a.requestedAuthConfigs)) {
|
|
58
|
+
if (!((_a = functionResponseEvent.actions) == null ? void 0 : _a.requestedAuthConfigs) || isEmpty(functionResponseEvent.actions.requestedAuthConfigs)) {
|
|
56
59
|
return void 0;
|
|
57
60
|
}
|
|
58
61
|
const parts = [];
|
|
@@ -88,7 +91,7 @@ function generateRequestConfirmationEvent({
|
|
|
88
91
|
functionResponseEvent
|
|
89
92
|
}) {
|
|
90
93
|
var _a, _b;
|
|
91
|
-
if (!((_a = functionResponseEvent.actions) == null ? void 0 : _a.requestedToolConfirmations)) {
|
|
94
|
+
if (!((_a = functionResponseEvent.actions) == null ? void 0 : _a.requestedToolConfirmations) || isEmpty(functionResponseEvent.actions.requestedToolConfirmations)) {
|
|
92
95
|
return;
|
|
93
96
|
}
|
|
94
97
|
const parts = [];
|
|
@@ -3,15 +3,23 @@
|
|
|
3
3
|
* Copyright 2025 Google LLC
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
+
import { cloneDeep } from "lodash";
|
|
6
7
|
import { z } from "zod";
|
|
8
|
+
import { BaseCodeExecutor } from "../code_executors/base_code_executor.js";
|
|
9
|
+
import { BuiltInCodeExecutor } from "../code_executors/built_in_code_executor.js";
|
|
10
|
+
import { buildCodeExecutionResultPart, buildExecutableCodePart, convertCodeExecutionParts, extractCodeAndTruncateContent } from "../code_executors/code_execution_utils.js";
|
|
11
|
+
import { CodeExecutorContext } from "../code_executors/code_executor_context.js";
|
|
7
12
|
import { createEvent, createNewEventId, getFunctionCalls, getFunctionResponses, isFinalResponse } from "../events/event.js";
|
|
8
|
-
import {
|
|
13
|
+
import { createEventActions } from "../events/event_actions.js";
|
|
14
|
+
import { isBaseLlm } from "../models/base_llm.js";
|
|
9
15
|
import { appendInstructions, setOutputSchema } from "../models/llm_request.js";
|
|
10
16
|
import { LLMRegistry } from "../models/registry.js";
|
|
17
|
+
import { State } from "../sessions/state.js";
|
|
11
18
|
import { BaseTool } from "../tools/base_tool.js";
|
|
12
19
|
import { FunctionTool } from "../tools/function_tool.js";
|
|
13
20
|
import { ToolConfirmation } from "../tools/tool_confirmation.js";
|
|
14
21
|
import { ToolContext } from "../tools/tool_context.js";
|
|
22
|
+
import { base64Decode } from "../utils/env_aware_utils.js";
|
|
15
23
|
import { logger } from "../utils/logger.js";
|
|
16
24
|
import { BaseAgent } from "./base_agent.js";
|
|
17
25
|
import { BaseLlmRequestProcessor } from "./base_llm_processor.js";
|
|
@@ -323,6 +331,321 @@ class RequestConfirmationLlmRequestProcessor extends BaseLlmRequestProcessor {
|
|
|
323
331
|
}
|
|
324
332
|
}
|
|
325
333
|
const REQUEST_CONFIRMATION_LLM_REQUEST_PROCESSOR = new RequestConfirmationLlmRequestProcessor();
|
|
334
|
+
class CodeExecutionRequestProcessor extends BaseLlmRequestProcessor {
|
|
335
|
+
async *runAsync(invocationContext, llmRequest) {
|
|
336
|
+
if (!(invocationContext.agent instanceof LlmAgent)) {
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
if (!invocationContext.agent.codeExecutor) {
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
for await (const event of runPreProcessor(invocationContext, llmRequest)) {
|
|
343
|
+
yield event;
|
|
344
|
+
}
|
|
345
|
+
if (!(invocationContext.agent.codeExecutor instanceof BaseCodeExecutor)) {
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
for (const content of llmRequest.contents) {
|
|
349
|
+
const delimeters = invocationContext.agent.codeExecutor.codeBlockDelimiters.length ? invocationContext.agent.codeExecutor.codeBlockDelimiters[0] : ["", ""];
|
|
350
|
+
const codeExecutionParts = convertCodeExecutionParts(
|
|
351
|
+
content,
|
|
352
|
+
delimeters,
|
|
353
|
+
invocationContext.agent.codeExecutor.executionResultDelimiters
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
const DATA_FILE_UTIL_MAP = {
|
|
359
|
+
"text/csv": {
|
|
360
|
+
extension: ".csv",
|
|
361
|
+
loaderCodeTemplate: "pd.read_csv('{filename}')"
|
|
362
|
+
}
|
|
363
|
+
};
|
|
364
|
+
const DATA_FILE_HELPER_LIB = `
|
|
365
|
+
import pandas as pd
|
|
366
|
+
|
|
367
|
+
def explore_df(df: pd.DataFrame) -> None:
|
|
368
|
+
"""Prints some information about a pandas DataFrame."""
|
|
369
|
+
|
|
370
|
+
with pd.option_context(
|
|
371
|
+
'display.max_columns', None, 'display.expand_frame_repr', False
|
|
372
|
+
):
|
|
373
|
+
# Print the column names to never encounter KeyError when selecting one.
|
|
374
|
+
df_dtypes = df.dtypes
|
|
375
|
+
|
|
376
|
+
# Obtain information about data types and missing values.
|
|
377
|
+
df_nulls = (len(df) - df.isnull().sum()).apply(
|
|
378
|
+
lambda x: f'{x} / {df.shape[0]} non-null'
|
|
379
|
+
)
|
|
380
|
+
|
|
381
|
+
# Explore unique total values in columns using \`.unique()\`.
|
|
382
|
+
df_unique_count = df.apply(lambda x: len(x.unique()))
|
|
383
|
+
|
|
384
|
+
# Explore unique values in columns using \`.unique()\`.
|
|
385
|
+
df_unique = df.apply(lambda x: crop(str(list(x.unique()))))
|
|
386
|
+
|
|
387
|
+
df_info = pd.concat(
|
|
388
|
+
(
|
|
389
|
+
df_dtypes.rename('Dtype'),
|
|
390
|
+
df_nulls.rename('Non-Null Count'),
|
|
391
|
+
df_unique_count.rename('Unique Values Count'),
|
|
392
|
+
df_unique.rename('Unique Values'),
|
|
393
|
+
),
|
|
394
|
+
axis=1,
|
|
395
|
+
)
|
|
396
|
+
df_info.index.name = 'Columns'
|
|
397
|
+
print(f"""Total rows: {df.shape[0]}
|
|
398
|
+
Total columns: {df.shape[1]}
|
|
399
|
+
|
|
400
|
+
{df_info}""")
|
|
401
|
+
`;
|
|
402
|
+
class CodeExecutionResponseProcessor {
|
|
403
|
+
/**
|
|
404
|
+
* Processes the LLM response asynchronously.
|
|
405
|
+
*
|
|
406
|
+
* @param invocationContext The invocation context
|
|
407
|
+
* @param llmResponse The LLM response to process
|
|
408
|
+
* @returns An async generator yielding events
|
|
409
|
+
*/
|
|
410
|
+
async *runAsync(invocationContext, llmResponse) {
|
|
411
|
+
if (llmResponse.partial) {
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
for await (const event of runPostProcessor(invocationContext, llmResponse)) {
|
|
415
|
+
yield event;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
const responseProcessor = new CodeExecutionResponseProcessor();
|
|
420
|
+
async function* runPreProcessor(invocationContext, llmRequest) {
|
|
421
|
+
const agent = invocationContext.agent;
|
|
422
|
+
if (!(agent instanceof LlmAgent)) {
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
const codeExecutor = agent.codeExecutor;
|
|
426
|
+
if (!codeExecutor || !(codeExecutor instanceof BaseCodeExecutor)) {
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
if (codeExecutor instanceof BuiltInCodeExecutor) {
|
|
430
|
+
codeExecutor.processLlmRequest(llmRequest);
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
if (!codeExecutor.optimizeDataFile) {
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
const codeExecutorContext = new CodeExecutorContext(new State(invocationContext.session.state));
|
|
437
|
+
if (codeExecutorContext.getErrorCount(invocationContext.invocationId) >= codeExecutor.errorRetryAttempts) {
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
const allInputFiles = extractAndReplaceInlineFiles(codeExecutorContext, llmRequest);
|
|
441
|
+
const processedFileNames = new Set(codeExecutorContext.getProcessedFileNames());
|
|
442
|
+
const filesToProcess = allInputFiles.filter((f) => !processedFileNames.has(f.name));
|
|
443
|
+
for (const file of filesToProcess) {
|
|
444
|
+
const codeStr = getDataFilePreprocessingCode(file);
|
|
445
|
+
if (!codeStr) {
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
const codeContent = {
|
|
449
|
+
role: "model",
|
|
450
|
+
parts: [
|
|
451
|
+
{ text: `Processing input file: \`${file.name}\`` },
|
|
452
|
+
buildExecutableCodePart(codeStr)
|
|
453
|
+
]
|
|
454
|
+
};
|
|
455
|
+
llmRequest.contents.push(cloneDeep(codeContent));
|
|
456
|
+
yield createEvent({
|
|
457
|
+
invocationId: invocationContext.invocationId,
|
|
458
|
+
author: agent.name,
|
|
459
|
+
branch: invocationContext.branch,
|
|
460
|
+
content: codeContent
|
|
461
|
+
});
|
|
462
|
+
const executionId = getOrSetExecutionId(invocationContext, codeExecutorContext);
|
|
463
|
+
const codeExecutionResult = await codeExecutor.executeCode({
|
|
464
|
+
invocationContext,
|
|
465
|
+
codeExecutionInput: {
|
|
466
|
+
code: codeStr,
|
|
467
|
+
inputFiles: [file],
|
|
468
|
+
executionId
|
|
469
|
+
}
|
|
470
|
+
});
|
|
471
|
+
codeExecutorContext.updateCodeExecutionResult({
|
|
472
|
+
invocationId: invocationContext.invocationId,
|
|
473
|
+
code: codeStr,
|
|
474
|
+
resultStdout: codeExecutionResult.stdout,
|
|
475
|
+
resultStderr: codeExecutionResult.stderr
|
|
476
|
+
});
|
|
477
|
+
codeExecutorContext.addProcessedFileNames([file.name]);
|
|
478
|
+
const executionResultEvent = await postProcessCodeExecutionResult(
|
|
479
|
+
invocationContext,
|
|
480
|
+
codeExecutorContext,
|
|
481
|
+
codeExecutionResult
|
|
482
|
+
);
|
|
483
|
+
yield executionResultEvent;
|
|
484
|
+
llmRequest.contents.push(cloneDeep(executionResultEvent.content));
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
async function* runPostProcessor(invocationContext, llmResponse) {
|
|
488
|
+
const agent = invocationContext.agent;
|
|
489
|
+
if (!(agent instanceof LlmAgent)) {
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
const codeExecutor = agent.codeExecutor;
|
|
493
|
+
if (!codeExecutor || !(codeExecutor instanceof BaseCodeExecutor)) {
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
if (!llmResponse || !llmResponse.content) {
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
if (codeExecutor instanceof BuiltInCodeExecutor) {
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
const codeExecutorContext = new CodeExecutorContext(new State(invocationContext.session.state));
|
|
503
|
+
if (codeExecutorContext.getErrorCount(invocationContext.invocationId) >= codeExecutor.errorRetryAttempts) {
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
const responseContent = llmResponse.content;
|
|
507
|
+
const codeStr = extractCodeAndTruncateContent(
|
|
508
|
+
responseContent,
|
|
509
|
+
codeExecutor.codeBlockDelimiters
|
|
510
|
+
);
|
|
511
|
+
if (!codeStr) {
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
yield createEvent({
|
|
515
|
+
invocationId: invocationContext.invocationId,
|
|
516
|
+
author: agent.name,
|
|
517
|
+
branch: invocationContext.branch,
|
|
518
|
+
content: responseContent
|
|
519
|
+
});
|
|
520
|
+
const executionId = getOrSetExecutionId(invocationContext, codeExecutorContext);
|
|
521
|
+
const codeExecutionResult = await codeExecutor.executeCode({
|
|
522
|
+
invocationContext,
|
|
523
|
+
codeExecutionInput: {
|
|
524
|
+
code: codeStr,
|
|
525
|
+
inputFiles: codeExecutorContext.getInputFiles(),
|
|
526
|
+
executionId
|
|
527
|
+
}
|
|
528
|
+
});
|
|
529
|
+
codeExecutorContext.updateCodeExecutionResult({
|
|
530
|
+
invocationId: invocationContext.invocationId,
|
|
531
|
+
code: codeStr,
|
|
532
|
+
resultStdout: codeExecutionResult.stdout,
|
|
533
|
+
resultStderr: codeExecutionResult.stderr
|
|
534
|
+
});
|
|
535
|
+
yield await postProcessCodeExecutionResult(
|
|
536
|
+
invocationContext,
|
|
537
|
+
codeExecutorContext,
|
|
538
|
+
codeExecutionResult
|
|
539
|
+
);
|
|
540
|
+
llmResponse.content = null;
|
|
541
|
+
}
|
|
542
|
+
function extractAndReplaceInlineFiles(codeExecutorContext, llmRequest) {
|
|
543
|
+
var _a;
|
|
544
|
+
const allInputFiles = codeExecutorContext.getInputFiles();
|
|
545
|
+
const savedFileNames = new Set(allInputFiles.map((f) => f.name));
|
|
546
|
+
for (let i = 0; i < llmRequest.contents.length; i++) {
|
|
547
|
+
const content = llmRequest.contents[i];
|
|
548
|
+
if (content.role !== "user" || !content.parts) {
|
|
549
|
+
continue;
|
|
550
|
+
}
|
|
551
|
+
for (let j = 0; j < content.parts.length; j++) {
|
|
552
|
+
const part = content.parts[j];
|
|
553
|
+
const mimeType = (_a = part.inlineData) == null ? void 0 : _a.mimeType;
|
|
554
|
+
if (!mimeType || !part.inlineData || !DATA_FILE_UTIL_MAP[mimeType]) {
|
|
555
|
+
continue;
|
|
556
|
+
}
|
|
557
|
+
const fileName = `data_${i + 1}_${j + 1}${DATA_FILE_UTIL_MAP[mimeType].extension}`;
|
|
558
|
+
part.text = `
|
|
559
|
+
Available file: \`${fileName}\`
|
|
560
|
+
`;
|
|
561
|
+
const file = {
|
|
562
|
+
name: fileName,
|
|
563
|
+
content: base64Decode(part.inlineData.data),
|
|
564
|
+
mimeType
|
|
565
|
+
};
|
|
566
|
+
if (!savedFileNames.has(fileName)) {
|
|
567
|
+
codeExecutorContext.addInputFiles([file]);
|
|
568
|
+
allInputFiles.push(file);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
return allInputFiles;
|
|
573
|
+
}
|
|
574
|
+
function getOrSetExecutionId(invocationContext, codeExecutorContext) {
|
|
575
|
+
var _a;
|
|
576
|
+
const agent = invocationContext.agent;
|
|
577
|
+
if (!(agent instanceof LlmAgent) || !((_a = agent.codeExecutor) == null ? void 0 : _a.stateful)) {
|
|
578
|
+
return void 0;
|
|
579
|
+
}
|
|
580
|
+
let executionId = codeExecutorContext.getExecutionId();
|
|
581
|
+
if (!executionId) {
|
|
582
|
+
executionId = invocationContext.session.id;
|
|
583
|
+
codeExecutorContext.setExecutionId(executionId);
|
|
584
|
+
}
|
|
585
|
+
return executionId;
|
|
586
|
+
}
|
|
587
|
+
async function postProcessCodeExecutionResult(invocationContext, codeExecutorContext, codeExecutionResult) {
|
|
588
|
+
if (!invocationContext.artifactService) {
|
|
589
|
+
throw new Error("Artifact service is not initialized.");
|
|
590
|
+
}
|
|
591
|
+
const resultContent = {
|
|
592
|
+
role: "model",
|
|
593
|
+
parts: [buildCodeExecutionResultPart(codeExecutionResult)]
|
|
594
|
+
};
|
|
595
|
+
const eventActions = createEventActions({ stateDelta: codeExecutorContext.getStateDelta() });
|
|
596
|
+
if (codeExecutionResult.stderr) {
|
|
597
|
+
codeExecutorContext.incrementErrorCount(invocationContext.invocationId);
|
|
598
|
+
} else {
|
|
599
|
+
codeExecutorContext.resetErrorCount(invocationContext.invocationId);
|
|
600
|
+
}
|
|
601
|
+
for (const outputFile of codeExecutionResult.outputFiles) {
|
|
602
|
+
const version = await invocationContext.artifactService.saveArtifact({
|
|
603
|
+
appName: invocationContext.appName || "",
|
|
604
|
+
userId: invocationContext.userId || "",
|
|
605
|
+
sessionId: invocationContext.session.id,
|
|
606
|
+
filename: outputFile.name,
|
|
607
|
+
artifact: {
|
|
608
|
+
inlineData: { data: outputFile.content, mimeType: outputFile.mimeType }
|
|
609
|
+
}
|
|
610
|
+
});
|
|
611
|
+
eventActions.artifactDelta[outputFile.name] = version;
|
|
612
|
+
}
|
|
613
|
+
return createEvent({
|
|
614
|
+
invocationId: invocationContext.invocationId,
|
|
615
|
+
author: invocationContext.agent.name,
|
|
616
|
+
branch: invocationContext.branch,
|
|
617
|
+
content: resultContent,
|
|
618
|
+
actions: eventActions
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
function getDataFilePreprocessingCode(file) {
|
|
622
|
+
function getNormalizedFileName(fileName) {
|
|
623
|
+
const [varName2] = fileName.split(".");
|
|
624
|
+
let normalizedName = varName2.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
625
|
+
if (/^\d/.test(normalizedName)) {
|
|
626
|
+
normalizedName = "_" + normalizedName;
|
|
627
|
+
}
|
|
628
|
+
return normalizedName;
|
|
629
|
+
}
|
|
630
|
+
if (!DATA_FILE_UTIL_MAP[file.mimeType]) {
|
|
631
|
+
return void 0;
|
|
632
|
+
}
|
|
633
|
+
const varName = getNormalizedFileName(file.name);
|
|
634
|
+
const loaderCode = DATA_FILE_UTIL_MAP[file.mimeType].loaderCodeTemplate.replace(
|
|
635
|
+
"{filename}",
|
|
636
|
+
file.name
|
|
637
|
+
);
|
|
638
|
+
return `
|
|
639
|
+
${DATA_FILE_HELPER_LIB}
|
|
640
|
+
|
|
641
|
+
# Load the dataframe.
|
|
642
|
+
${varName} = ${loaderCode}
|
|
643
|
+
|
|
644
|
+
# Use \`explore_df\` to guide my analysis.
|
|
645
|
+
explore_df(${varName})
|
|
646
|
+
`;
|
|
647
|
+
}
|
|
648
|
+
const CODE_EXECUTION_REQUEST_PROCESSOR = new CodeExecutionRequestProcessor();
|
|
326
649
|
class LlmAgent extends BaseAgent {
|
|
327
650
|
constructor(config) {
|
|
328
651
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
@@ -342,12 +665,14 @@ class LlmAgent extends BaseAgent {
|
|
|
342
665
|
this.afterModelCallback = config.afterModelCallback;
|
|
343
666
|
this.beforeToolCallback = config.beforeToolCallback;
|
|
344
667
|
this.afterToolCallback = config.afterToolCallback;
|
|
668
|
+
this.codeExecutor = config.codeExecutor;
|
|
345
669
|
this.requestProcessors = (_g = config.requestProcessors) != null ? _g : [
|
|
346
670
|
BASIC_LLM_REQUEST_PROCESSOR,
|
|
347
671
|
IDENTITY_LLM_REQUEST_PROCESSOR,
|
|
348
672
|
INSTRUCTIONS_LLM_REQUEST_PROCESSOR,
|
|
349
673
|
REQUEST_CONFIRMATION_LLM_REQUEST_PROCESSOR,
|
|
350
|
-
CONTENT_REQUEST_PROCESSOR
|
|
674
|
+
CONTENT_REQUEST_PROCESSOR,
|
|
675
|
+
CODE_EXECUTION_REQUEST_PROCESSOR
|
|
351
676
|
];
|
|
352
677
|
this.responseProcessors = (_h = config.responseProcessors) != null ? _h : [];
|
|
353
678
|
const agentTransferDisabled = this.disallowTransferToParent && this.disallowTransferToPeers && !((_i = this.subAgents) == null ? void 0 : _i.length);
|
|
@@ -397,7 +722,7 @@ class LlmAgent extends BaseAgent {
|
|
|
397
722
|
* When not set, the agent will inherit the model from its ancestor.
|
|
398
723
|
*/
|
|
399
724
|
get canonicalModel() {
|
|
400
|
-
if (this.model
|
|
725
|
+
if (isBaseLlm(this.model)) {
|
|
401
726
|
return this.model;
|
|
402
727
|
}
|
|
403
728
|
if (typeof this.model === "string" && this.model) {
|
|
@@ -830,5 +1155,6 @@ class LlmAgent extends BaseAgent {
|
|
|
830
1155
|
}
|
|
831
1156
|
export {
|
|
832
1157
|
LlmAgent,
|
|
833
|
-
REQUEST_CONFIRMATION_LLM_REQUEST_PROCESSOR
|
|
1158
|
+
REQUEST_CONFIRMATION_LLM_REQUEST_PROCESSOR,
|
|
1159
|
+
responseProcessor
|
|
834
1160
|
};
|