@paean-ai/adk 0.2.6 → 0.2.8
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/index.js +11 -11
- package/dist/cjs/index.js.map +3 -3
- package/dist/cjs/models/google_llm.js +57 -10
- package/dist/esm/index.js +11 -11
- package/dist/esm/index.js.map +3 -3
- package/dist/esm/models/google_llm.js +62 -11
- package/dist/web/index.js +1 -1
- package/dist/web/index.js.map +3 -3
- package/dist/web/models/google_llm.js +62 -11
- package/package.json +1 -1
package/dist/esm/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/agents/base_agent.ts", "../../src/events/event_actions.ts", "../../src/events/event.ts", "../../src/sessions/state.ts", "../../src/agents/readonly_context.ts", "../../src/agents/callback_context.ts", "../../src/utils/env_aware_utils.ts", "../../src/agents/invocation_context.ts", "../../src/agents/functions.ts", "../../src/auth/auth_handler.ts", "../../src/tools/tool_confirmation.ts", "../../src/tools/tool_context.ts", "../../src/utils/logger.ts", "../../src/agents/live_request_queue.ts", "../../src/agents/llm_agent.ts", "../../src/code_executors/base_code_executor.ts", "../../src/utils/model_name.ts", "../../src/code_executors/built_in_code_executor.ts", "../../src/code_executors/code_execution_utils.ts", "../../src/utils/deep_clone.ts", "../../src/code_executors/code_executor_context.ts", "../../src/version.ts", "../../src/utils/client_labels.ts", "../../src/models/base_llm.ts", "../../src/models/llm_request.ts", "../../src/models/google_llm.ts", "../../src/utils/variant_utils.ts", "../../src/models/gemini_llm_connection.ts", "../../src/models/llm_response.ts", "../../src/models/registry.ts", "../../src/tools/base_tool.ts", "../../src/tools/function_tool.ts", "../../src/utils/simple_zod_to_json.ts", "../../src/agents/base_llm_processor.ts", "../../src/agents/content_processor_utils.ts", "../../src/agents/instructions.ts", "../../src/agents/run_config.ts", "../../src/agents/loop_agent.ts", "../../src/agents/parallel_agent.ts", "../../src/agents/sequential_agent.ts", "../../src/artifacts/in_memory_artifact_service.ts", "../../src/memory/in_memory_memory_service.ts", "../../src/plugins/base_plugin.ts", "../../src/plugins/logging_plugin.ts", "../../src/plugins/plugin_manager.ts", "../../src/plugins/security_plugin.ts", "../../src/sessions/base_session_service.ts", "../../src/sessions/session.ts", "../../src/sessions/in_memory_session_service.ts", "../../src/runner/runner.ts", "../../src/runner/in_memory_runner.ts", "../../src/tools/agent_tool.ts", "../../src/tools/forwarding_artifact_service.ts", "../../src/tools/base_toolset.ts", "../../src/tools/google_search_tool.ts", "../../src/tools/long_running_tool.ts", "../../src/tools/mcp/mcp_session_manager.ts", "../../src/utils/gemini_schema_util.ts", "../../src/tools/mcp/mcp_tool.ts", "../../src/tools/mcp/mcp_toolset.ts", "../../src/artifacts/gcs_artifact_service.ts", "../../src/telemetry/setup.ts", "../../src/telemetry/google_cloud.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Content} from '@google/genai';\nimport {trace} from '@opentelemetry/api';\n\nimport {createEvent, Event} from '../events/event.js';\n\nimport {CallbackContext} from './callback_context.js';\nimport {InvocationContext} from './invocation_context.js';\n\ntype SingleAgentCallback = (context: CallbackContext) =>\n Promise<Content|undefined>|(Content|undefined);\n\ntype BeforeAgentCallback = SingleAgentCallback|SingleAgentCallback[];\n\ntype AfterAgentCallback = SingleAgentCallback|SingleAgentCallback[];\n\n/**\n * The config of a base agent.\n */\nexport interface BaseAgentConfig {\n name: string;\n description?: string;\n parentAgent?: BaseAgent;\n subAgents?: BaseAgent[];\n beforeAgentCallback?: BeforeAgentCallback;\n afterAgentCallback?: AfterAgentCallback;\n}\n\n/**\n * Base class for all agents in Agent Development Kit.\n */\nexport abstract class BaseAgent {\n /**\n * The agent's name.\n * Agent name must be a JS identifier and unique within the agent tree.\n * Agent name cannot be \"user\", since it's reserved for end-user's input.\n */\n readonly name: string;\n\n /**\n * Description about the agent's capability.\n *\n * The model uses this to determine whether to delegate control to the agent.\n * One-line description is enough and preferred.\n */\n readonly description?: string;\n\n /**\n * Root agent of this agent.\n */\n readonly rootAgent: BaseAgent;\n\n /**\n * The parent agent of this agent.\n *\n * Note that an agent can ONLY be added as sub-agent once.\n *\n * If you want to add one agent twice as sub-agent, consider to create two\n * agent instances with identical config, but with different name and add them\n * to the agent tree.\n *\n * The parent agent is the agent that created this agent.\n */\n parentAgent?: BaseAgent;\n\n /**\n * The sub-agents of this agent.\n */\n readonly subAgents: BaseAgent[];\n\n /**\n * Callback or list of callbacks to be invoked before the agent run.\n *\n * When a list of callbacks is provided, the callbacks will be called in the\n * order they are listed until a callback does not return undefined.\n *\n * @param callbackContext: MUST be named 'callbackContext' (enforced).\n *\n * @return Content: The content to return to the user. When the content is\n * present, the agent run will be skipped and the provided content will be\n * returned to user.\n */\n readonly beforeAgentCallback: SingleAgentCallback[];\n\n /**\n * Callback or list of callbacks to be invoked after the agent run.\n *\n * When a list of callbacks is provided, the callbacks will be called in the\n * order they are listed until a callback does not return undefined.\n *\n * @param callbackContext: MUST be named 'callbackContext' (enforced).\n *\n * @return Content: The content to return to the user. When the content is\n * present, the provided content will be used as agent response and\n * appended to event history as agent response.\n */\n readonly afterAgentCallback: SingleAgentCallback[];\n\n constructor(config: BaseAgentConfig) {\n this.name = validateAgentName(config.name);\n this.description = config.description;\n this.parentAgent = config.parentAgent;\n this.subAgents = config.subAgents || [];\n this.rootAgent = getRootAgent(this);\n this.beforeAgentCallback =\n getCannonicalCallback(config.beforeAgentCallback);\n this.afterAgentCallback = getCannonicalCallback(config.afterAgentCallback);\n\n this.setParentAgentForSubAgents();\n }\n\n /**\n * Entry method to run an agent via text-based conversation.\n *\n * @param parentContext The invocation context of the parent agent.\n * @yields The events generated by the agent.\n * @returns An AsyncGenerator that yields the events generated by the agent.\n */\n async *\n runAsync(parentContext: InvocationContext):\n AsyncGenerator<Event, void, void> {\n const span = trace.getTracer('gcp.vertex.agent')\n .startSpan(`agent_run [${this.name}]`);\n try {\n const context = this.createInvocationContext(parentContext);\n\n const beforeAgentCallbackEvent =\n await this.handleBeforeAgentCallback(context);\n if (beforeAgentCallbackEvent) {\n yield beforeAgentCallbackEvent;\n }\n\n if (context.endInvocation) {\n return;\n }\n\n for await (const event of this.runAsyncImpl(context)) {\n yield event;\n }\n\n if (context.endInvocation) {\n return;\n }\n\n const afterAgentCallbackEvent =\n await this.handleAfterAgentCallback(context);\n if (afterAgentCallbackEvent) {\n yield afterAgentCallbackEvent;\n }\n } finally {\n span.end();\n }\n }\n\n /**\n * Entry method to run an agent via video/audio-based conversation.\n *\n * @param parentContext The invocation context of the parent agent.\n * @yields The events generated by the agent.\n * @returns An AsyncGenerator that yields the events generated by the agent.\n */\n async *\n runLive(parentContext: InvocationContext):\n AsyncGenerator<Event, void, void> {\n const span = trace.getTracer('gcp.vertex.agent')\n .startSpan(`agent_run [${this.name}]`);\n try {\n // TODO(b/425992518): Implement live mode.\n throw new Error('Live mode is not implemented yet.');\n } finally {\n span.end();\n }\n }\n\n /**\n * Core logic to run this agent via text-based conversation.\n *\n * @param context The invocation context of the agent.\n * @yields The events generated by the agent.\n * @returns An AsyncGenerator that yields the events generated by the agent.\n */\n protected abstract runAsyncImpl(context: InvocationContext):\n AsyncGenerator<Event, void, void>;\n\n /**\n * Core logic to run this agent via video/audio-based conversation.\n *\n * @param context The invocation context of the agent.\n * @yields The events generated by the agent.\n * @returns An AsyncGenerator that yields the events generated by the agent.\n */\n protected abstract runLiveImpl(context: InvocationContext):\n AsyncGenerator<Event, void, void>;\n\n /**\n * Finds the agent with the given name in this agent and its descendants.\n *\n * @param name The name of the agent to find.\n * @return The agent with the given name, or undefined if not found.\n */\n findAgent(name: string): BaseAgent|undefined {\n if (this.name === name) {\n return this;\n }\n\n return this.findSubAgent(name);\n }\n\n /**\n * Finds the agent with the given name in this agent's descendants.\n *\n * @param name The name of the agent to find.\n * @return The agent with the given name, or undefined if not found.\n */\n findSubAgent(name: string): BaseAgent|undefined {\n for (const subAgent of this.subAgents) {\n const result = subAgent.findAgent(name);\n if (result) {\n return result;\n }\n }\n\n return undefined;\n }\n\n /**\n * Creates an invocation context for this agent.\n *\n * @param parentContext The invocation context of the parent agent.\n * @return The invocation context for this agent.\n */\n protected createInvocationContext(parentContext: InvocationContext):\n InvocationContext {\n return new InvocationContext({\n ...parentContext,\n agent: this,\n });\n }\n\n /**\n * Runs the before agent callback if it exists.\n *\n * @param invocationContext The invocation context of the agent.\n * @return The event to return to the user, or undefined if no event is\n * generated.\n */\n protected async handleBeforeAgentCallback(\n invocationContext: InvocationContext): Promise<Event|undefined> {\n if (this.beforeAgentCallback.length === 0) {\n return undefined;\n }\n\n const callbackContext = new CallbackContext({invocationContext});\n for (const callback of this.beforeAgentCallback) {\n const content = await callback(callbackContext);\n\n if (content) {\n invocationContext.endInvocation = true;\n\n return createEvent({\n invocationId: invocationContext.invocationId,\n author: this.name,\n branch: invocationContext.branch,\n content,\n actions: callbackContext.eventActions,\n });\n }\n }\n\n if (callbackContext.state.hasDelta()) {\n return createEvent({\n invocationId: invocationContext.invocationId,\n author: this.name,\n branch: invocationContext.branch,\n actions: callbackContext.eventActions,\n });\n }\n\n return undefined;\n }\n\n /**\n * Runs the after agent callback if it exists.\n *\n * @param invocationContext The invocation context of the agent.\n * @return The event to return to the user, or undefined if no event is\n * generated.\n */\n protected async handleAfterAgentCallback(\n invocationContext: InvocationContext): Promise<Event|undefined> {\n if (this.afterAgentCallback.length === 0) {\n return undefined;\n }\n\n const callbackContext = new CallbackContext({invocationContext});\n for (const callback of this.afterAgentCallback) {\n const content = await callback(callbackContext);\n\n if (content) {\n return createEvent({\n invocationId: invocationContext.invocationId,\n author: this.name,\n branch: invocationContext.branch,\n content,\n actions: callbackContext.eventActions,\n });\n }\n }\n\n if (callbackContext.state.hasDelta()) {\n return createEvent({\n invocationId: invocationContext.invocationId,\n author: this.name,\n branch: invocationContext.branch,\n actions: callbackContext.eventActions,\n });\n }\n\n return undefined;\n }\n\n private setParentAgentForSubAgents(): void {\n for (const subAgent of this.subAgents) {\n if (subAgent.parentAgent) {\n throw new Error(`Agent \"${\n subAgent.name}\" already has a parent agent, current parent: \"${\n subAgent.parentAgent.name}\", trying to add: \"${this.name}\"`);\n }\n\n subAgent.parentAgent = this;\n }\n }\n}\n\n/**\n * Validates the agent name.\n *\n * @param name The name of the agent.\n * @return The validated agent name.\n */\nfunction validateAgentName(name: string): string {\n if (!isIdentifier(name)) {\n throw new Error(`Found invalid agent name: \"${\n name}\". Agent name must be a valid identifier. It should start with a letter (a-z, A-Z) or an underscore (_), and can only contain letters, digits (0-9), and underscores.`);\n }\n\n if (name === 'user') {\n throw new Error(\n `Agent name cannot be 'user'. 'user' is reserved for end-user's input.`);\n }\n\n return name;\n}\n\n/**\n * Checks if the given string is a valid identifier.\n *\n * @param str The string to check.\n * @return True if the string is a valid identifier, false otherwise.\n */\nfunction isIdentifier(str: string): boolean {\n return /^[\\p{ID_Start}$_][\\p{ID_Continue}$_]*$/u.test(str);\n}\n\n/**\n * Gets the root agent of the given agent.\n *\n * @param rootAgent The root agent to get the root agent of.\n * @return The root agent.\n */\nfunction getRootAgent(rootAgent: BaseAgent): BaseAgent {\n while (rootAgent.parentAgent) {\n rootAgent = rootAgent.parentAgent;\n }\n\n return rootAgent;\n}\n\n/**\n * Gets the canonical callback from the given callback.\n *\n * @param callbacks The callback or list of callbacks to get the canonical\n * callback from.\n * @return The canonical callback.\n */\nexport function getCannonicalCallback<T>(callbacks?: T|T[]): T[] {\n if (!callbacks) {\n return [];\n }\n\n return Array.isArray(callbacks) ? callbacks : [callbacks];\n}", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {ToolConfirmation} from '../tools/tool_confirmation.js';\n\n// TODO: b/425992518 - Replace 'any' with a proper AuthConfig.\ntype AuthConfig = any;\n\n/**\n * Represents the actions attached to an event.\n */\nexport interface EventActions {\n /**\n * If true, it won't call model to summarize function response.\n * Only used for function_response event.\n */\n skipSummarization?: boolean;\n\n /**\n * Indicates that the event is updating the state with the given delta.\n */\n stateDelta: {[key: string]: unknown};\n\n /**\n * Indicates that the event is updating an artifact. key is the filename,\n * value is the version.\n */\n artifactDelta: {[key: string]: number};\n\n /**\n * If set, the event transfers to the specified agent.\n */\n transferToAgent?: string;\n\n /**\n * The agent is escalating to a higher level agent.\n */\n escalate?: boolean;\n\n /**\n * Authentication configurations requested by tool responses.\n *\n * This field will only be set by a tool response event indicating tool\n * request auth credential.\n * - Keys: The function call id. Since one function response event could\n * contain multiple function responses that correspond to multiple function\n * calls. Each function call could request different auth configs. This id is\n * used to identify the function call.\n * - Values: The requested auth config.\n */\n requestedAuthConfigs: {[key: string]: AuthConfig};\n\n /**\n * A dict of tool confirmation requested by this event, keyed by the function\n * call id.\n */\n requestedToolConfirmations: {[key: string]: ToolConfirmation};\n}\n\n/**\n * Creates an EventActions object.\n */\nexport function createEventActions(state: Partial<EventActions> = {}):\n EventActions {\n return {\n stateDelta: {},\n artifactDelta: {},\n requestedAuthConfigs: {},\n requestedToolConfirmations: {},\n ...state,\n };\n}\n\n/**\n * Merges a list of EventActions objects into a single EventActions object.\n *\n * 1. It merges dictionaries (stateDelta, artifactDelta, requestedAuthConfigs)\n * by adding all the properties from each source.\n *\n * 2. For other properties (skipSummarization,transferToAgent, escalate), the\n * last one wins.\n */\nexport function mergeEventActions(\n sources: Array<Partial<EventActions>>,\n target?: EventActions): EventActions {\n const result = createEventActions();\n\n if (target) {\n Object.assign(result, target);\n }\n\n for (const source of sources) {\n if (!source) continue;\n\n if (source.stateDelta) {\n Object.assign(result.stateDelta, source.stateDelta);\n }\n if (source.artifactDelta) {\n Object.assign(result.artifactDelta, source.artifactDelta);\n }\n if (source.requestedAuthConfigs) {\n Object.assign(result.requestedAuthConfigs, source.requestedAuthConfigs);\n }\n if (source.requestedToolConfirmations) {\n Object.assign(\n result.requestedToolConfirmations, source.requestedToolConfirmations);\n }\n\n if (source.skipSummarization !== undefined) {\n result.skipSummarization = source.skipSummarization;\n }\n if (source.transferToAgent !== undefined) {\n result.transferToAgent = source.transferToAgent;\n }\n if (source.escalate !== undefined) {\n result.escalate = source.escalate;\n }\n }\n return result;\n}", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {FunctionCall, FunctionResponse} from '@google/genai';\n\nimport {LlmResponse} from '../models/llm_response.js';\n\nimport {createEventActions, EventActions} from './event_actions.js';\n\n/**\n * Represents an event in a conversation between agents and users.\n\n It is used to store the content of the conversation, as well as the actions\n taken by the agents like function calls, etc.\n */\nexport interface Event extends LlmResponse {\n /**\n * The unique identifier of the event.\n * Do not assign the ID. It will be assigned by the session.\n */\n id: string;\n\n /**\n * The invocation ID of the event. Should be non-empty before appending to a\n * session.\n */\n invocationId: string;\n\n /**\n * \"user\" or the name of the agent, indicating who appended the event to the\n * session.\n */\n author?: string;\n\n /**\n * The actions taken by the agent.\n */\n actions: EventActions;\n\n /**\n * Set of ids of the long running function calls. Agent client will know from\n * this field about which function call is long running. Only valid for\n * function call event\n */\n longRunningToolIds?: string[];\n\n /**\n * The branch of the event.\n * The format is like agent_1.agent_2.agent_3, where agent_1 is the parent of\n * agent_2, and agent_2 is the parent of agent_3.\n *\n * Branch is used when multiple sub-agent shouldn't see their peer agents'\n * conversation history.\n */\n branch?: string;\n\n /**\n * The timestamp of the event.\n */\n timestamp: number;\n}\n\n/**\n * Creates an event from a partial event.\n *\n * @param params The partial event to create the event from.\n * @returns The event.\n */\nexport function createEvent(params: Partial<Event> = {}): Event {\n return {\n ...params,\n id: params.id || createNewEventId(),\n invocationId: params.invocationId || '',\n author: params.author,\n actions: params.actions || createEventActions(),\n longRunningToolIds: params.longRunningToolIds || [],\n branch: params.branch,\n timestamp: params.timestamp || Date.now(),\n };\n}\n\n/**\n * Returns whether the event is the final response of the agent.\n */\nexport function isFinalResponse(event: Event) {\n if (event.actions.skipSummarization ||\n (event.longRunningToolIds && event.longRunningToolIds.length > 0)) {\n return true;\n }\n\n return (\n getFunctionCalls(event).length === 0 &&\n getFunctionResponses(event).length === 0 && !event.partial &&\n !hasTrailingCodeExecutionResult(event));\n}\n\n/**\n * Returns the function calls in the event.\n */\nexport function getFunctionCalls(event: Event): FunctionCall[] {\n const funcCalls = [];\n if (event.content && event.content.parts) {\n for (const part of event.content.parts) {\n if (part.functionCall) {\n funcCalls.push(part.functionCall);\n }\n }\n }\n\n return funcCalls;\n}\n\n/**\n * Returns the function responses in the event.\n */\nexport function getFunctionResponses(event: Event): FunctionResponse[] {\n const funcResponses = [];\n if (event.content && event.content.parts) {\n for (const part of event.content.parts) {\n if (part.functionResponse) {\n funcResponses.push(part.functionResponse);\n }\n }\n }\n\n return funcResponses;\n}\n\n/**\n * Returns whether the event has a trailing code execution result.\n */\nexport function hasTrailingCodeExecutionResult(event: Event): boolean {\n if (event.content && event.content.parts?.length) {\n const lastPart = event.content.parts[event.content.parts.length - 1];\n return lastPart.codeExecutionResult !== undefined;\n }\n\n return false;\n}\n\n/**\n * Extracts and concatenates all text from the parts of a `Event` object.\n * @param event The `Event` object to process.\n *\n * @returns A single string with the combined text.\n */\nexport function stringifyContent(event: Event): string {\n if (!event.content?.parts) {\n return '';\n }\n\n return event.content.parts.map(part => part.text ?? '').join('');\n}\n\nconst ASCII_LETTERS_AND_NUMBERS =\n 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';\n\n/**\n * Generates a new unique ID for the event.\n */\nexport function createNewEventId(): string {\n let id = '';\n\n for (let i = 0; i < 8; i++) {\n id += ASCII_LETTERS_AND_NUMBERS[Math.floor(\n Math.random() * ASCII_LETTERS_AND_NUMBERS.length)];\n }\n\n return id;\n}", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * A state mapping that maintains the current value and the pending-commit\n * delta.\n */\nexport class State {\n static readonly APP_PREFIX = 'app:';\n static readonly USER_PREFIX = 'user:';\n static readonly TEMP_PREFIX = 'temp:';\n\n constructor(\n /** The current value of the state. */\n private value: Record<string, unknown> = {},\n /** The delta change to the current value that hasn't been committed. */\n private delta: Record<string, unknown> = {},\n ) {}\n\n /**\n * Returns the value of the state dict for the given key.\n *\n * @param key The key to get the value for.\n * @param defaultValue The default value to return if the key is not found.\n * @return The value of the state for the given key, or the default value if\n * not found.\n */\n get<T>(key: string, defaultValue?: T): T|undefined {\n if (key in this.delta) {\n return this.delta[key] as T;\n }\n\n if (key in this.value) {\n return this.value[key] as T;\n }\n\n return defaultValue;\n }\n\n /**\n * Sets the value of the state dict for the given key.\n *\n * @param key The key to set the value for.\n * @param value The value to set.\n */\n set(key: string, value: unknown) {\n this.value[key] = value;\n this.delta[key] = value;\n }\n\n /**\n * Whether the state has pending delta.\n */\n has(key: string): boolean {\n return key in this.value || key in this.delta;\n }\n\n /**\n * Whether the state has pending delta.\n */\n hasDelta(): boolean {\n return Object.keys(this.delta).length > 0;\n }\n\n /**\n * Updates the state dict with the given delta.\n *\n * @param delta The delta to update the state with.\n */\n update(delta: Record<string, unknown>) {\n this.delta = {...this.delta, ...delta};\n this.value = {...this.value, ...delta};\n }\n\n /**\n * Returns the state as a plain JSON object.\n */\n toRecord(): Record<string, unknown> {\n return {...this.value, ...this.delta};\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Content} from '@google/genai';\n\nimport {State} from '../sessions/state.js';\n\nimport {InvocationContext} from './invocation_context.js';\n\n/**\n * A readonly context represents the data of a single invocation of an agent.\n */\nexport class ReadonlyContext {\n constructor(readonly invocationContext: InvocationContext) {}\n\n /**\n * The user content that started this invocation.\n */\n get userContent(): Content|undefined {\n return this.invocationContext.userContent;\n }\n\n /**\n * The current invocation id.\n */\n get invocationId(): string {\n return this.invocationContext.invocationId;\n }\n\n /**\n * The current agent name.\n */\n get agentName(): string {\n return this.invocationContext.agent.name;\n }\n\n /**\n * The state of the current session.\n */\n get state(): Readonly<State> {\n return new State(this.invocationContext.session.state, {}) as\n Readonly<State>;\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Part} from '@google/genai';\n\nimport {createEventActions, EventActions} from '../events/event_actions.js';\nimport {State} from '../sessions/state.js';\n\nimport {InvocationContext} from './invocation_context.js';\nimport {ReadonlyContext} from './readonly_context.js';\n\n/**\n * The context of various callbacks within an agent run.\n */\nexport class CallbackContext extends ReadonlyContext {\n private readonly _state: State;\n\n readonly eventActions: EventActions;\n\n constructor({invocationContext, eventActions}: {\n invocationContext: InvocationContext,\n eventActions?: EventActions,\n }) {\n super(invocationContext);\n this.eventActions = eventActions || createEventActions();\n this._state = new State(\n invocationContext.session.state,\n this.eventActions.stateDelta,\n );\n }\n\n /**\n * The delta-aware state of the current session.\n */\n override get state() {\n return this._state;\n }\n\n /**\n * Loads an artifact attached to the current session.\n *\n * @param filename The filename of the artifact.\n * @param version The version of the artifact. If not provided, the latest\n * version will be used.\n * @return A promise that resolves to the loaded artifact.\n */\n loadArtifact(filename: string, version?: number): Promise<Part|undefined> {\n if (!this.invocationContext.artifactService) {\n throw new Error('Artifact service is not initialized.');\n }\n\n return this.invocationContext.artifactService.loadArtifact({\n appName: this.invocationContext.appName,\n userId: this.invocationContext.userId,\n sessionId: this.invocationContext.session.id,\n filename,\n version,\n });\n }\n\n /**\n * Saves an artifact attached to the current session.\n *\n * @param filename The filename of the artifact.\n * @param artifact The artifact to save.\n * @return A promise that resolves to the version of the saved artifact.\n */\n async saveArtifact(filename: string, artifact: Part): Promise<number> {\n if (!this.invocationContext.artifactService) {\n throw new Error('Artifact service is not initialized.');\n }\n\n const version = await this.invocationContext.artifactService.saveArtifact({\n appName: this.invocationContext.appName,\n userId: this.invocationContext.userId,\n sessionId: this.invocationContext.session.id,\n filename,\n artifact,\n });\n this.eventActions.artifactDelta[filename] = version;\n\n return version;\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * Returns true if the environment is a browser.\n */\nexport function isBrowser() {\n return typeof window !== 'undefined';\n}\n\n/**\n * Generates a random UUID.\n */\nconst UUID_MASK = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';\nexport function randomUUID() {\n let uuid = '';\n\n for (let i = 0; i < UUID_MASK.length; i++) {\n const randomValue = (Math.random() * 16) | 0;\n\n if (UUID_MASK[i] === 'x') {\n uuid += randomValue.toString(16);\n } else if (UUID_MASK[i] === 'y') {\n uuid += ((randomValue & 0x3) | 0x8).toString(16);\n } else {\n uuid += UUID_MASK[i];\n }\n }\n\n return uuid;\n}\n\n/**\n * Encodes the given string to base64.\n *\n * @param data The string to encode.\n * @return The base64-encoded string.\n */\nexport function base64Encode(data: string): string {\n if (isBrowser()) {\n return window.btoa(data);\n }\n\n return Buffer.from(data).toString('base64');\n}\n\n/**\n * Decodes the given base64 string to a string.\n *\n * @param data The base64-encoded string.\n * @return The decoded string.\n */\nexport function base64Decode(data: string): string {\n if (isBrowser()) {\n return window.atob(data);\n }\n\n return Buffer.from(data, 'base64').toString();\n}\n\n/**\n * Checks if the given string is base64-encoded.\n *\n * @param data The string to check.\n * @return True if the string is base64-encoded, false otherwise.\n */\nexport function isBase64Encoded(data: string): boolean {\n try {\n return base64Encode(base64Decode(data)) === data;\n } catch (e) {\n return false;\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Content} from '@google/genai';\n\nimport {BaseArtifactService} from '../artifacts/base_artifact_service.js';\nimport {BaseCredentialService} from '../auth/credential_service/base_credential_service.js';\nimport {BaseMemoryService} from '../memory/base_memory_service.js';\nimport {PluginManager} from '../plugins/plugin_manager.js';\nimport {BaseSessionService} from '../sessions/base_session_service.js';\nimport {Session} from '../sessions/session.js';\nimport {randomUUID} from '../utils/env_aware_utils.js';\n\nimport {ActiveStreamingTool} from './active_streaming_tool.js';\nimport {BaseAgent} from './base_agent.js';\nimport {LiveRequestQueue} from './live_request_queue.js';\nimport {RunConfig} from './run_config.js';\nimport {TranscriptionEntry} from './transcription_entry.js';\n\ninterface InvocationContextParams {\n artifactService?: BaseArtifactService;\n sessionService?: BaseSessionService;\n memoryService?: BaseMemoryService;\n credentialService?: BaseCredentialService;\n invocationId: string;\n branch?: string;\n agent: BaseAgent;\n userContent?: Content;\n session: Session;\n endInvocation?: boolean;\n transcriptionCache?: TranscriptionEntry[];\n runConfig?: RunConfig;\n liveRequestQueue?: LiveRequestQueue;\n activeStreamingTools?: Record<string, ActiveStreamingTool>;\n pluginManager: PluginManager;\n}\n\n/**\n * A container to keep track of the cost of invocation.\n *\n * While we don't expect the metrics captured here to be a direct\n * representative of monetary cost incurred in executing the current\n * invocation, they in some ways have an indirect effect.\n */\nclass InvocationCostManager {\n private numberOfLlmCalls: number = 0;\n\n /**\n * Increments the number of llm calls and enforces the limit.\n *\n * @param runConfig the run config of the invocation.\n * @throws If number of llm calls made exceed the set threshold.\n */\n incrementAndEnforceLlmCallsLimit(runConfig?: RunConfig) {\n this.numberOfLlmCalls++;\n\n if (runConfig && runConfig.maxLlmCalls! > 0 &&\n this.numberOfLlmCalls > runConfig.maxLlmCalls!) {\n throw new Error(`Max number of llm calls limit of ${\n runConfig.maxLlmCalls!} exceeded`);\n }\n }\n}\n\n/**\n * An invocation context represents the data of a single invocation of an agent.\n *\n * An invocation:\n * 1. Starts with a user message and ends with a final response.\n * 2. Can contain one or multiple agent calls.\n * 3. Is handled by runner.runAsync().\n *\n * An invocation runs an agent until it does not request to transfer to\n * another agent.\n *\n * An agent call:\n * 1. Is handled by agent.runAsync().\n * 2. Ends when agent.runAsync() ends.\n *\n * An LLM agent call is an agent with a BaseLLMFlow.\n * An LLM agent call can contain one or multiple steps.\n *\n * An LLM agent runs steps in a loop until:\n * 1. A final response is generated.\n * 2. The agent transfers to another agent.\n * 3. The end_invocation is set to true by any callbacks or tools.\n *\n * A step:\n * 1. Calls the LLM only once and yields its response.\n * 2. Calls the tools and yields their responses if requested.\n *\n * The summarization of the function response is considered another step, since\n * it is another llm call.\n * A step ends when it's done calling llm and tools, or if the end_invocation\n * is set to true at any time.\n *\n * ```\n * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 invocation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 llm_agent_call_1 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250C\u2500 agent_call_2 \u2500\u2510\n * \u250C\u2500\u2500\u2500\u2500 step_1 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250C\u2500\u2500\u2500\u2500\u2500 step_2 \u2500\u2500\u2500\u2500\u2500\u2500\u2510\n * [call_llm] [call_tool] [call_llm] [transfer]\n * ```\n */\nexport class InvocationContext {\n readonly artifactService?: BaseArtifactService;\n readonly sessionService?: BaseSessionService;\n readonly memoryService?: BaseMemoryService;\n readonly credentialService?: BaseCredentialService;\n\n /**\n * The id of this invocation context.\n */\n readonly invocationId: string;\n\n /**\n * The branch of the invocation context.\n *\n * The format is like agent_1.agent_2.agent_3, where agent_1 is the parent of\n * agent_2, and agent_2 is the parent of agent_3.\n *\n * Branch is used when multiple sub-agents shouldn't see their peer agents'\n * conversation history.\n */\n branch?: string;\n\n /**\n * The current agent of this invocation context.\n */\n agent: BaseAgent;\n\n /**\n * The user content that started this invocation.\n */\n readonly userContent?: Content;\n\n /**\n * The current session of this invocation context.\n */\n readonly session: Session;\n\n /**\n * Whether to end this invocation.\n * Set to True in callbacks or tools to terminate this invocation.\n */\n endInvocation: boolean;\n\n /**\n * Caches necessary, data audio or contents, that are needed by transcription.\n */\n transcriptionCache?: TranscriptionEntry[];\n\n /**\n * Configurations for live agents under this invocation.\n */\n runConfig?: RunConfig;\n\n /**\n * A container to keep track of different kinds of costs incurred as a part of\n * this invocation.\n */\n private readonly invocationCostManager = new InvocationCostManager();\n\n /**\n * The queue to receive live requests.\n */\n liveRequestQueue?: LiveRequestQueue;\n\n /**\n * The running streaming tools of this invocation.\n */\n activeStreamingTools?: Record<string, ActiveStreamingTool>;\n\n /**\n * The manager for keeping track of plugins in this invocation.\n */\n pluginManager: PluginManager;\n\n /**\n * @param params The parameters for creating an invocation context.\n */\n constructor(params: InvocationContextParams) {\n this.artifactService = params.artifactService;\n this.sessionService = params.sessionService;\n this.memoryService = params.memoryService;\n this.invocationId = params.invocationId;\n this.branch = params.branch;\n this.agent = params.agent;\n this.userContent = params.userContent;\n this.session = params.session;\n this.endInvocation = params.endInvocation || false;\n this.transcriptionCache = params.transcriptionCache;\n this.runConfig = params.runConfig;\n this.liveRequestQueue = params.liveRequestQueue;\n this.activeStreamingTools = params.activeStreamingTools;\n this.pluginManager = params.pluginManager;\n }\n\n /**\n * The app name of the current session.\n */\n get appName() {\n return this.session.appName;\n }\n\n /**\n * The user ID of the current session.\n */\n get userId() {\n return this.session.userId;\n }\n\n /**\n * Tracks number of llm calls made.\n *\n * @throws If number of llm calls made exceed the set threshold.\n */\n incrementLlmCallCount() {\n this.invocationCostManager.incrementAndEnforceLlmCallsLimit(this.runConfig);\n }\n}\n\nexport function newInvocationContextId(): string {\n return `e-${randomUUID()}`;\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\n// TODO - b/436079721: implement traceMergedToolCalls, traceToolCall, tracer.\nimport {Content, createUserContent, FunctionCall, Part} from '@google/genai';\n\nimport {InvocationContext} from '../agents/invocation_context.js';\nimport {createEvent, Event, getFunctionCalls} from '../events/event.js';\nimport {mergeEventActions} from '../events/event_actions.js';\nimport {BaseTool} from '../tools/base_tool.js';\nimport {ToolConfirmation} from '../tools/tool_confirmation.js';\nimport {ToolContext} from '../tools/tool_context.js';\nimport {randomUUID} from '../utils/env_aware_utils.js';\nimport {logger} from '../utils/logger.js';\n\nimport {SingleAfterToolCallback, SingleBeforeToolCallback} from './llm_agent.js';\n\nconst AF_FUNCTION_CALL_ID_PREFIX = 'adk-';\nexport const REQUEST_EUC_FUNCTION_CALL_NAME = 'adk_request_credential';\nexport const REQUEST_CONFIRMATION_FUNCTION_CALL_NAME =\n 'adk_request_confirmation';\n\n// Export these items for testing purposes only\nexport const functionsExportedForTestingOnly = {\n handleFunctionCallList,\n};\n\nexport function generateClientFunctionCallId(): string {\n return `${AF_FUNCTION_CALL_ID_PREFIX}${randomUUID()}`;\n}\n\n/**\n * Populates client-side function call IDs.\n *\n * It iterates through all function calls in the event and assigns a\n * unique client-side ID to each one that doesn't already have an ID.\n */\n// TODO - b/425992518: consider move into event.ts\nexport function populateClientFunctionCallId(\n modelResponseEvent: Event,\n ): void {\n const functionCalls = getFunctionCalls(modelResponseEvent);\n if (!functionCalls) {\n return;\n }\n for (const functionCall of functionCalls) {\n if (!functionCall.id) {\n functionCall.id = generateClientFunctionCallId();\n }\n }\n}\n// TODO - b/425992518: consider internalize in content_[processor].ts\n/**\n * Removes the client-generated function call IDs from a given content object.\n *\n * When sending content back to the server, these IDs are\n * specific to the client-side and should not be included in requests to the\n * model.\n */\nexport function removeClientFunctionCallId(content: Content): void {\n if (content && content.parts) {\n for (const part of content.parts) {\n if (part.functionCall && part.functionCall.id &&\n part.functionCall.id.startsWith(AF_FUNCTION_CALL_ID_PREFIX)) {\n part.functionCall.id = undefined;\n }\n if (part.functionResponse && part.functionResponse.id &&\n part.functionResponse.id.startsWith(AF_FUNCTION_CALL_ID_PREFIX)) {\n part.functionResponse.id = undefined;\n }\n }\n }\n}\n// TODO - b/425992518: consider internalize as part of llm_agent's runtime.\n/**\n * Returns a set of function call ids of the long running tools.\n */\nexport function getLongRunningFunctionCalls(\n functionCalls: FunctionCall[],\n toolsDict: Record<string, BaseTool>,\n ): Set<string> {\n const longRunningToolIds = new Set<string>();\n for (const functionCall of functionCalls) {\n if (functionCall.name && functionCall.name in toolsDict &&\n toolsDict[functionCall.name].isLongRunning && functionCall.id) {\n longRunningToolIds.add(functionCall.id);\n }\n }\n return longRunningToolIds;\n}\n\n// TODO - b/425992518: consider internalize as part of llm_agent's runtime.\n// The auth part of function calling is a bit hacky, need to to clarify.\n/**\n * Generates an authentication event.\n *\n * It iterates through requested auth configurations in a function response\n * event and creates a new function call for each.\n */\nexport function generateAuthEvent(\n invocationContext: InvocationContext,\n functionResponseEvent: Event,\n ): Event|undefined {\n if (!functionResponseEvent.actions?.requestedAuthConfigs) {\n return undefined;\n }\n const parts: Part[] = [];\n const longRunningToolIds = new Set<string>();\n for (const [functionCallId, authConfig] of Object.entries(\n functionResponseEvent.actions.requestedAuthConfigs,\n )) {\n const requestEucFunctionCall: FunctionCall = {\n name: REQUEST_EUC_FUNCTION_CALL_NAME,\n args: {\n 'function_call_id': functionCallId,\n 'auth_config': authConfig,\n },\n id: generateClientFunctionCallId(),\n };\n longRunningToolIds.add(requestEucFunctionCall.id!);\n parts.push({functionCall: requestEucFunctionCall});\n }\n\n return createEvent({\n invocationId: invocationContext.invocationId,\n author: invocationContext.agent.name,\n branch: invocationContext.branch,\n content: {\n parts: parts,\n role: functionResponseEvent.content!.role,\n },\n longRunningToolIds: Array.from(longRunningToolIds),\n });\n}\n\n/**\n * Generates a request confirmation event from a function response event.\n */\nexport function generateRequestConfirmationEvent({\n invocationContext,\n functionCallEvent,\n functionResponseEvent,\n}: {\n invocationContext: InvocationContext,\n functionCallEvent: Event,\n functionResponseEvent: Event\n}): Event|undefined {\n if (!functionResponseEvent.actions?.requestedToolConfirmations) {\n return;\n }\n const parts: Part[] = [];\n const longRunningToolIds = new Set<string>();\n const functionCalls = getFunctionCalls(functionCallEvent);\n\n for (const [functionCallId, toolConfirmation] of Object.entries(\n functionResponseEvent.actions.requestedToolConfirmations,\n )) {\n const originalFunctionCall =\n functionCalls.find(call => call.id === functionCallId) ?? undefined;\n if (!originalFunctionCall) {\n continue;\n }\n const requestConfirmationFunctionCall: FunctionCall = {\n name: REQUEST_CONFIRMATION_FUNCTION_CALL_NAME,\n args: {\n 'originalFunctionCall': originalFunctionCall,\n 'toolConfirmation': toolConfirmation,\n },\n id: generateClientFunctionCallId(),\n };\n longRunningToolIds.add(requestConfirmationFunctionCall.id!);\n parts.push({functionCall: requestConfirmationFunctionCall});\n }\n return createEvent({\n invocationId: invocationContext.invocationId,\n author: invocationContext.agent.name,\n branch: invocationContext.branch,\n content: {\n parts: parts,\n role: functionResponseEvent.content!.role,\n },\n longRunningToolIds: Array.from(longRunningToolIds),\n });\n}\n\nasync function callToolAsync(\n tool: BaseTool,\n args: Record<string, any>,\n toolContext: ToolContext,\n ): Promise<any> {\n // TODO - b/436079721: implement [tracer.start_as_current_span]\n logger.debug(`callToolAsync ${tool.name}`);\n return await tool.runAsync({args, toolContext});\n}\n\n/**\n * Handles function calls.\n * Runtime behavior to pay attention to:\n * - Iterate through each function call in the `functionCallEvent`:\n * - Execute before tool callbacks !!if a callback provides a response, short\n * circuit the rest.\n * - Execute the tool.\n * - Execute after tool callbacks !!if a callback provides a response, short\n * circuit the rest.\n * - If the tool is long-running and the response is null, continue. !!state\n * - Merge all function response events into a single event.\n */\nexport async function handleFunctionCallsAsync({\n invocationContext,\n functionCallEvent,\n toolsDict,\n beforeToolCallbacks,\n afterToolCallbacks,\n filters,\n toolConfirmationDict,\n}: {\n invocationContext: InvocationContext,\n functionCallEvent: Event,\n toolsDict: Record<string, BaseTool>,\n beforeToolCallbacks: SingleBeforeToolCallback[],\n afterToolCallbacks: SingleAfterToolCallback[],\n filters?: Set<string>,\n toolConfirmationDict?: Record<string, ToolConfirmation>,\n}): Promise<Event|null> {\n const functionCalls = getFunctionCalls(functionCallEvent);\n return await handleFunctionCallList({\n invocationContext: invocationContext,\n functionCalls: functionCalls,\n toolsDict: toolsDict,\n beforeToolCallbacks: beforeToolCallbacks,\n afterToolCallbacks: afterToolCallbacks,\n filters: filters,\n toolConfirmationDict: toolConfirmationDict,\n });\n}\n\n/**\n * The underlying implementation of handleFunctionCalls, but takes a list of\n * function calls instead of an event.\n * This is also used by llm_agent execution flow in preprocessing.\n */\nexport async function handleFunctionCallList({\n invocationContext,\n functionCalls,\n toolsDict,\n beforeToolCallbacks,\n afterToolCallbacks,\n filters,\n toolConfirmationDict,\n}: {\n invocationContext: InvocationContext,\n functionCalls: FunctionCall[],\n toolsDict: Record<string, BaseTool>,\n beforeToolCallbacks: SingleBeforeToolCallback[],\n afterToolCallbacks: SingleAfterToolCallback[],\n filters?: Set<string>,\n toolConfirmationDict?: Record<string, ToolConfirmation>,\n}): Promise<Event|null> {\n const functionResponseEvents: Event[] = [];\n\n // Note: only function ids INCLUDED in the filters will be executed.\n const filteredFunctionCalls = functionCalls.filter(functionCall => {\n return !filters || (functionCall.id && filters.has(functionCall.id));\n });\n\n for (const functionCall of filteredFunctionCalls) {\n let toolConfirmation = undefined;\n if (toolConfirmationDict && functionCall.id) {\n toolConfirmation = toolConfirmationDict[functionCall.id];\n }\n\n const {tool, toolContext} = getToolAndContext(\n {\n invocationContext,\n functionCall,\n toolsDict,\n toolConfirmation,\n },\n );\n\n // TODO - b/436079721: implement [tracer.start_as_current_span]\n logger.debug(`execute_tool ${tool.name}`);\n const functionArgs = functionCall.args ?? {};\n\n // Step 1: Check if plugin before_tool_callback overrides the function\n // response.\n let functionResponse = null;\n let functionResponseError: string|unknown|undefined;\n functionResponse =\n await invocationContext.pluginManager.runBeforeToolCallback({\n tool: tool,\n toolArgs: functionArgs,\n toolContext: toolContext,\n });\n\n // Step 2: If no overrides are provided from the plugins, further run the\n // canonical callback.\n // TODO - b/425992518: validate the callback response type matches.\n if (functionResponse == null) { // Cover both null and undefined\n for (const callback of beforeToolCallbacks) {\n functionResponse = await callback({\n tool: tool,\n args: functionArgs,\n context: toolContext,\n });\n if (functionResponse) {\n break;\n }\n }\n }\n\n // Step 3: Otherwise, proceed calling the tool normally.\n if (functionResponse == null) { // Cover both null and undefined\n try {\n functionResponse = await callToolAsync(\n tool,\n functionArgs,\n toolContext,\n );\n } catch (e: unknown) {\n if (e instanceof Error) {\n const onToolErrorResponse =\n await invocationContext.pluginManager.runOnToolErrorCallback(\n {\n tool: tool,\n toolArgs: functionArgs,\n toolContext: toolContext,\n error: e,\n },\n );\n\n // Set function response to the result of the error callback and\n // continue execution, do not shortcut\n if (onToolErrorResponse) {\n functionResponse = onToolErrorResponse;\n } else {\n // If the error callback returns undefined, use the error message\n // as the function response error.\n functionResponseError = e.message;\n }\n } else {\n // If the error is not an Error, use the error object as the function\n // response error.\n functionResponseError = e;\n }\n }\n }\n\n // Step 4: Check if plugin after_tool_callback overrides the function\n // response.\n let alteredFunctionResponse =\n await invocationContext.pluginManager.runAfterToolCallback({\n tool: tool,\n toolArgs: functionArgs,\n toolContext: toolContext,\n result: functionResponse,\n });\n\n // Step 5: If no overrides are provided from the plugins, further run the\n // canonical after_tool_callbacks.\n if (alteredFunctionResponse == null) { // Cover both null and undefined\n for (const callback of afterToolCallbacks) {\n alteredFunctionResponse = await callback({\n tool: tool,\n args: functionArgs,\n context: toolContext,\n response: functionResponse,\n });\n if (alteredFunctionResponse) {\n break;\n }\n }\n }\n\n // Step 6: If alternative response exists from after_tool_callback, use it\n // instead of the original function response.\n if (alteredFunctionResponse != null) {\n functionResponse = alteredFunctionResponse;\n }\n\n // TODO - b/425992518: state event polluting runtime, consider fix.\n // Allow long running function to return None as response.\n if (tool.isLongRunning && !functionResponse) {\n continue;\n }\n\n if (functionResponseError) {\n functionResponse = {error: functionResponseError};\n } else if (\n typeof functionResponse !== 'object' || functionResponse == null) {\n functionResponse = {result: functionResponse};\n }\n\n // Builds the function response event.\n const functionResponseEvent = createEvent({\n invocationId: invocationContext.invocationId,\n author: invocationContext.agent.name,\n content: createUserContent({\n functionResponse: {\n id: toolContext.functionCallId,\n name: tool.name,\n response: functionResponse,\n },\n }),\n actions: toolContext.actions,\n branch: invocationContext.branch,\n });\n\n // TODO - b/436079721: implement [traceToolCall]\n logger.debug('traceToolCall', {\n tool: tool.name,\n args: functionArgs,\n functionResponseEvent: functionResponseEvent.id,\n });\n functionResponseEvents.push(functionResponseEvent);\n }\n\n if (!functionResponseEvents.length) {\n return null;\n }\n const mergedEvent =\n mergeParallelFunctionResponseEvents(functionResponseEvents);\n\n if (functionResponseEvents.length > 1) {\n // TODO - b/436079721: implement [tracer.start_as_current_span]\n logger.debug('execute_tool (merged)');\n // TODO - b/436079721: implement [traceMergedToolCalls]\n logger.debug('traceMergedToolCalls', {\n responseEventId: mergedEvent.id,\n functionResponseEvent: mergedEvent.id,\n });\n }\n return mergedEvent;\n}\n\n// TODO - b/425992518: consider inline, which is much cleaner.\nfunction getToolAndContext(\n {\n invocationContext,\n functionCall,\n toolsDict,\n toolConfirmation,\n }: {\n invocationContext: InvocationContext,\n functionCall: FunctionCall,\n toolsDict: Record<string, BaseTool>,\n toolConfirmation?: ToolConfirmation,\n },\n ): {tool: BaseTool; toolContext: ToolContext} {\n if (!functionCall.name || !(functionCall.name in toolsDict)) {\n throw new Error(\n `Function ${functionCall.name} is not found in the toolsDict.`,\n );\n }\n\n const toolContext = new ToolContext({\n invocationContext: invocationContext,\n functionCallId: functionCall.id || undefined,\n toolConfirmation,\n });\n\n const tool = toolsDict[functionCall.name];\n\n return {tool, toolContext};\n}\n\n/**\n * Merges a list of function response events into a single event.\n */\n// TODO - b/425992518: may not need export. Can be conslidated into Event.\nexport function mergeParallelFunctionResponseEvents(\n functionResponseEvents: Event[],\n ): Event {\n if (!functionResponseEvents.length) {\n throw new Error('No function response events provided.');\n }\n\n if (functionResponseEvents.length === 1) {\n return functionResponseEvents[0];\n }\n const mergedParts: Part[] = [];\n for (const event of functionResponseEvents) {\n if (event.content && event.content.parts) {\n mergedParts.push(...event.content.parts);\n }\n }\n\n const baseEvent = functionResponseEvents[0];\n\n const actionsList = functionResponseEvents.map(event => event.actions || {});\n const mergedActions = mergeEventActions(actionsList);\n\n return createEvent({\n author: baseEvent.author,\n branch: baseEvent.branch,\n content: {role: 'user', parts: mergedParts},\n actions: mergedActions,\n timestamp: baseEvent.timestamp!,\n });\n}\n\n// TODO - b/425992518: support function call in live connection.\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {State} from '../sessions/state.js';\n\nimport {AuthCredential} from './auth_credential.js';\nimport {AuthConfig} from './auth_tool.js';\n\n// TODO(b/425992518): Implement the rest\n/**\n * A handler that handles the auth flow in Agent Development Kit to help\n * orchestrates the credential request and response flow (e.g. OAuth flow)\n * This class should only be used by Agent Development Kit.\n */\nexport class AuthHandler {\n constructor(private readonly authConfig: AuthConfig) {}\n\n getAuthResponse(state: State): AuthCredential|undefined {\n const credentialKey = 'temp:' + this.authConfig.credentialKey;\n\n return state.get<AuthCredential>(credentialKey);\n }\n\n generateAuthRequest(): AuthConfig {\n const authSchemeType = this.authConfig.authScheme.type;\n\n if (!['oauth2', 'openIdConnect'].includes(authSchemeType)) {\n return this.authConfig;\n }\n\n if (this.authConfig.exchangedAuthCredential?.oauth2?.authUri) {\n return this.authConfig;\n }\n\n if (!this.authConfig.rawAuthCredential) {\n throw new Error(`Auth Scheme ${authSchemeType} requires authCredential.`);\n }\n\n if (!this.authConfig.rawAuthCredential.oauth2) {\n throw new Error(\n `Auth Scheme ${authSchemeType} requires oauth2 in authCredential.`);\n }\n\n if (this.authConfig.rawAuthCredential.oauth2.authUri) {\n return {\n credentialKey: this.authConfig.credentialKey,\n authScheme: this.authConfig.authScheme,\n rawAuthCredential: this.authConfig.rawAuthCredential,\n exchangedAuthCredential: this.authConfig.rawAuthCredential,\n };\n }\n\n if (!this.authConfig.rawAuthCredential.oauth2.clientId ||\n !this.authConfig.rawAuthCredential.oauth2.clientSecret) {\n throw new Error(`Auth Scheme ${\n authSchemeType} requires both clientId and clientSecret in authCredential.oauth2.`);\n }\n\n return {\n credentialKey: this.authConfig.credentialKey,\n authScheme: this.authConfig.authScheme,\n rawAuthCredential: this.authConfig.rawAuthCredential,\n exchangedAuthCredential: this.generateAuthUri(),\n };\n }\n\n /**\n * Generates an response containing the auth uri for user to sign in.\n *\n * @return An AuthCredential object containing the auth URI and state.\n * @throws Error: If the authorization endpoint is not configured in the\n * auth scheme.\n */\n generateAuthUri(): AuthCredential|undefined {\n return this.authConfig.rawAuthCredential;\n // TODO - b/425992518: Implement the rest of the function\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * Represents a tool confirmation configuration.\n * @experimental (Experimental, subject to change)\n */\nexport class ToolConfirmation {\n /** The hint text for why the input is needed. */\n hint: string;\n\n /** Whether the tool excution is confirmed. */\n confirmed: boolean;\n\n /**\n * The custom data payload needed from the user to continue the flow.\n * It should be JSON serializable.\n */\n payload?: unknown;\n\n constructor({\n hint,\n confirmed,\n payload,\n }: {\n hint?: string, confirmed: boolean,\n payload?: unknown,\n }) {\n this.hint = hint ?? '';\n this.confirmed = confirmed;\n this.payload = payload;\n }\n}", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {CallbackContext} from '../agents/callback_context.js';\nimport {InvocationContext} from '../agents/invocation_context.js';\nimport {AuthCredential} from '../auth/auth_credential.js';\nimport {AuthHandler} from '../auth/auth_handler.js';\nimport {AuthConfig} from '../auth/auth_tool.js';\nimport {EventActions} from '../events/event_actions.js';\nimport {SearchMemoryResponse} from '../memory/base_memory_service.js';\nimport {ToolConfirmation} from '../tools/tool_confirmation.js';\n\n/*\n * The context of the tool.\n *\n * This class provides the context for a tool invocation, including access to\n * the invocation context, function call ID, event actions, and authentication\n * response. It also provides methods for requesting credentials, retrieving\n * authentication responses, listing artifacts, and searching memory.\n */\nexport class ToolContext extends CallbackContext {\n readonly functionCallId?: string;\n toolConfirmation?: ToolConfirmation;\n\n /**\n * @param params.invocationContext The invocation context of the tool.\n * @param params.eventActions The event actions of the current tool call.\n * @param params.functionCallId The function call id of the current tool call.\n * This id was returned in the function call event from LLM to identify a\n * function call. If LLM didn't return this id, ADK will assign one to it.\n * This id is used to map function call response to the original function\n * call.\n * @param params.toolConfirmation The tool confirmation of the current tool\n * call.\n */\n constructor({\n invocationContext,\n eventActions,\n functionCallId,\n toolConfirmation,\n }: {\n invocationContext: InvocationContext,\n eventActions?: EventActions,\n functionCallId?: string,\n toolConfirmation?: ToolConfirmation,\n }) {\n super({invocationContext, eventActions});\n this.functionCallId = functionCallId;\n this.toolConfirmation = toolConfirmation;\n }\n\n get actions(): EventActions {\n return this.eventActions;\n }\n\n requestCredential(authConfig: AuthConfig) {\n if (!this.functionCallId) {\n throw new Error('functionCallId is not set.');\n }\n\n const authHandler = new AuthHandler(authConfig);\n this.eventActions.requestedAuthConfigs[this.functionCallId] =\n authHandler.generateAuthRequest();\n }\n\n /**\n * Gets the auth credential for the given auth config.\n *\n * @param authConfig The auth config to get the auth credential for.\n * @return The auth credential for the given auth config.\n */\n getAuthResponse(authConfig: AuthConfig): AuthCredential|undefined {\n const authHandler = new AuthHandler(authConfig);\n\n return authHandler.getAuthResponse(this.state);\n }\n\n /**\n * Lists the filenames of the artifacts attached to the current session.\n *\n * @return A promise that resolves to a list of artifact filenames.\n */\n listArtifacts(): Promise<string[]> {\n if (!this.invocationContext.artifactService) {\n throw new Error('Artifact service is not initialized.');\n }\n\n return this.invocationContext.artifactService.listArtifactKeys({\n appName: this.invocationContext.session.appName,\n userId: this.invocationContext.session.userId,\n sessionId: this.invocationContext.session.id,\n });\n }\n\n /**\n * Searches the memory of the current user.\n *\n * @param query The query to search memory for.\n * @return A promise that resolves to SearchMemoryResponse containing the\n * matching memories.\n */\n searchMemory(query: string): Promise<SearchMemoryResponse> {\n if (!this.invocationContext.memoryService) {\n throw new Error('Memory service is not initialized.');\n }\n\n return this.invocationContext.memoryService.searchMemory({\n appName: this.invocationContext.session.appName,\n userId: this.invocationContext.session.userId,\n query,\n });\n }\n\n /**\n * Requests confirmation for the current tool call.\n */\n requestConfirmation({hint, payload}: {hint?: string, payload?: unknown}) {\n if (!this.functionCallId) {\n throw new Error('functionCallId is not set.');\n }\n this.eventActions.requestedToolConfirmations[this.functionCallId] =\n new ToolConfirmation({\n hint: hint,\n confirmed: false,\n payload: payload,\n });\n }\n}", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/** Log levels for the logger. */\nexport enum LogLevel {\n DEBUG = 0,\n INFO = 1,\n WARN = 2,\n ERROR = 3,\n}\n\n/**\n * Logger interface for ADK.\n */\nexport interface Logger {\n log(level: LogLevel, ...args: unknown[]): void;\n\n debug(...args: unknown[]): void;\n\n info(...args: unknown[]): void;\n\n warn(...args: unknown[]): void;\n\n error(...args: unknown[]): void;\n}\n\nlet logLevel = LogLevel.INFO;\n\n/**\n * Sets the log level for the logger.\n */\nexport function setLogLevel(level: LogLevel) {\n logLevel = level;\n}\n\n/**\n * Simple logger class for ADK.\n */\nclass SimpleLogger implements Logger {\n log(level: LogLevel, ...args: unknown[]) {\n if (level < logLevel) {\n return;\n }\n\n switch (level) {\n case LogLevel.DEBUG:\n this.debug(...args);\n break;\n case LogLevel.INFO:\n this.info(...args);\n break;\n case LogLevel.WARN:\n this.warn(...args);\n break;\n case LogLevel.ERROR:\n this.error(...args);\n break;\n default:\n throw new Error(`Unsupported log level: ${level}`);\n }\n }\n\n debug(...args: unknown[]) {\n if (logLevel > LogLevel.DEBUG) {\n return;\n }\n\n console.debug(getColoredPrefix(LogLevel.DEBUG), ...args);\n }\n\n info(...args: unknown[]) {\n if (logLevel > LogLevel.INFO) {\n return;\n }\n\n console.info(getColoredPrefix(LogLevel.INFO), ...args);\n }\n\n warn(...args: unknown[]) {\n if (logLevel > LogLevel.WARN) {\n return;\n }\n\n console.warn(getColoredPrefix(LogLevel.WARN), ...args);\n }\n\n error(...args: unknown[]) {\n if (logLevel > LogLevel.ERROR) {\n return;\n }\n\n console.error(getColoredPrefix(LogLevel.ERROR), ...args);\n }\n}\n\nconst LOG_LEVEL_STR: Record<LogLevel, string> = {\n [LogLevel.DEBUG]: 'DEBUG',\n [LogLevel.INFO]: 'INFO',\n [LogLevel.WARN]: 'WARN',\n [LogLevel.ERROR]: 'ERROR',\n};\n\nconst CONSOLE_COLOR_MAP: Record<LogLevel, string> = {\n [LogLevel.DEBUG]: '\\x1b[34m', // Blue\n [LogLevel.INFO]: '\\x1b[32m', // Green\n [LogLevel.WARN]: '\\x1b[33m', // Yellow\n [LogLevel.ERROR]: '\\x1b[31m', // Red\n};\n\nconst RESET_COLOR = '\\x1b[0m';\n\nfunction getColoredPrefix(level: LogLevel): string {\n return `${CONSOLE_COLOR_MAP[level]}[ADK ${LOG_LEVEL_STR[level]}]:${\n RESET_COLOR}`;\n}\n\n/**\n * The logger instance for ADK.\n */\nexport const logger = new SimpleLogger();", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {ActivityEnd, ActivityStart, Blob, Content} from '@google/genai';\n\n/**\n * Request sent to live agents.\n */\nexport interface LiveRequest {\n /** If set, send the content to the model in turn-by-turn mode. */\n content?: Content;\n /** If set, send the blob to the model in realtime mode. */\n blob?: Blob;\n /** If set, signal the start of user activity to the model. */\n activityStart?: ActivityStart;\n /** If set, signal the end of user activity to the model. */\n activityEnd?: ActivityEnd;\n /** If set, close the queue. */\n close?: boolean;\n}\n\n/** Function type for resolving a Promise with a LiveRequest. */\ntype PromiseResolveFn = (req: LiveRequest) => void;\n\n/**\n * Queue used to send LiveRequest in a live (bidirectional streaming) way.\n */\nexport class LiveRequestQueue {\n // Keeps track of the data that are waiting to be sent.\n private readonly queue: LiveRequest[] = [];\n // Keeps track of the promises that are waiting for data.\n private readonly resolveFnFifoQueue: PromiseResolveFn[] = [];\n private isClosed = false;\n\n /**\n * Adds a request to the queue. If there is a pending `get()` call, it\n * will be resolved with the given request.\n * @param req The request to send.\n */\n send(req: LiveRequest) {\n if (this.isClosed) {\n throw new Error('Cannot send to a closed queue.');\n }\n if (this.resolveFnFifoQueue.length > 0) {\n const resolve = this.resolveFnFifoQueue.shift()!;\n resolve(req);\n } else {\n this.queue.push(req);\n }\n }\n\n /**\n * Retrieves a request from the queue. If the queue is empty, it will\n * wait until a request is available.\n * @returns A promise that resolves with the next available request.\n */\n async get(): Promise<LiveRequest> {\n if (this.queue.length > 0) {\n return this.queue.shift()!;\n }\n if (this.isClosed) {\n return {close: true};\n }\n return new Promise<LiveRequest>((resolve) => {\n this.resolveFnFifoQueue.push(resolve);\n });\n }\n\n /**\n * Sends a close signal to the queue.\n */\n close() {\n if (this.isClosed) {\n return;\n }\n this.isClosed = true;\n\n // Satisfy pending gets with existing queue items\n while (this.resolveFnFifoQueue.length > 0 && this.queue.length > 0) {\n const resolve = this.resolveFnFifoQueue.shift()!;\n const req = this.queue.shift()!;\n resolve(req);\n }\n\n // Resolve remaining pending gets with close signal\n const closeRequest: LiveRequest = {close: true};\n while (this.resolveFnFifoQueue.length > 0) {\n const resolve = this.resolveFnFifoQueue.shift()!;\n resolve(closeRequest);\n }\n\n // Remaining items in this.queue will be drained by subsequent get() calls.\n }\n\n /**\n * Sends a content object to the queue.\n * @param content The content to send.\n */\n sendContent(content: Content) {\n this.send({content});\n }\n\n /**\n * Sends a blob to the model in realtime mode.\n * @param blob The blob to send.\n */\n sendRealtime(blob: Blob) {\n this.send({blob});\n }\n\n /**\n * Sends an activity start signal to mark the beginning of user input.\n */\n sendActivityStart() {\n this.send({activityStart: {}});\n }\n\n /**\n * Sends an activity end signal to mark the end of user input.\n */\n sendActivityEnd() {\n this.send({activityEnd: {}});\n }\n\n /**\n * Implements the async iterator protocol.\n */\n async *\n [Symbol.asyncIterator](): AsyncGenerator<LiveRequest, void, undefined> {\n while (true) {\n const request = await this.get();\n yield request;\n if (request.close) {\n break;\n }\n }\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Content, FunctionCall, GenerateContentConfig, Schema, Part } from '@google/genai';\nimport { z } from 'zod';\n\nimport { BaseCodeExecutor } from '../code_executors/base_code_executor.js';\nimport { BuiltInCodeExecutor } from '../code_executors/built_in_code_executor.js';\nimport { buildCodeExecutionResultPart, buildExecutableCodePart, CodeExecutionResult, convertCodeExecutionParts, extractCodeAndTruncateContent, File } from '../code_executors/code_execution_utils.js';\nimport { CodeExecutorContext } from '../code_executors/code_executor_context.js';\nimport { createEvent, createNewEventId, Event, getFunctionCalls, getFunctionResponses, isFinalResponse } from '../events/event.js';\nimport { EventActions, createEventActions } from '../events/event_actions.js';\nimport { BaseExampleProvider } from '../examples/base_example_provider.js';\nimport { Example } from '../examples/example.js';\nimport { BaseLlm, isBaseLlm } from '../models/base_llm.js';\nimport { appendInstructions, LlmRequest, setOutputSchema } from '../models/llm_request.js';\nimport { LlmResponse } from '../models/llm_response.js';\nimport { LLMRegistry } from '../models/registry.js';\nimport { State } from '../sessions/state.js';\nimport { BaseTool } from '../tools/base_tool.js';\nimport { BaseToolset } from '../tools/base_toolset.js';\nimport { FunctionTool } from '../tools/function_tool.js';\nimport { ToolConfirmation } from '../tools/tool_confirmation.js';\nimport { ToolContext } from '../tools/tool_context.js';\nimport { deepClone } from '../utils/deep_clone.js';\nimport { base64Decode } from '../utils/env_aware_utils.js';\nimport { logger } from '../utils/logger.js';\n\nimport { BaseAgent, BaseAgentConfig } from './base_agent.js';\nimport { BaseLlmRequestProcessor, BaseLlmResponseProcessor } from './base_llm_processor.js';\nimport { CallbackContext } from './callback_context.js';\nimport { getContents, getCurrentTurnContents } from './content_processor_utils.js';\nimport { generateAuthEvent, generateRequestConfirmationEvent, getLongRunningFunctionCalls, handleFunctionCallList, handleFunctionCallsAsync, populateClientFunctionCallId, REQUEST_CONFIRMATION_FUNCTION_CALL_NAME } from './functions.js';\nimport { injectSessionState } from './instructions.js';\nimport { InvocationContext } from './invocation_context.js';\nimport { ReadonlyContext } from './readonly_context.js';\nimport { StreamingMode } from './run_config.js';\n\n/** An object that can provide an instruction string. */\nexport type InstructionProvider = (\n context: ReadonlyContext,\n) => string | Promise<string>;\n\n/**\n * A callback that runs before a request is sent to the model.\n *\n * @param context The current callback context.\n * @param request The raw model request. Callback can mutate the request.\n * @returns The content to return to the user. When present, the model call\n * will be skipped and the provided content will be returned to user.\n */\nexport type SingleBeforeModelCallback =\n (params: { context: CallbackContext; request: LlmRequest; }) =>\n LlmResponse | undefined | Promise<LlmResponse | undefined>;\n\n/**\n * A single callback or a list of callbacks.\n *\n * When a list of callbacks is provided, the callbacks will be called in the\n * order they are listed until a callback does not return None.\n */\nexport type BeforeModelCallback =\n | SingleBeforeModelCallback | SingleBeforeModelCallback[];\n\n/**\n * A callback that runs after a response is received from the model.\n *\n * @param context The current callback context.\n * @param response The actual model response.\n * @returns The content to return to the user. When present, the actual model\n * response will be ignored and the provided content will be returned to\n * user.\n */\nexport type SingleAfterModelCallback =\n (params: { context: CallbackContext; response: LlmResponse; }) =>\n LlmResponse | undefined | Promise<LlmResponse | undefined>;\n\n/**\n * A single callback or a list of callbacks.\n *\n * When a list of callbacks is provided, the callbacks will be called in the\n order they are listed until a callback does not return None.\n */\nexport type AfterModelCallback =\n | SingleAfterModelCallback | SingleAfterModelCallback[];\n\n/** A generic dictionary type. */\nexport type Dict = {\n [key: string]: unknown\n};\n\n/**\n * A callback that runs before a tool is called.\n *\n * @param tool The tool to be called.\n * @param args The arguments to the tool.\n * @param tool_context: ToolContext,\n * @returns The tool response. When present, the returned tool response will\n * be used and the framework will skip calling the actual tool.\n */\nexport type SingleBeforeToolCallback =\n (params: { tool: BaseTool; args: Dict; context: ToolContext; }) =>\n Dict | undefined | Promise<Dict | undefined>;\n\n/**\n * A single callback or a list of callbacks.\n *\n * When a list of callbacks is provided, the callbacks will be called in the\n * order they are listed until a callback does not return None.\n */\nexport type BeforeToolCallback =\n | SingleBeforeToolCallback | SingleBeforeToolCallback[];\n\n/**\n * A callback that runs after a tool is called.\n *\n * @param tool The tool to be called.\n * @param args The arguments to the tool.\n * @param tool_context: ToolContext,\n * @param tool_response: The response from the tool.\n * @returns When present, the returned dict will be used as tool result.\n */\nexport type SingleAfterToolCallback = (params: {\n tool: BaseTool; args: Dict; context: ToolContext; response: Dict;\n}) => Dict | undefined | Promise<Dict | undefined>;\n\n/**\n * A single callback or a list of callbacks.\n *\n * When a list of callbacks is provided, the callbacks will be called in the\n * order they are listed until acallback does not return None.\n */\nexport type AfterToolCallback =\n | SingleAfterToolCallback | SingleAfterToolCallback[];\n\n/** A list of examples or an example provider. */\nexport type ExamplesUnion = Example[] | BaseExampleProvider;\n\n/** A union of tool types that can be provided to an agent. */\nexport type ToolUnion = BaseTool | BaseToolset;\n\nconst ADK_AGENT_NAME_LABEL_KEY = 'adk_agent_name';\n\nexport interface LlmAgentConfig extends BaseAgentConfig {\n /**\n * The model to use for the agent.\n */\n model?: string | BaseLlm;\n\n /** Instructions for the LLM model, guiding the agent's behavior. */\n instruction?: string | InstructionProvider;\n\n /**\n * Instructions for all the agents in the entire agent tree.\n *\n * ONLY the globalInstruction in root agent will take effect.\n *\n * For example: use globalInstruction to make all agents have a stable\n * identity or personality.\n */\n globalInstruction?: string | InstructionProvider;\n\n /** Tools available to this agent. */\n tools?: ToolUnion[];\n\n /**\n * The additional content generation configurations.\n *\n * NOTE: not all fields are usable, e.g. tools must be configured via\n * `tools`, thinking_config must be configured via `planner` in LlmAgent.\n *\n * For example: use this config to adjust model temperature, configure safety\n * settings, etc.\n */\n generateContentConfig?: GenerateContentConfig;\n\n /**\n * Disallows LLM-controlled transferring to the parent agent.\n *\n * NOTE: Setting this as True also prevents this agent to continue reply to\n * the end-user. This behavior prevents one-way transfer, in which end-user\n * may be stuck with one agent that cannot transfer to other agents in the\n * agent tree.\n */\n disallowTransferToParent?: boolean;\n\n /** Disallows LLM-controlled transferring to the peer agents. */\n disallowTransferToPeers?: boolean;\n\n // TODO - b/425992518: consider more complex contex engineering mechanims.\n /**\n * Controls content inclusion in model requests.\n *\n * Options:\n * default: Model receives relevant conversation history\n * none: Model receives no prior history, operates solely on current\n * instruction and input\n */\n includeContents?: 'default' | 'none';\n\n /** The input schema when agent is used as a tool. */\n inputSchema?: Schema;\n\n /**\n * The output schema when agent replies.\n *\n * NOTE:\n * When this is set, agent can ONLY reply and CANNOT use any tools, such as\n * function tools, RAGs, agent transfer, etc.\n */\n outputSchema?: Schema;\n\n /**\n * The key in session state to store the output of the agent.\n *\n * Typically use cases:\n * - Extracts agent reply for later use, such as in tools, callbacks, etc.\n * - Connects agents to coordinate with each other.\n */\n outputKey?: string;\n\n /**\n * Callbacks to be called before calling the LLM.\n */\n beforeModelCallback?: BeforeModelCallback;\n\n /**\n * Callbacks to be called after calling the LLM.\n */\n afterModelCallback?: AfterModelCallback;\n\n /**\n * Callbacks to be called before calling the tool.\n */\n beforeToolCallback?: BeforeToolCallback;\n\n /**\n * Callbacks to be called after calling the tool.\n */\n afterToolCallback?: AfterToolCallback;\n\n /**\n * Processors to run before the LLM request is sent.\n */\n requestProcessors?: BaseLlmRequestProcessor[];\n\n /**\n * Processors to run after the LLM response is received.\n */\n responseProcessors?: BaseLlmResponseProcessor[];\n\n /**\n * Instructs the agent to make a plan and execute it step by step.\n */\n codeExecutor?: BaseCodeExecutor;\n}\n\nasync function convertToolUnionToTools(\n toolUnion: ToolUnion,\n context?: ReadonlyContext,\n): Promise<BaseTool[]> {\n if (toolUnion instanceof BaseTool) {\n return [toolUnion];\n }\n return await toolUnion.getTools(context);\n}\n\n// --------------------------------------------------------------------------\n// #START Request Processors\n// --------------------------------------------------------------------------\nclass BasicLlmRequestProcessor extends BaseLlmRequestProcessor {\n override async *\n runAsync(\n invocationContext: InvocationContext,\n llmRequest: LlmRequest,\n ): AsyncGenerator<Event, void, void> {\n const agent = invocationContext.agent;\n if (!(agent instanceof LlmAgent)) {\n return;\n }\n\n // set model string, not model instance.\n llmRequest.model = agent.canonicalModel.model;\n\n llmRequest.config = { ...agent.generateContentConfig ?? {} };\n if (agent.outputSchema) {\n setOutputSchema(llmRequest, agent.outputSchema);\n }\n\n if (invocationContext.runConfig) {\n llmRequest.liveConnectConfig.responseModalities =\n invocationContext.runConfig.responseModalities;\n llmRequest.liveConnectConfig.speechConfig =\n invocationContext.runConfig.speechConfig;\n llmRequest.liveConnectConfig.outputAudioTranscription =\n invocationContext.runConfig.outputAudioTranscription;\n llmRequest.liveConnectConfig.inputAudioTranscription =\n invocationContext.runConfig.inputAudioTranscription;\n llmRequest.liveConnectConfig.realtimeInputConfig =\n invocationContext.runConfig.realtimeInputConfig;\n llmRequest.liveConnectConfig.enableAffectiveDialog =\n invocationContext.runConfig.enableAffectiveDialog;\n llmRequest.liveConnectConfig.proactivity =\n invocationContext.runConfig.proactivity;\n }\n }\n}\nconst BASIC_LLM_REQUEST_PROCESSOR = new BasicLlmRequestProcessor();\n\n\nclass IdentityLlmRequestProcessor extends BaseLlmRequestProcessor {\n override async *\n runAsync(\n invocationContext: InvocationContext,\n llmRequest: LlmRequest,\n ): AsyncGenerator<Event, void, undefined> {\n const agent = invocationContext.agent;\n const si = [`You are an agent. Your internal name is \"${agent.name}\".`];\n if (agent.description) {\n si.push(`The description about you is \"${agent.description}\"`);\n }\n appendInstructions(llmRequest, si);\n }\n}\nconst IDENTITY_LLM_REQUEST_PROCESSOR = new IdentityLlmRequestProcessor();\n\n\nclass InstructionsLlmRequestProcessor extends BaseLlmRequestProcessor {\n /**\n * Handles instructions and global instructions for LLM flow.\n */\n async *\n runAsync(\n invocationContext: InvocationContext,\n llmRequest: LlmRequest,\n ): AsyncGenerator<Event, void, void> {\n const agent = invocationContext.agent;\n if (!(agent instanceof LlmAgent) ||\n !(agent.rootAgent instanceof LlmAgent)) {\n return;\n }\n const rootAgent: LlmAgent = agent.rootAgent;\n\n // TODO - b/425992518: unexpected and buggy for performance.\n // Global instruction should be explicitly scoped.\n // Step 1: Appends global instructions if set by RootAgent.\n if (rootAgent instanceof LlmAgent && rootAgent.globalInstruction) {\n const { instruction, requireStateInjection } =\n await rootAgent.canonicalGlobalInstruction(\n new ReadonlyContext(invocationContext),\n );\n let instructionWithState = instruction;\n if (requireStateInjection) {\n instructionWithState = await injectSessionState(\n instruction,\n new ReadonlyContext(invocationContext),\n );\n }\n appendInstructions(llmRequest, [instructionWithState]);\n }\n\n // Step 2: Appends agent local instructions if set.\n // TODO - b/425992518: requireStateInjection means user passed a\n // instruction processor. We need to make it more explicit.\n if (agent.instruction) {\n const { instruction, requireStateInjection } =\n await agent.canonicalInstruction(\n new ReadonlyContext(invocationContext),\n );\n let instructionWithState = instruction;\n if (requireStateInjection) {\n instructionWithState = await injectSessionState(\n instruction,\n new ReadonlyContext(invocationContext),\n );\n }\n appendInstructions(llmRequest, [instructionWithState]);\n }\n }\n}\nconst INSTRUCTIONS_LLM_REQUEST_PROCESSOR =\n new InstructionsLlmRequestProcessor();\n\n\nclass ContentRequestProcessor implements BaseLlmRequestProcessor {\n async *\n runAsync(invocationContext: InvocationContext, llmRequest: LlmRequest):\n AsyncGenerator<Event, void, void> {\n const agent = invocationContext.agent;\n if (!agent || !(agent instanceof LlmAgent)) {\n return;\n }\n\n if (agent.includeContents === 'default') {\n // Include full conversation history\n llmRequest.contents = getContents(\n invocationContext.session.events,\n agent.name,\n invocationContext.branch,\n );\n } else {\n // Include current turn context only (no conversation history).\n llmRequest.contents = getCurrentTurnContents(\n invocationContext.session.events,\n agent.name,\n invocationContext.branch,\n );\n }\n\n return;\n }\n}\nconst CONTENT_REQUEST_PROCESSOR = new ContentRequestProcessor();\n\nclass AgentTransferLlmRequestProcessor extends BaseLlmRequestProcessor {\n private readonly toolName = 'transfer_to_agent' as const;\n private readonly tool = new FunctionTool({\n name: this.toolName,\n description:\n 'Transfer the question to another agent. This tool hands off control to another agent when it is more suitable to answer the user question according to the agent description.',\n parameters: z.object({\n agentName: z.string().describe('the agent name to transfer to.'),\n }),\n execute:\n function (args: { agentName: string }, toolContext?: ToolContext) {\n if (!toolContext) {\n throw new Error('toolContext is required.');\n }\n toolContext.actions.transferToAgent = args.agentName;\n return 'Transfer queued';\n },\n });\n\n override async *\n runAsync(\n invocationContext: InvocationContext,\n llmRequest: LlmRequest,\n ): AsyncGenerator<Event, void, void> {\n if (!(invocationContext.agent instanceof LlmAgent)) {\n return;\n }\n\n const transferTargets = this.getTransferTargets(invocationContext.agent);\n if (!transferTargets.length) {\n return;\n }\n\n appendInstructions(llmRequest, [\n this.buildTargetAgentsInstructions(\n invocationContext.agent,\n transferTargets,\n ),\n ]);\n\n const toolContext = new ToolContext({ invocationContext });\n await this.tool.processLlmRequest({ toolContext, llmRequest });\n }\n\n private buildTargetAgentsInfo(targetAgent: BaseAgent): string {\n return `\nAgent name: ${targetAgent.name}\nAgent description: ${targetAgent.description}\n`;\n }\n\n private buildTargetAgentsInstructions(\n agent: LlmAgent,\n targetAgents: BaseAgent[],\n ): string {\n let instructions = `\nYou have a list of other agents to transfer to:\n\n${targetAgents.map(this.buildTargetAgentsInfo).join('\\n')}\n\nIf you are the best to answer the question according to your description, you\ncan answer it.\n\nIf another agent is better for answering the question according to its\ndescription, call \\`${this.toolName}\\` function to transfer the\nquestion to that agent. When transferring, do not generate any text other than\nthe function call.\n`;\n\n if (agent.parentAgent && !agent.disallowTransferToParent) {\n instructions += `\nYour parent agent is ${agent.parentAgent.name}. If neither the other agents nor\nyou are best for answering the question according to the descriptions, transfer\nto your parent agent.\n`;\n }\n return instructions;\n }\n\n private getTransferTargets(agent: LlmAgent): BaseAgent[] {\n const targets: BaseAgent[] = [];\n targets.push(...agent.subAgents);\n\n if (!agent.parentAgent || !(agent.parentAgent instanceof LlmAgent)) {\n return targets;\n }\n\n if (!agent.disallowTransferToParent) {\n targets.push(agent.parentAgent);\n }\n\n if (!agent.disallowTransferToPeers) {\n targets.push(\n ...agent.parentAgent.subAgents.filter(\n (peerAgent) => peerAgent.name !== agent.name,\n ),\n );\n }\n\n return targets;\n }\n}\nconst AGENT_TRANSFER_LLM_REQUEST_PROCESSOR =\n new AgentTransferLlmRequestProcessor();\n\n\nclass RequestConfirmationLlmRequestProcessor extends BaseLlmRequestProcessor {\n /** Handles tool confirmation information to build the LLM request. */\n override async *\n runAsync(\n invocationContext: InvocationContext,\n llmRequest: LlmRequest,\n ): AsyncGenerator<Event, void, void> {\n const agent = invocationContext.agent;\n if (!(agent instanceof LlmAgent)) {\n return;\n }\n const events = invocationContext.session.events;\n if (!events || events.length === 0) {\n return;\n }\n\n const requestConfirmationFunctionResponses:\n { [key: string]: ToolConfirmation } = {};\n\n let confirmationEventIndex = -1;\n // Step 1: Find the FIRST confirmation event authored by user.\n for (let i = events.length - 1; i >= 0; i--) {\n const event = events[i];\n if (event.author !== 'user') {\n continue;\n }\n const responses = getFunctionResponses(event);\n if (!responses) {\n continue;\n }\n\n let foundConfirmation = false;\n for (const functionResponse of responses) {\n if (functionResponse.name !== REQUEST_CONFIRMATION_FUNCTION_CALL_NAME) {\n continue;\n }\n foundConfirmation = true;\n\n let toolConfirmation = null;\n\n if (functionResponse.response &&\n Object.keys(functionResponse.response).length === 1 &&\n 'response' in functionResponse.response) {\n toolConfirmation =\n JSON.parse(functionResponse.response['response'] as string) as\n ToolConfirmation;\n } else if (functionResponse.response) {\n toolConfirmation = new ToolConfirmation({\n hint: functionResponse.response['hint'] as string,\n payload: functionResponse.response['payload'],\n confirmed: functionResponse.response['confirmed'] as boolean,\n });\n }\n\n if (functionResponse.id && toolConfirmation) {\n requestConfirmationFunctionResponses[functionResponse.id] =\n toolConfirmation;\n }\n }\n if (foundConfirmation) {\n confirmationEventIndex = i;\n break;\n }\n }\n\n if (Object.keys(requestConfirmationFunctionResponses).length === 0) {\n return;\n }\n\n // Step 2: Find the system generated FunctionCall event requesting the tool\n // confirmation\n for (let i = confirmationEventIndex - 1; i >= 0; i--) {\n const event = events[i];\n const functionCalls = getFunctionCalls(event);\n if (!functionCalls) {\n continue;\n }\n\n const toolsToResumeWithConfirmation:\n { [key: string]: ToolConfirmation } = {};\n const toolsToResumeWithArgs: { [key: string]: FunctionCall } = {};\n\n for (const functionCall of functionCalls) {\n if (!functionCall.id ||\n !(functionCall.id in requestConfirmationFunctionResponses)) {\n continue;\n }\n\n const args = functionCall.args;\n if (!args || !('originalFunctionCall' in args)) {\n continue;\n }\n const originalFunctionCall =\n args['originalFunctionCall'] as FunctionCall;\n\n if (originalFunctionCall.id) {\n toolsToResumeWithConfirmation[originalFunctionCall.id] =\n requestConfirmationFunctionResponses[functionCall.id];\n toolsToResumeWithArgs[originalFunctionCall.id] = originalFunctionCall;\n }\n }\n if (Object.keys(toolsToResumeWithConfirmation).length === 0) {\n continue;\n }\n\n // Step 3: Remove the tools that have already been confirmed AND resumed.\n for (let j = events.length - 1; j > confirmationEventIndex; j--) {\n const eventToCheck = events[j];\n const functionResponses = getFunctionResponses(eventToCheck);\n if (!functionResponses) {\n continue;\n }\n\n for (const fr of functionResponses) {\n if (fr.id && fr.id in toolsToResumeWithConfirmation) {\n delete toolsToResumeWithConfirmation[fr.id];\n delete toolsToResumeWithArgs[fr.id];\n }\n }\n if (Object.keys(toolsToResumeWithConfirmation).length === 0) {\n break;\n }\n }\n\n if (Object.keys(toolsToResumeWithConfirmation).length === 0) {\n continue;\n }\n\n const toolsList =\n await agent.canonicalTools(new ReadonlyContext(invocationContext));\n const toolsDict =\n Object.fromEntries(toolsList.map((tool) => [tool.name, tool]));\n\n const functionResponseEvent = await handleFunctionCallList({\n invocationContext: invocationContext,\n functionCalls: Object.values(toolsToResumeWithArgs),\n toolsDict: toolsDict,\n beforeToolCallbacks: agent.canonicalBeforeToolCallbacks,\n afterToolCallbacks: agent.canonicalAfterToolCallbacks,\n filters: new Set(Object.keys(toolsToResumeWithConfirmation)),\n toolConfirmationDict: toolsToResumeWithConfirmation,\n });\n\n if (functionResponseEvent) {\n yield functionResponseEvent;\n }\n return;\n }\n }\n}\n\nexport const REQUEST_CONFIRMATION_LLM_REQUEST_PROCESSOR =\n new RequestConfirmationLlmRequestProcessor();\n\n\n/**\n * Processes code execution requests.\n */\nclass CodeExecutionRequestProcessor extends BaseLlmRequestProcessor {\n override async *\n runAsync(\n invocationContext: InvocationContext,\n llmRequest: LlmRequest,\n ): AsyncGenerator<Event, void, void> {\n if (!(invocationContext.agent instanceof LlmAgent)) {\n return;\n }\n\n if (!invocationContext.agent.codeExecutor) {\n return;\n }\n\n for await (const event of runPreProcessor(invocationContext, llmRequest)) {\n yield event;\n }\n\n if (!(invocationContext.agent.codeExecutor instanceof BaseCodeExecutor)) {\n return;\n }\n\n for (const content of llmRequest.contents) {\n const delimeters: [string, string] =\n invocationContext.agent.codeExecutor.codeBlockDelimiters.length ?\n invocationContext.agent.codeExecutor.codeBlockDelimiters[0] :\n ['', ''];\n\n const codeExecutionParts = convertCodeExecutionParts(\n content,\n delimeters,\n invocationContext.agent.codeExecutor.executionResultDelimiters,\n );\n }\n }\n}\n\n/**\n * Map of MIME types to data file utilities\n */\nconst DATA_FILE_UTIL_MAP: Record<string, {\n extension: string;\n loaderCodeTemplate: string;\n}\n> = {\n 'text/csv': {\n extension: '.csv',\n loaderCodeTemplate: 'pd.read_csv(\\'{filename}\\')',\n },\n};\n\n/**\n * Helper library for data file exploration\n */\nconst DATA_FILE_HELPER_LIB = `\nimport pandas as pd\n\ndef explore_df(df: pd.DataFrame) -> None:\n \"\"\"Prints some information about a pandas DataFrame.\"\"\"\n\n with pd.option_context(\n 'display.max_columns', None, 'display.expand_frame_repr', False\n ):\n # Print the column names to never encounter KeyError when selecting one.\n df_dtypes = df.dtypes\n\n # Obtain information about data types and missing values.\n df_nulls = (len(df) - df.isnull().sum()).apply(\n lambda x: f'{x} / {df.shape[0]} non-null'\n )\n\n # Explore unique total values in columns using \\`.unique()\\`.\n df_unique_count = df.apply(lambda x: len(x.unique()))\n\n # Explore unique values in columns using \\`.unique()\\`.\n df_unique = df.apply(lambda x: crop(str(list(x.unique()))))\n\n df_info = pd.concat(\n (\n df_dtypes.rename('Dtype'),\n df_nulls.rename('Non-Null Count'),\n df_unique_count.rename('Unique Values Count'),\n df_unique.rename('Unique Values'),\n ),\n axis=1,\n )\n df_info.index.name = 'Columns'\n print(f\"\"\"Total rows: {df.shape[0]}\nTotal columns: {df.shape[1]}\n\n{df_info}\"\"\")\n`;\n\n/**\n * Processor for code execution responses.\n */\nclass CodeExecutionResponseProcessor implements BaseLlmResponseProcessor {\n /**\n * Processes the LLM response asynchronously.\n *\n * @param invocationContext The invocation context\n * @param llmResponse The LLM response to process\n * @returns An async generator yielding events\n */\n async *\n runAsync(invocationContext: InvocationContext, llmResponse: LlmResponse):\n AsyncGenerator<Event, void, unknown> {\n // Skip if the response is partial (streaming)\n if (llmResponse.partial) {\n return;\n }\n\n // Run the post-processor with standard generator approach\n for await (\n const event of runPostProcessor(invocationContext, llmResponse)) {\n yield event;\n }\n }\n}\n\n/**\n * The exported response processor instance.\n */\nexport const responseProcessor = new CodeExecutionResponseProcessor();\n\n/**\n * Pre-processes the user message by adding the user message to the execution\n * environment.\n *\n * @param invocationContext The invocation context\n * @param llmRequest The LLM request to process\n * @returns An async generator yielding events\n */\nasync function*\n runPreProcessor(\n invocationContext: InvocationContext,\n llmRequest: LlmRequest,\n ): AsyncGenerator<Event, void, unknown> {\n const agent = invocationContext.agent;\n\n if (!(agent instanceof LlmAgent)) {\n return;\n }\n\n const codeExecutor = agent.codeExecutor;\n\n if (!codeExecutor || !(codeExecutor instanceof BaseCodeExecutor)) {\n return;\n }\n\n if (codeExecutor instanceof BuiltInCodeExecutor) {\n codeExecutor.processLlmRequest(llmRequest);\n return;\n }\n\n if (!codeExecutor.optimizeDataFile) {\n return;\n }\n\n const codeExecutorContext =\n new CodeExecutorContext(new State(invocationContext.session.state));\n\n // Skip if the error count exceeds the max retry attempts\n if (codeExecutorContext.getErrorCount(invocationContext.invocationId) >=\n codeExecutor.errorRetryAttempts) {\n return;\n }\n\n // [Step 1] Extract data files from the session_history and store them in\n // memory Meanwhile, mutate the inline data file to text part in session\n // history from all turns\n const allInputFiles =\n extractAndReplaceInlineFiles(codeExecutorContext, llmRequest);\n\n // [Step 2] Run explore_df code on the data files from the current turn\n // We only need to explore the new data files because the previous data files\n // should already be explored and cached in the code execution runtime\n const processedFileNames =\n new Set(codeExecutorContext.getProcessedFileNames());\n const filesToProcess =\n allInputFiles.filter(f => !processedFileNames.has(f.name));\n\n for (const file of filesToProcess) {\n const codeStr = getDataFilePreprocessingCode(file);\n\n // Skip for unsupported file or executor types\n if (!codeStr) {\n return;\n }\n\n // Emit the code to execute, and add it to the LLM request\n const codeContent: Content = {\n role: 'model',\n parts: [\n { text: `Processing input file: \\`${file.name}\\`` },\n buildExecutableCodePart(codeStr)\n ]\n };\n\n llmRequest.contents.push(deepClone(codeContent)!);\n\n yield createEvent({\n invocationId: invocationContext.invocationId,\n author: agent.name,\n branch: invocationContext.branch,\n content: codeContent\n });\n\n const executionId =\n getOrSetExecutionId(invocationContext, codeExecutorContext);\n const codeExecutionResult = await codeExecutor.executeCode({\n invocationContext,\n codeExecutionInput: {\n code: codeStr,\n inputFiles: [file],\n executionId,\n }\n });\n\n // Update the processing results to code executor context\n codeExecutorContext.updateCodeExecutionResult({\n invocationId: invocationContext.invocationId,\n code: codeStr,\n resultStdout: codeExecutionResult.stdout,\n resultStderr: codeExecutionResult.stderr,\n });\n\n codeExecutorContext.addProcessedFileNames([file.name]);\n\n // Emit the execution result, and add it to the LLM request\n const executionResultEvent = await postProcessCodeExecutionResult(\n invocationContext,\n codeExecutorContext,\n codeExecutionResult,\n );\n\n yield executionResultEvent;\n llmRequest.contents.push(deepClone(executionResultEvent.content)!);\n }\n}\n\n/**\n * Post-processes the model response by extracting and executing the first code\n * block.\n *\n * @param invocationContext The invocation context\n * @param llmResponse The LLM response to process\n * @returns An async generator yielding events\n */\nasync function*\n runPostProcessor(\n invocationContext: InvocationContext,\n llmResponse: LlmResponse,\n ): AsyncGenerator<Event, void, unknown> {\n const agent = invocationContext.agent;\n\n if (!(agent instanceof LlmAgent)) {\n return;\n }\n\n const codeExecutor = agent.codeExecutor;\n\n if (!codeExecutor || !(codeExecutor instanceof BaseCodeExecutor)) {\n return;\n }\n\n if (!llmResponse || !llmResponse.content) {\n return;\n }\n\n if (codeExecutor instanceof BuiltInCodeExecutor) {\n return;\n }\n\n const codeExecutorContext =\n new CodeExecutorContext(new State(invocationContext.session.state));\n\n // Skip if the error count exceeds the max retry attempts\n if (codeExecutorContext.getErrorCount(invocationContext.invocationId) >=\n codeExecutor.errorRetryAttempts) {\n return;\n }\n\n // [Step 1] Extract code from the model predict response and truncate the\n // content to the part with the first code block\n const responseContent = llmResponse.content;\n const codeStr = extractCodeAndTruncateContent(\n responseContent, codeExecutor.codeBlockDelimiters);\n\n // Terminal state: no code to execute\n if (!codeStr) {\n return;\n }\n\n // [Step 2] Executes the code and emit 2 Events for code and execution result\n yield createEvent({\n invocationId: invocationContext.invocationId,\n author: agent.name,\n branch: invocationContext.branch,\n content: responseContent,\n });\n\n const executionId =\n getOrSetExecutionId(invocationContext, codeExecutorContext);\n const codeExecutionResult = await codeExecutor.executeCode({\n invocationContext,\n codeExecutionInput: {\n code: codeStr,\n inputFiles: codeExecutorContext.getInputFiles(),\n executionId,\n }\n });\n\n codeExecutorContext.updateCodeExecutionResult({\n invocationId: invocationContext.invocationId,\n code: codeStr,\n resultStdout: codeExecutionResult.stdout,\n resultStderr: codeExecutionResult.stderr,\n });\n\n yield await postProcessCodeExecutionResult(\n invocationContext,\n codeExecutorContext,\n codeExecutionResult,\n );\n\n // [Step 3] Skip processing the original model response\n // to continue code generation loop\n llmResponse.content = null as any;\n}\n\n/**\n * Extracts and replaces inline files with file names in the LLM request.\n *\n * @param codeExecutorContext The code executor context\n * @param llmRequest The LLM request to process\n * @returns A list of input files\n */\nfunction extractAndReplaceInlineFiles(\n codeExecutorContext: CodeExecutorContext, llmRequest: LlmRequest): File[] {\n const allInputFiles = codeExecutorContext.getInputFiles();\n const savedFileNames = new Set(allInputFiles.map(f => f.name));\n\n // [Step 1] Process input files from LlmRequest and cache them in CodeExecutor\n for (let i = 0; i < llmRequest.contents.length; i++) {\n const content = llmRequest.contents[i];\n\n // Only process the user message\n if (content.role !== 'user' || !content.parts) {\n continue;\n }\n\n for (let j = 0; j < content.parts.length; j++) {\n const part = content.parts[j] as Part;\n const mimeType = part.inlineData?.mimeType;\n\n // Skip if the inline data is not supported\n if (!mimeType || !part.inlineData || !DATA_FILE_UTIL_MAP[mimeType]) {\n continue;\n }\n\n // Replace the inline data file with a file name placeholder\n const fileName =\n `data_${i + 1}_${j + 1}${DATA_FILE_UTIL_MAP[mimeType].extension}`;\n\n part.text = `\\nAvailable file: \\`${fileName}\\`\\n`;\n\n // Add the inline data as input file to the code executor context\n const file: File = {\n name: fileName,\n content: base64Decode(part.inlineData.data!),\n mimeType\n };\n\n if (!savedFileNames.has(fileName)) {\n codeExecutorContext.addInputFiles([file]);\n allInputFiles.push(file);\n }\n }\n }\n\n return allInputFiles;\n}\n\n/**\n * Gets or sets the execution ID for stateful code execution.\n *\n * @param invocationContext The invocation context\n * @param codeExecutorContext The code executor context\n * @returns The execution ID or undefined if not stateful\n */\nfunction getOrSetExecutionId(\n invocationContext: InvocationContext,\n codeExecutorContext: CodeExecutorContext): string | undefined {\n const agent = invocationContext.agent;\n\n if (!(agent instanceof LlmAgent) || !agent.codeExecutor?.stateful) {\n return undefined;\n }\n\n let executionId = codeExecutorContext.getExecutionId();\n\n if (!executionId) {\n executionId = invocationContext.session.id;\n codeExecutorContext.setExecutionId(executionId);\n }\n\n return executionId;\n}\n\n/**\n * Post-processes the code execution result and emits an Event.\n *\n * @param invocationContext The invocation context\n * @param codeExecutorContext The code executor context\n * @param codeExecutionResult The code execution result\n * @returns The event with the code execution result\n */\nasync function postProcessCodeExecutionResult(\n invocationContext: InvocationContext,\n codeExecutorContext: CodeExecutorContext,\n codeExecutionResult: CodeExecutionResult): Promise<Event> {\n if (!invocationContext.artifactService) {\n throw new Error('Artifact service is not initialized.');\n }\n\n const resultContent: Content = {\n role: 'model',\n parts: [buildCodeExecutionResultPart(codeExecutionResult)]\n };\n\n const eventActions =\n createEventActions({ stateDelta: codeExecutorContext.getStateDelta() });\n\n // Handle code execution error retry\n if (codeExecutionResult.stderr) {\n codeExecutorContext.incrementErrorCount(invocationContext.invocationId);\n } else {\n codeExecutorContext.resetErrorCount(invocationContext.invocationId);\n }\n\n // Handle output files\n for (const outputFile of codeExecutionResult.outputFiles) {\n const version = await invocationContext.artifactService.saveArtifact({\n appName: invocationContext.appName || '',\n userId: invocationContext.userId || '',\n sessionId: invocationContext.session.id,\n filename: outputFile.name,\n artifact: {\n inlineData: { data: outputFile.content, mimeType: outputFile.mimeType }\n },\n });\n\n eventActions.artifactDelta[outputFile.name] = version;\n }\n\n return createEvent({\n invocationId: invocationContext.invocationId,\n author: invocationContext.agent.name,\n branch: invocationContext.branch,\n content: resultContent,\n actions: eventActions\n });\n}\n\n/**\n * Returns the code to explore the data file.\n *\n * @param file The file to explore\n * @returns The code to explore the data file or undefined if not supported\n */\nfunction getDataFilePreprocessingCode(file: File): string | undefined {\n /**\n * Gets a normalized file name.\n *\n * @param fileName The file name to normalize\n * @returns The normalized file name\n */\n function getNormalizedFileName(fileName: string): string {\n const [varName] = fileName.split('.');\n\n // Replace non-alphanumeric characters with underscores\n let normalizedName = varName.replace(/[^a-zA-Z0-9_]/g, '_');\n\n // If the filename starts with a digit, prepend an underscore\n if (/^\\d/.test(normalizedName)) {\n normalizedName = '_' + normalizedName;\n }\n\n return normalizedName;\n }\n\n if (!DATA_FILE_UTIL_MAP[file.mimeType]) {\n return undefined;\n }\n\n const varName = getNormalizedFileName(file.name);\n const loaderCode =\n DATA_FILE_UTIL_MAP[file.mimeType].loaderCodeTemplate.replace(\n '{filename}', file.name);\n\n return `\n${DATA_FILE_HELPER_LIB}\n\n# Load the dataframe.\n${varName} = ${loaderCode}\n\n# Use \\`explore_df\\` to guide my analysis.\nexplore_df(${varName})\n`;\n}\n\nconst CODE_EXECUTION_REQUEST_PROCESSOR = new CodeExecutionRequestProcessor();\n\n// --------------------------------------------------------------------------\n// #END RequesBaseCodeExecutort Processors\n// --------------------------------------------------------------------------\n\n/**\n * An agent that uses a large language model to generate responses.\n */\nexport class LlmAgent extends BaseAgent {\n model?: string | BaseLlm;\n instruction: string | InstructionProvider;\n globalInstruction: string | InstructionProvider;\n tools: ToolUnion[];\n generateContentConfig?: GenerateContentConfig;\n disallowTransferToParent: boolean;\n disallowTransferToPeers: boolean;\n includeContents: 'default' | 'none';\n inputSchema?: Schema;\n outputSchema?: Schema;\n outputKey?: string;\n beforeModelCallback?: BeforeModelCallback;\n afterModelCallback?: AfterModelCallback;\n beforeToolCallback?: BeforeToolCallback;\n afterToolCallback?: AfterToolCallback;\n requestProcessors: BaseLlmRequestProcessor[];\n responseProcessors: BaseLlmResponseProcessor[];\n codeExecutor?: BaseCodeExecutor;\n\n constructor(config: LlmAgentConfig) {\n super(config);\n this.model = config.model;\n this.instruction = config.instruction ?? '';\n this.globalInstruction = config.globalInstruction ?? '';\n this.tools = config.tools ?? [];\n this.generateContentConfig = config.generateContentConfig;\n this.disallowTransferToParent = config.disallowTransferToParent ?? false;\n this.disallowTransferToPeers = config.disallowTransferToPeers ?? false;\n this.includeContents = config.includeContents ?? 'default';\n this.inputSchema = config.inputSchema;\n this.outputSchema = config.outputSchema;\n this.outputKey = config.outputKey;\n this.beforeModelCallback = config.beforeModelCallback;\n this.afterModelCallback = config.afterModelCallback;\n this.beforeToolCallback = config.beforeToolCallback;\n this.afterToolCallback = config.afterToolCallback;\n this.codeExecutor = config.codeExecutor;\n\n // TODO - b/425992518: Define these processor arrays.\n // Orders matter, don't change. Append new processors to the end\n this.requestProcessors = config.requestProcessors ?? [\n BASIC_LLM_REQUEST_PROCESSOR,\n IDENTITY_LLM_REQUEST_PROCESSOR,\n INSTRUCTIONS_LLM_REQUEST_PROCESSOR,\n REQUEST_CONFIRMATION_LLM_REQUEST_PROCESSOR,\n CONTENT_REQUEST_PROCESSOR,\n CODE_EXECUTION_REQUEST_PROCESSOR,\n ];\n this.responseProcessors = config.responseProcessors ?? [];\n\n // Preserve the agent transfer behavior.\n const agentTransferDisabled = this.disallowTransferToParent &&\n this.disallowTransferToPeers && !this.subAgents?.length;\n if (!agentTransferDisabled) {\n this.requestProcessors.push(AGENT_TRANSFER_LLM_REQUEST_PROCESSOR);\n }\n\n // Validate generateContentConfig.\n if (config.generateContentConfig) {\n if (config.generateContentConfig.tools) {\n throw new Error('All tools must be set via LlmAgent.tools.');\n }\n if (config.generateContentConfig.systemInstruction) {\n throw new Error(\n 'System instruction must be set via LlmAgent.instruction.',\n );\n }\n if (config.generateContentConfig.responseSchema) {\n throw new Error(\n 'Response schema must be set via LlmAgent.output_schema.');\n }\n } else {\n this.generateContentConfig = {}\n }\n\n // Validate output schema related configurations.\n if (this.outputSchema) {\n if (!this.disallowTransferToParent || !this.disallowTransferToPeers) {\n logger.warn(\n `Invalid config for agent ${this.name}: outputSchema cannot co-exist with agent transfer configurations. Setting disallowTransferToParent=true, disallowTransferToPeers=true`,\n );\n this.disallowTransferToParent = true;\n this.disallowTransferToPeers = true;\n }\n\n if (this.subAgents && this.subAgents.length > 0) {\n throw new Error(\n `Invalid config for agent ${this.name}: if outputSchema is set, subAgents must be empty to disable agent transfer.`,\n );\n }\n\n if (this.tools && this.tools.length > 0) {\n throw new Error(\n `Invalid config for agent ${this.name}: if outputSchema is set, tools must be empty`,\n );\n }\n }\n }\n\n /**\n * The resolved BaseLlm instance.\n *\n * When not set, the agent will inherit the model from its ancestor.\n */\n get canonicalModel(): BaseLlm {\n if (isBaseLlm(this.model)) {\n return this.model;\n }\n\n if (typeof this.model === 'string' && this.model) {\n return LLMRegistry.newLlm(this.model);\n }\n\n let ancestorAgent = this.parentAgent;\n while (ancestorAgent) {\n if (ancestorAgent instanceof LlmAgent) {\n return ancestorAgent.canonicalModel;\n }\n ancestorAgent = ancestorAgent.parentAgent;\n }\n throw new Error(`No model found for ${this.name}.`);\n }\n\n /**\n * The resolved self.instruction field to construct instruction for this\n * agent.\n *\n * This method is only for use by Agent Development Kit.\n * @param context The context to retrieve the session state.\n * @returns The resolved self.instruction field.\n */\n async canonicalInstruction(context: ReadonlyContext):\n Promise<{ instruction: string, requireStateInjection: boolean }> {\n if (typeof this.instruction === 'string') {\n return { instruction: this.instruction, requireStateInjection: true };\n }\n return {\n instruction: await this.instruction(context),\n requireStateInjection: false\n };\n }\n\n /**\n * The resolved self.instruction field to construct global instruction.\n *\n * This method is only for use by Agent Development Kit.\n * @param context The context to retrieve the session state.\n * @returns The resolved self.global_instruction field.\n */\n async canonicalGlobalInstruction(context: ReadonlyContext):\n Promise<{ instruction: string, requireStateInjection: boolean }> {\n if (typeof this.globalInstruction === 'string') {\n return { instruction: this.globalInstruction, requireStateInjection: true };\n }\n return {\n instruction: await this.globalInstruction(context),\n requireStateInjection: false\n };\n }\n\n /**\n * The resolved self.tools field as a list of BaseTool based on the context.\n *\n * This method is only for use by Agent Development Kit.\n */\n async canonicalTools(context?: ReadonlyContext): Promise<BaseTool[]> {\n const resolvedTools: BaseTool[] = [];\n for (const toolUnion of this.tools) {\n const tools = await convertToolUnionToTools(toolUnion, context);\n resolvedTools.push(...tools);\n }\n return resolvedTools;\n }\n\n /**\n * Normalizes a callback or an array of callbacks into an array of callbacks.\n *\n * @param callback The callback or an array of callbacks.\n * @returns An array of callbacks.\n */\n private static normalizeCallbackArray<T>(callback?: T | T[]): T[] {\n if (!callback) {\n return [];\n }\n if (Array.isArray(callback)) {\n return callback;\n }\n return [callback];\n }\n\n /**\n * The resolved self.before_model_callback field as a list of\n * SingleBeforeModelCallback.\n *\n * This method is only for use by Agent Development Kit.\n */\n get canonicalBeforeModelCallbacks(): SingleBeforeModelCallback[] {\n return LlmAgent.normalizeCallbackArray(this.beforeModelCallback);\n }\n\n /**\n * The resolved self.after_model_callback field as a list of\n * SingleAfterModelCallback.\n *\n * This method is only for use by Agent Development Kit.\n */\n get canonicalAfterModelCallbacks(): SingleAfterModelCallback[] {\n return LlmAgent.normalizeCallbackArray(this.afterModelCallback);\n }\n\n /**\n * The resolved self.before_tool_callback field as a list of\n * BeforeToolCallback.\n *\n * This method is only for use by Agent Development Kit.\n */\n get canonicalBeforeToolCallbacks(): SingleBeforeToolCallback[] {\n return LlmAgent.normalizeCallbackArray(this.beforeToolCallback);\n }\n\n /**\n * The resolved self.after_tool_callback field as a list of AfterToolCallback.\n *\n * This method is only for use by Agent Development Kit.\n */\n get canonicalAfterToolCallbacks(): SingleAfterToolCallback[] {\n return LlmAgent.normalizeCallbackArray(this.afterToolCallback);\n }\n\n /**\n * Saves the agent's final response to the session state if configured.\n *\n * It extracts the text content from the final response event, optionally\n * parses it as JSON based on the output schema, and stores the result in the\n * session state using the specified output key.\n *\n * @param event The event to process.\n */\n private maybeSaveOutputToState(event: Event) {\n if (event.author !== this.name) {\n logger.debug(\n `Skipping output save for agent ${this.name}: event authored by ${event.author}`,\n );\n return;\n }\n if (!this.outputKey) {\n logger.debug(\n `Skipping output save for agent ${this.name}: outputKey is not set`,\n );\n return;\n }\n if (!isFinalResponse(event)) {\n logger.debug(\n `Skipping output save for agent ${this.name}: event is not a final response`,\n );\n return;\n }\n if (!event.content?.parts?.length) {\n logger.debug(\n `Skipping output save for agent ${this.name}: event content is empty`,\n );\n return;\n }\n\n const resultStr: string =\n event.content.parts.map((part) => (part.text ? part.text : ''))\n .join('');\n let result: unknown = resultStr;\n if (this.outputSchema) {\n // If the result from the final chunk is just whitespace or empty,\n // it means this is an empty final chunk of a stream.\n // Do not attempt to parse it as JSON.\n if (!resultStr.trim()) {\n return;\n }\n // TODO - b/425992518: Use a proper Schema validation utility.\n // Should use output schema to validate the JSON.\n try {\n result = JSON.parse(resultStr);\n } catch (e) {\n logger.error(`Error parsing output for agent ${this.name}`, e);\n }\n }\n event.actions.stateDelta[this.outputKey] = result;\n }\n\n protected async *\n runAsyncImpl(\n context: InvocationContext,\n ): AsyncGenerator<Event, void, void> {\n while (true) {\n let lastEvent: Event | undefined = undefined;\n for await (const event of this.runOneStepAsync(context)) {\n lastEvent = event;\n this.maybeSaveOutputToState(event);\n yield event;\n }\n\n if (!lastEvent || isFinalResponse(lastEvent)) {\n break;\n }\n if (lastEvent.partial) {\n logger.warn('The last event is partial, which is not expected.');\n break;\n }\n }\n }\n\n protected async *\n runLiveImpl(\n context: InvocationContext,\n ): AsyncGenerator<Event, void, void> {\n for await (const event of this.runLiveFlow(context)) {\n this.maybeSaveOutputToState(event);\n yield event;\n }\n if (context.endInvocation) {\n return;\n }\n }\n\n // --------------------------------------------------------------------------\n // #START LlmFlow Logic\n // --------------------------------------------------------------------------\n private async *\n runLiveFlow(\n invocationContext: InvocationContext,\n ): AsyncGenerator<Event, void, void> {\n // TODO - b/425992518: remove dummy logic, implement this.\n await Promise.resolve();\n throw new Error('LlmAgent.runLiveFlow not implemented');\n }\n\n private async *\n runOneStepAsync(\n invocationContext: InvocationContext,\n ): AsyncGenerator<Event, void, void> {\n const llmRequest: LlmRequest = {\n contents: [],\n toolsDict: {},\n liveConnectConfig: {},\n };\n\n // =========================================================================\n // Preprocess before calling the LLM\n // =========================================================================\n // Runs request processors.\n for (const processor of this.requestProcessors) {\n for await (\n const event of processor.runAsync(invocationContext, llmRequest)) {\n yield event;\n }\n }\n // TODO - b/425992518: check if tool preprocessors can be simplified.\n // Run pre-processors for tools.\n for (const toolUnion of this.tools) {\n const toolContext = new ToolContext({ invocationContext });\n\n // process all tools from this tool union\n const tools = await convertToolUnionToTools(\n toolUnion, new ReadonlyContext(invocationContext));\n for (const tool of tools) {\n await tool.processLlmRequest({ toolContext, llmRequest });\n }\n }\n // =========================================================================\n // Global runtime interruption\n // =========================================================================\n // TODO - b/425992518: global runtime interruption, hacky, fix.\n if (invocationContext.endInvocation) {\n return;\n }\n\n // =========================================================================\n // Calls the LLM\n // =========================================================================\n // TODO - b/425992518: misleading, this is passing metadata.\n const modelResponseEvent = createEvent({\n invocationId: invocationContext.invocationId,\n author: this.name,\n branch: invocationContext.branch,\n });\n for await (const llmResponse of this.callLlmAsync(\n invocationContext, llmRequest, modelResponseEvent)) {\n // ======================================================================\n // Postprocess after calling the LLM\n // ======================================================================\n for await (const event of this.postprocess(\n invocationContext, llmRequest, llmResponse, modelResponseEvent)) {\n // Update the mutable event id to avoid conflict\n modelResponseEvent.id = createNewEventId();\n modelResponseEvent.timestamp = new Date().getTime();\n yield event;\n }\n }\n }\n\n private async *\n postprocess(\n invocationContext: InvocationContext,\n llmRequest: LlmRequest,\n llmResponse: LlmResponse,\n modelResponseEvent: Event,\n ): AsyncGenerator<Event, void, void> {\n // =========================================================================\n // Runs response processors\n // =========================================================================\n for (const processor of this.responseProcessors) {\n for await (\n const event of processor.runAsync(invocationContext, llmResponse)) {\n yield event;\n }\n }\n\n // =========================================================================\n // Builds the merged model response event\n // =========================================================================\n // If no model response, skip.\n if (!llmResponse.content && !llmResponse.errorCode &&\n !llmResponse.interrupted) {\n return;\n }\n\n // Merge llm response with model response event.\n const mergedEvent = createEvent({\n ...modelResponseEvent,\n ...llmResponse,\n });\n\n if (mergedEvent.content) {\n const functionCalls = getFunctionCalls(mergedEvent);\n if (functionCalls?.length) {\n // TODO - b/425992518: rename topopulate if missing.\n populateClientFunctionCallId(mergedEvent);\n // TODO - b/425992518: hacky, transaction log, simplify.\n // Long running is a property of tool in registry.\n mergedEvent.longRunningToolIds = Array.from(\n getLongRunningFunctionCalls(functionCalls, llmRequest.toolsDict));\n }\n }\n yield mergedEvent;\n\n // =========================================================================\n // Process function calls if any, which inlcudes agent transfer.\n // =========================================================================\n if (!getFunctionCalls(mergedEvent)?.length) {\n return;\n }\n\n // Call functions\n // TODO - b/425992518: bloated funciton input, fix.\n // Tool callback passed to get rid of cyclic dependency.\n const functionResponseEvent = await handleFunctionCallsAsync({\n invocationContext: invocationContext,\n functionCallEvent: mergedEvent,\n toolsDict: llmRequest.toolsDict,\n beforeToolCallbacks: this.canonicalBeforeToolCallbacks,\n afterToolCallbacks: this.canonicalAfterToolCallbacks,\n });\n\n if (!functionResponseEvent) {\n return;\n }\n\n // Yiels an authentication event if any.\n // TODO - b/425992518: transaction log session, simplify.\n const authEvent =\n generateAuthEvent(invocationContext, functionResponseEvent);\n if (authEvent) {\n yield authEvent;\n }\n\n // Yields a tool confirmation event if any.\n const toolConfirmationEvent = generateRequestConfirmationEvent({\n invocationContext: invocationContext,\n functionCallEvent: mergedEvent,\n functionResponseEvent: functionResponseEvent,\n });\n if (toolConfirmationEvent) {\n yield toolConfirmationEvent;\n }\n\n // Yields the function response event.\n yield functionResponseEvent;\n\n // If model instruct to transfer to an agent, run the transferred agent.\n const nextAgentName = functionResponseEvent.actions.transferToAgent;\n if (nextAgentName) {\n const nextAgent = this.getAgentByName(invocationContext, nextAgentName);\n for await (const event of nextAgent.runAsync(invocationContext)) {\n yield event;\n }\n }\n }\n\n /**\n * Retrieves an agent from the agent tree by its name.\n *\n * Performing a depth-first search to locate the agent with the given name.\n * - Starts searching from the root agent of the current invocation context.\n * - Traverses down the agent tree to find the specified agent.\n *\n * @param invocationContext The current invocation context.\n * @param agentName The name of the agent to retrieve.\n * @returns The agent with the given name.\n * @throws Error if the agent is not found.\n */\n private getAgentByName(\n invocationContext: InvocationContext,\n agentName: string,\n ): BaseAgent {\n const rootAgent = invocationContext.agent.rootAgent;\n const agentToRun = rootAgent.findAgent(agentName);\n if (!agentToRun) {\n throw new Error(`Agent ${agentName} not found in the agent tree.`);\n }\n return agentToRun;\n }\n\n private async *\n callLlmAsync(\n invocationContext: InvocationContext,\n llmRequest: LlmRequest,\n modelResponseEvent: Event,\n ): AsyncGenerator<LlmResponse, void, void> {\n // Runs before_model_callback if it exists.\n const beforeModelResponse = await this.handleBeforeModelCallback(\n invocationContext, llmRequest, modelResponseEvent);\n if (beforeModelResponse) {\n yield beforeModelResponse;\n return;\n }\n\n llmRequest.config ??= {};\n llmRequest.config.labels ??= {};\n\n // Add agent name as a label to the llm_request. This will help with slicing\n // the billing reports on a per-agent basis.\n if (!llmRequest.config.labels[ADK_AGENT_NAME_LABEL_KEY]) {\n llmRequest.config.labels[ADK_AGENT_NAME_LABEL_KEY] = this.name;\n }\n\n // Calls the LLM.\n const llm = this.canonicalModel;\n // TODO - b/436079721: Add tracer.start_as_current_span('call_llm')\n if (invocationContext.runConfig?.supportCfc) {\n // TODO - b/425992518: Implement CFC call path\n // This is a hack, underneath it calls runLive. Which makes\n // runLive/run mixed.\n throw new Error('CFC is not yet supported in callLlmAsync');\n } else {\n invocationContext.incrementLlmCallCount();\n const responsesGenerator = llm.generateContentAsync(\n llmRequest,\n /* stream= */ invocationContext.runConfig?.streamingMode ===\n StreamingMode.SSE,\n );\n\n for await (const llmResponse of this.runAndHandleError(\n responsesGenerator, invocationContext, llmRequest,\n modelResponseEvent)) {\n // TODO - b/436079721: Add trace_call_llm\n\n // Runs after_model_callback if it exists.\n const alteredLlmResponse = await this.handleAfterModelCallback(\n invocationContext, llmResponse, modelResponseEvent);\n yield alteredLlmResponse ?? llmResponse;\n }\n }\n }\n\n private async handleBeforeModelCallback(\n invocationContext: InvocationContext,\n llmRequest: LlmRequest,\n modelResponseEvent: Event,\n ): Promise<LlmResponse | undefined> {\n // TODO - b/425992518: Clean up eventActions from CallbackContext here as\n // modelResponseEvent.actions is always empty.\n const callbackContext = new CallbackContext(\n { invocationContext, eventActions: modelResponseEvent.actions });\n\n // Plugin callbacks before canonical callbacks\n const beforeModelCallbackResponse =\n await invocationContext.pluginManager.runBeforeModelCallback(\n { callbackContext, llmRequest });\n if (beforeModelCallbackResponse) {\n return beforeModelCallbackResponse;\n }\n\n // If no override was returned from the plugins, run the canonical callbacks\n for (const callback of this.canonicalBeforeModelCallbacks) {\n const callbackResponse =\n await callback({ context: callbackContext, request: llmRequest });\n if (callbackResponse) {\n return callbackResponse;\n }\n }\n return undefined;\n }\n\n private async handleAfterModelCallback(\n invocationContext: InvocationContext,\n llmResponse: LlmResponse,\n modelResponseEvent: Event,\n ): Promise<LlmResponse | undefined> {\n const callbackContext = new CallbackContext(\n { invocationContext, eventActions: modelResponseEvent.actions });\n\n // Plugin callbacks before canonical callbacks\n const afterModelCallbackResponse =\n await invocationContext.pluginManager.runAfterModelCallback(\n { callbackContext, llmResponse });\n if (afterModelCallbackResponse) {\n return afterModelCallbackResponse;\n }\n\n // If no override was returned from the plugins, run the canonical callbacks\n for (const callback of this.canonicalAfterModelCallbacks) {\n const callbackResponse =\n await callback({ context: callbackContext, response: llmResponse });\n if (callbackResponse) {\n return callbackResponse;\n }\n }\n return undefined;\n }\n\n private async *\n runAndHandleError(\n responseGenerator: AsyncGenerator<LlmResponse, void, void>,\n invocationContext: InvocationContext,\n llmRequest: LlmRequest,\n modelResponseEvent: Event,\n ): AsyncGenerator<LlmResponse, void, void> {\n try {\n for await (const response of responseGenerator) {\n yield response;\n }\n } catch (modelError: unknown) {\n // Return an LlmResponse with error details.\n // Note: this will cause agent to work better if there's a loop.\n const callbackContext = new CallbackContext(\n { invocationContext, eventActions: modelResponseEvent.actions });\n\n // Wrapped LLM should throw Error-typed errors\n if (modelError instanceof Error) {\n // Try plugins to recover from the error\n const onModelErrorCallbackResponse =\n await invocationContext.pluginManager.runOnModelErrorCallback({\n callbackContext: callbackContext,\n llmRequest: llmRequest,\n error: modelError as Error\n });\n\n if (onModelErrorCallbackResponse) {\n yield onModelErrorCallbackResponse;\n } else {\n // If no plugins, just return the message.\n const errorResponse = JSON.parse(modelError.message) as\n { error: { code: number; message: string; } };\n\n yield {\n errorCode: String(errorResponse.error.code),\n errorMessage: errorResponse.error.message,\n };\n }\n } else {\n logger.error('Unknown error during response generation', modelError);\n throw modelError;\n }\n }\n }\n\n // --------------------------------------------------------------------------\n // #END LlmFlow Logic\n // --------------------------------------------------------------------------\n\n // TODO - b/425992518: omitted Py LlmAgent features.\n // - code_executor\n // - configurable agents by yaml config\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {InvocationContext} from '../agents/invocation_context.js';\n\nimport {CodeExecutionInput, CodeExecutionResult} from './code_execution_utils.js';\n\n/**\n * The parameters for executing code.\n * */\nexport interface ExecuteCodeParams {\n /** The invocation context of the code execution. */\n invocationContext: InvocationContext;\n /** The input of the code execution. */\n codeExecutionInput: CodeExecutionInput;\n}\n\n/**\n * The code executor allows the agent to execute code blocks from model\n * responses and incorporate the execution results into the final response.\n */\nexport abstract class BaseCodeExecutor {\n /**\n * If true, extract and process data files from the model request\n * and attach them to the code executor.\n *\n * Supported data file MimeTypes are [text/csv].\n * Default to false.\n */\n optimizeDataFile = false;\n\n /**\n * Whether the code executor is stateful. Default to false.\n */\n stateful = false;\n\n /**\n * The number of attempts to retry on consecutive code execution errors.\n * Default to 2.\n */\n errorRetryAttempts = 2;\n\n /**\n * The list of the enclosing delimiters to identify the code blocks.\n * For example, the delimiter('```python\\\\n', '\\\\n```') can be used to\n * identify code blocks with the following format::\n *\n * ```python\n * print(\"hello\")\n * ```\n */\n codeBlockDelimiters: Array<[string, string]> = [\n ['```tool_code\\n', '\\n```'],\n ['```python\\n', '\\n```'],\n ];\n\n /**\n * The delimiters to format the code execution result.\n */\n executionResultDelimiters: [string, string] = ['```tool_output\\n', '\\n```'];\n\n /**\n * Executes code and return the code execution result.\n *\n * @param params The parameters for executing code.\n * @return The result of the code execution.\n */\n abstract executeCode(params: ExecuteCodeParams): Promise<CodeExecutionResult>;\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nconst MODEL_NAME_PATTERN =\n '^projects/[^/]+/locations/[^/]+/publishers/[^/]+/models/(.+)$';\n\n/**\n * Extract the actual model name from either simple or path-based format.\n *\n * @param modelString Either a simple model name like \"gemini-2.5-pro\" or\n * a path-based model name like \"projects/.../models/gemini-2.0-flash-001\"\n * @return The extracted model name (e.g., \"gemini-2.5-pro\")\n */\nexport function extractModelName(modelString: string): string {\n const match = modelString.match(MODEL_NAME_PATTERN);\n if (match) {\n return match[1];\n }\n\n // If it's not a path-based model, return as-is (simple model name)\n return modelString;\n}\n\n/**\n * Check if the model is a Gemini model using regex patterns.\n *\n * @param modelString Either a simple model name or path - based model name\n * @return true if it's a Gemini model, false otherwise.\n */\nexport function isGeminiModel(modelString: string): boolean {\n const modelName = extractModelName(modelString);\n\n return modelName.startsWith('gemini-');\n}\n\n/**\n * Check if the model is a Gemini 1.x model using regex patterns.\n *\n * @param modelString Either a simple model name or path - based model name\n * @return true if it's a Gemini 1.x model, false otherwise.\n */\nexport function isGemini1Model(modelString: string): boolean {\n const modelName = extractModelName(modelString);\n\n return modelName.startsWith('gemini-1');\n}\n\n/**\n * Check if the model is a Gemini 2.x model using regex patterns.\n *\n * @param modelString Either a simple model name or path - based model name\n * @return true if it's a Gemini 2.x model, false otherwise.\n */\nexport function isGemini2Model(modelString: string): boolean {\n const modelName = extractModelName(modelString);\n\n return modelName.startsWith('gemini-2');\n}\n\n/**\n * Check if the model is a Gemini 3.x model using regex patterns.\n *\n * @param modelString Either a simple model name or path - based model name\n * @return true if it's a Gemini 3.x model, false otherwise.\n */\nexport function isGemini3Model(modelString: string): boolean {\n const modelName = extractModelName(modelString);\n\n return modelName.startsWith('gemini-3');\n}\n\n/**\n * Check if the model is a Gemini 3.x preview model.\n * Preview models require special endpoint handling (aiplatform.googleapis.com).\n *\n * @param modelString Either a simple model name or path - based model name\n * @return true if it's a Gemini 3.x preview model, false otherwise.\n */\nexport function isGemini3PreviewModel(modelString: string): boolean {\n const modelName = extractModelName(modelString);\n\n return modelName.startsWith('gemini-3') && modelName.includes('preview');\n}", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {GenerateContentConfig} from '@google/genai'\n\nimport {InvocationContext} from '../agents/invocation_context.js';\nimport {LlmRequest} from '../models/llm_request.js';\nimport {isGemini2Model} from '../utils/model_name.js';\n\nimport {BaseCodeExecutor, ExecuteCodeParams} from './base_code_executor.js';\nimport {CodeExecutionInput, CodeExecutionResult} from './code_execution_utils.js';\n\n/**\n * A code executor that uses the Model's built-in code executor.\n *\n * Currently only supports Gemini 2.0+ models, but will be expanded to\n * other models.\n */\nexport class BuiltInCodeExecutor extends BaseCodeExecutor {\n executeCode(params: ExecuteCodeParams): Promise<CodeExecutionResult> {\n return Promise.resolve({\n stdout: '',\n stderr: '',\n outputFiles: [],\n });\n }\n\n processLlmRequest(llmRequest: LlmRequest) {\n if (llmRequest.model && isGemini2Model(llmRequest.model)) {\n llmRequest.config = llmRequest.config || {};\n llmRequest.config.tools = llmRequest.config.tools || [];\n llmRequest.config.tools.push({codeExecution: {}});\n\n return;\n }\n\n throw new Error(`Gemini code execution tool is not supported for model ${\n llmRequest.model}`);\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {Content, Language, Outcome, Part} from '@google/genai';\n\nimport {deepClone} from '../utils/deep_clone.js';\nimport {base64Encode, isBase64Encoded} from '../utils/env_aware_utils.js';\n\n/**\n * A structure that contains a file name and its content\n */\nexport interface File {\n /**\n * The name of the file with file extension(e.g., ' file.csv')\n * */\n name: string;\n\n /**\n * The base64 - encoded bytes of the file content.\n * */\n content: string;\n\n /**\n * The mime type of the file (e.g., ' image / png')\n * */\n mimeType: string;\n}\n\n/**\n * A structure that contains the input of code execution.\n * */\nexport interface CodeExecutionInput {\n /**\n * The code to execute.\n * */\n code: string;\n\n /**\n * The input files available to the code.\n * */\n inputFiles: File[];\n\n /**\n * The execution ID for the stateful code execution.\n * */\n executionId?: string;\n}\n\n/**\n * A structure that contains the result of code execution.\n * */\nexport interface CodeExecutionResult {\n /**\n * The standard output of the code execution.\n * */\n stdout: string;\n\n /**\n * The standard error of the code execution.\n * */\n stderr: string;\n\n /**\n * The output files from the code execution.\n * */\n outputFiles: File[];\n}\n\n/**\n * Gets the file content as a base64-encoded bytes.\n *\n * @param data The file content bytes.\n * @return The file content as a base64-encoded bytes.\n */\nexport function getEncodedFileContent(data: string): string {\n return isBase64Encoded(data) ? data : base64Encode(data);\n}\n\n// Type to be used for regex matching of code blocks.\ninterface CodeGroupMatch {\n groups?: {prefix?: string; codeStr?: string;};\n index?: number;\n length?: number;\n}\n\n/**\n * Extracts the first code block from the content and truncate everything after\n * it.\n *\n * @param content The mutable content to extract the code from.\n * @param codeBlockDelimiters The list of the enclosing delimiters to identify\n * the code blocks.\n * @return The first code block if found, otherwise None.\n */\nexport function extractCodeAndTruncateContent(\n content: Content,\n codeBlockDelimiters: Array<[string, string]>,\n ): string {\n if (!content.parts?.length) {\n return '';\n }\n\n // Extract the code from the executable code parts if there're no associated\n // code execution result parts.\n for (let i = 0; i < content.parts.length; i++) {\n const part = content.parts[i];\n if (part.executableCode &&\n (i === content.parts.length - 1 ||\n !content.parts[i + 1].codeExecutionResult)) {\n content.parts = content.parts.slice(0, i + 1);\n return part.executableCode.code!;\n }\n }\n\n // Extract the code from the text parts.\n const textParts = content.parts.filter((part) => part.text);\n if (!textParts.length) {\n return '';\n }\n\n const firstTextPart = deepClone(textParts[0])!;\n const responseText = textParts.map((part) => part.text!).join('\\n');\n\n // Find the first code block.\n const leadingDelimiterPattern =\n codeBlockDelimiters.map((d) => d[0]).join('|');\n const trailingDelimiterPattern =\n codeBlockDelimiters.map((d) => d[1]).join('|');\n const match =\n new RegExp(\n `?<prefix>.*?)(${leadingDelimiterPattern})(?<codeStr>.*?)(${\n trailingDelimiterPattern})(?<suffix>.*?)$`,\n 's').exec(responseText) as unknown as CodeGroupMatch |\n null;\n\n const {prefix, codeStr} = match?.groups || {};\n\n if (!codeStr) {\n return '';\n }\n\n content.parts = [];\n\n if (prefix) {\n firstTextPart.text = prefix;\n content.parts.push(firstTextPart);\n }\n content.parts.push(buildExecutableCodePart(codeStr));\n\n return codeStr;\n}\n\n/**\n * Builds an executable code part with code string.\n *\n * @param code The code string.\n * @return The constructed executable code part.\n */\nexport function buildExecutableCodePart(code: string): Part {\n return {\n text: code,\n executableCode: {\n code,\n language: Language.PYTHON,\n },\n };\n}\n\n/**\n * Builds the code execution result part from the code execution result.\n *\n * @param codeExecutionResult The code execution result.\n * @return The code execution result part.\n */\nexport function buildCodeExecutionResultPart(\n codeExecutionResult: CodeExecutionResult,\n ): Part {\n if (codeExecutionResult.stderr) {\n return {\n text: codeExecutionResult.stderr,\n codeExecutionResult: {\n outcome: Outcome.OUTCOME_FAILED,\n },\n };\n }\n\n const finalResult = [];\n if (codeExecutionResult.stdout || !codeExecutionResult.outputFiles) {\n finalResult.push(`Code execution result:\\n${codeExecutionResult.stdout}\\n`);\n }\n if (codeExecutionResult.outputFiles) {\n finalResult.push(\n `Saved artifacts:\\n` +\n codeExecutionResult.outputFiles.map(f => f.name).join(', '));\n }\n\n return {\n text: finalResult.join('\\n\\n'),\n codeExecutionResult: {\n outcome: Outcome.OUTCOME_OK,\n },\n };\n}\n\n/**\n * Converts the code execution parts to text parts in a Content.\n *\n * @param content The mutable content to convert the code execution parts to\n * text parts.\n * @param codeBlockDelimiter The delimiter to format the code block.\n * @param executionResultDelimiters The delimiter to format the code execution\n * result.\n * @return The converted content.\n */\nexport function convertCodeExecutionParts(\n content: Content,\n codeBlockDelimiter: [string, string],\n executionResultDelimiters: [string, string],\n) {\n if (!content.parts?.length) {\n return;\n }\n\n const lastPart = content.parts[content.parts.length - 1];\n\n if (lastPart.executableCode) {\n content.parts[content.parts.length - 1] = {\n text: codeBlockDelimiter[0] + lastPart.executableCode.code +\n codeBlockDelimiter[1],\n };\n } else if (content.parts.length == 1 && lastPart.codeExecutionResult) {\n content.parts[content.parts.length - 1] = {\n text: executionResultDelimiters[0] + lastPart.codeExecutionResult.output +\n executionResultDelimiters[1],\n };\n content.role = 'user'\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {Event} from '../events/event.js';\n\n// TODO - b/425992518: replace with lodash deep clone.\nexport function deepClone<T>(obj: T): T {\n if (obj === undefined) {\n return undefined as T;\n }\n\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {State} from '../sessions/state.js';\nimport {deepClone} from '../utils/deep_clone.js';\n\nimport {File} from './code_execution_utils.js';\n\nconst CONTEXT_KEY = '_code_execution_context';\nconst SESSION_ID_KEY = 'execution_session_id';\nconst PROCESSED_FILE_NAMES_KEY = 'processed_input_files';\nconst INPUT_FILE_KEY = '_code_executor_input_files';\nconst ERROR_COUNT_KEY = '_code_executor_error_counts';\nconst CODE_EXECUTION_RESULTS_KEY = '_code_execution_results';\n\ninterface CodeExecutionResult {\n code: string;\n resultStdout: string;\n resultStderr: string;\n timestamp: number;\n}\n\n/**\n * The parameters for updating the code execution result.\n * */\nexport interface UpdateCodeExecutionResultParams {\n invocationId: string;\n code: string;\n resultStdout: string;\n resultStderr: string;\n}\n\n/**\n * The persistent context used to configure the code executor.\n */\nexport class CodeExecutorContext {\n private readonly context:\n {[SESSION_ID_KEY]?: string;[PROCESSED_FILE_NAMES_KEY]?: string[];};\n\n constructor(private readonly sessionState: State) {\n this.context = sessionState.get(CONTEXT_KEY) ?? {};\n this.sessionState = sessionState;\n }\n\n /**\n * Gets the state delta to update in the persistent session state.\n * @return The state delta to update in the persistent session state.\n */\n getStateDelta(): Record<string, unknown> {\n return {\n [CONTEXT_KEY]: deepClone(this.context),\n };\n }\n\n /**\n * Gets the execution ID for the code executor.\n * @return The execution ID for the code executor.\n */\n getExecutionId(): string|undefined {\n if (!(SESSION_ID_KEY in this.context)) {\n return undefined;\n }\n\n return this.context[SESSION_ID_KEY];\n }\n\n /**\n * Sets the execution ID for the code executor.\n * @param executionId The execution ID to set.\n */\n setExecutionId(executionId: string) {\n this.context[SESSION_ID_KEY] = executionId;\n }\n\n /**\n * Gets the processed file names from the session state.\n * @return A list of processed file names in the code executor context.\n */\n getProcessedFileNames(): string[] {\n if (!(PROCESSED_FILE_NAMES_KEY in this.context)) {\n return [];\n }\n\n return this.context[PROCESSED_FILE_NAMES_KEY]!;\n }\n\n /**\n * Adds the processed file names to the session state.\n * @param fileNames The file names to add to the session state.\n */\n addProcessedFileNames(fileNames: string[]) {\n if (!(PROCESSED_FILE_NAMES_KEY in this.context)) {\n this.context[PROCESSED_FILE_NAMES_KEY] = [];\n }\n\n this.context[PROCESSED_FILE_NAMES_KEY]!.push(...fileNames);\n }\n\n /**\n * Gets the input files from the session state.\n * @return A list of input files in the code executor context.\n */\n getInputFiles(): File[] {\n if (!(INPUT_FILE_KEY in this.sessionState)) {\n return [];\n }\n\n return this.sessionState.get(INPUT_FILE_KEY) as File[];\n }\n\n /**\n * Adds the input files to the session state.\n * @param inputFiles The input files to add to the session state.\n */\n addInputFiles(inputFiles: File[]) {\n if (!(INPUT_FILE_KEY in this.sessionState)) {\n this.sessionState.set(INPUT_FILE_KEY, []);\n }\n\n (this.sessionState.get(INPUT_FILE_KEY) as File[]).push(...inputFiles);\n }\n\n clearInputFiles() {\n if (INPUT_FILE_KEY in this.sessionState) {\n this.sessionState.set(INPUT_FILE_KEY, []);\n }\n\n if (PROCESSED_FILE_NAMES_KEY in this.context) {\n this.context[PROCESSED_FILE_NAMES_KEY] = [];\n }\n }\n\n /**\n * Gets the error count from the session state.\n * @param invocationId The invocation ID to get the error count for.\n * @return The error count for the given invocation ID.\n */\n getErrorCount(invocationId: string): number {\n if (!(ERROR_COUNT_KEY in this.sessionState)) {\n return 0;\n }\n\n return (this.sessionState.get(ERROR_COUNT_KEY) as\n Record<string, number>)[invocationId] as number ||\n 0;\n }\n\n /**\n * Increments the error count from the session state.\n * @param invocationId The invocation ID to increment the error count for.\n */\n incrementErrorCount(invocationId: string) {\n if (!(ERROR_COUNT_KEY in this.sessionState)) {\n this.sessionState.set(ERROR_COUNT_KEY, {});\n }\n\n (this.sessionState.get(ERROR_COUNT_KEY) as\n Record<string, number>)[invocationId] =\n (this.getErrorCount(invocationId) + 1);\n }\n\n /**\n * Resets the error count from the session state.\n * @param invocationId The invocation ID to reset the error count for.\n */\n resetErrorCount(invocationId: string) {\n if (!(ERROR_COUNT_KEY in this.sessionState)) {\n return;\n }\n\n const errorCounts =\n this.sessionState.get(ERROR_COUNT_KEY) as Record<string, number>;\n\n if (invocationId in errorCounts) {\n delete errorCounts[invocationId];\n }\n }\n\n /**\n * Updates the code execution result.\n * @param invocationId The invocation ID to update the code execution result\n * for.\n * @param code The code to execute.\n * @param resultStdout The standard output of the code execution.\n * @param resultStderr The standard error of the code execution.\n */\n updateCodeExecutionResult({\n invocationId,\n code,\n resultStdout,\n resultStderr,\n }: UpdateCodeExecutionResultParams) {\n if (!(CODE_EXECUTION_RESULTS_KEY in this.sessionState)) {\n this.sessionState.set(CODE_EXECUTION_RESULTS_KEY, {});\n }\n\n const codeExecutionResults =\n this.sessionState.get(CODE_EXECUTION_RESULTS_KEY) as\n Record<string, CodeExecutionResult[]>;\n\n if (!(invocationId in codeExecutionResults)) {\n codeExecutionResults[invocationId] = [];\n }\n\n codeExecutionResults[invocationId].push({\n code,\n resultStdout,\n resultStderr,\n timestamp: Date.now(),\n });\n }\n\n /**\n * Gets the code executor context from the session state.\n * @param invocationId The session state to get the code executor context\n * from.\n * @return The code execution context for the given invocation ID.\n */\n getCodeExecutionContext(invocationId: string): Record<string, unknown> {\n return this.sessionState.get(CONTEXT_KEY) || {};\n }\n}", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n// version: major.minor.patch\nexport const version = '0.2.4';\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {version} from '../version.js';\n\nimport {isBrowser} from './env_aware_utils.js';\n\nconst ADK_LABEL = 'google-adk';\nconst LANGUAGE_LABEL = 'gl-typescript';\nconst AGENT_ENGINE_TELEMETRY_TAG = 'remote_reasoning_engine';\nconst AGENT_ENGINE_TELEMETRY_ENV_VARIABLE_NAME = 'GOOGLE_CLOUD_AGENT_ENGINE_ID';\n\n// TODO: b/468053794 - Configurable client labels in AsyncLocalStorage and/or\n// browser equivalent\n\nfunction _getDefaultLabels(): string[] {\n let frameworkLabel = `${ADK_LABEL}/${version}`;\n\n if (!isBrowser() && process.env[AGENT_ENGINE_TELEMETRY_ENV_VARIABLE_NAME]) {\n frameworkLabel = `${frameworkLabel}+${AGENT_ENGINE_TELEMETRY_TAG}`;\n }\n\n // TODO: b/468051563 - Consider extracting browser name and version from\n // userAgent string\n const languageLabel = `${LANGUAGE_LABEL}/${\n isBrowser() ? window.navigator.userAgent : process.version}`;\n return [frameworkLabel, languageLabel];\n}\n\n/**\n * Returns the current list of client labels that can be added to HTTP Headers.\n */\nexport function getClientLabels(): string[] {\n const labels = _getDefaultLabels();\n // TODO: b/468053794 - Configurable client labels in AsyncLocalStorage and/or\n // browser equivalent\n return labels;\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {getClientLabels} from '../utils/client_labels.js';\n\nimport {BaseLlmConnection} from './base_llm_connection.js';\nimport {LlmRequest} from './llm_request.js';\nimport {LlmResponse} from './llm_response.js';\n\nconst BASE_MODEL_SYMBOL = Symbol('baseModel');\n\nexport function isBaseLlm(obj: unknown): obj is BaseLlm {\n return typeof obj === 'object' && obj !== null && BASE_MODEL_SYMBOL in obj &&\n obj[BASE_MODEL_SYMBOL] === true;\n}\n\n/**\n * The BaseLLM class.\n */\nexport abstract class BaseLlm {\n readonly[BASE_MODEL_SYMBOL] = true;\n\n readonly model: string;\n\n /**\n * Creates an instance of BaseLLM.\n * @param params The parameters for creating a BaseLlm instance.\n * @param params.model The name of the LLM, e.g. gemini-1.5-flash or\n * gemini-1.5-flash-001.\n */\n constructor({model}: {model: string}) {\n this.model = model;\n }\n\n /**\n * List of supported models in regex for LlmRegistry.\n */\n static readonly supportedModels: Array<string|RegExp> = [];\n\n /**\n * Generates one content from the given contents and tools.\n *\n * @param llmRequest LlmRequest, the request to send to the LLM.\n * @param stream whether to do streaming call.\n * For non-streaming call, it will only yield one Content.\n * @return A generator of LlmResponse.\n */\n abstract generateContentAsync(llmRequest: LlmRequest, stream?: boolean):\n AsyncGenerator<LlmResponse, void>;\n\n /**\n * Creates a live connection to the LLM.\n *\n * @param llmRequest LlmRequest, the request to send to the LLM.\n * @return A live connection to the LLM.\n */\n abstract connect(llmRequest: LlmRequest): Promise<BaseLlmConnection>;\n\n protected get trackingHeaders(): Record<string, string> {\n const labels = getClientLabels();\n const headerValue = labels.join(' ');\n return {\n 'x-goog-api-client': headerValue,\n 'user-agent': headerValue,\n };\n }\n\n /**\n * Appends a user content, so that model can continue to output.\n *\n * @param llmRequest LlmRequest, the request to send to the LLM.\n */\n maybeAppendUserContent(llmRequest: LlmRequest): void {\n if (llmRequest.contents.length === 0) {\n llmRequest.contents.push({\n role: 'user',\n parts: [\n {text: 'Handle the requests as specified in the System Instruction.'}\n ],\n });\n }\n\n if (llmRequest.contents[llmRequest.contents.length - 1]?.role !== 'user') {\n llmRequest.contents.push({\n role: 'user',\n parts: [{\n text:\n 'Continue processing previous requests as instructed. Exit or provide a summary if no more outputs are needed.'\n }],\n });\n }\n }\n}", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Content, FunctionDeclaration, GenerateContentConfig, LiveConnectConfig, SchemaUnion} from '@google/genai';\n\nimport {BaseTool} from '../tools/base_tool.js';\n\n/**\n * LLM request class that allows passing in tools, output schema and system\n * instructions to the model.\n */\nexport interface LlmRequest {\n /**\n * The model name.\n */\n model?: string;\n\n /**\n * The contents to send to the model.\n */\n contents: Content[];\n\n /**\n * Additional config for the generate content request.\n * Tools in generateContentConfig should not be set directly; use appendTools.\n */\n config?: GenerateContentConfig;\n\n liveConnectConfig: LiveConnectConfig;\n\n /**\n * The tools dictionary. Excluded from JSON serialization.\n */\n toolsDict: {[key: string]: BaseTool};\n}\n\n/**\n * Appends instructions to the system instruction.\n * @param instructions The instructions to append.\n */\nexport function appendInstructions(\n llmRequest: LlmRequest,\n instructions: string[],\n ): void {\n if (!llmRequest.config) {\n llmRequest.config = {};\n }\n const newInstructions = instructions.join('\\n\\n');\n if (llmRequest.config.systemInstruction) {\n llmRequest.config.systemInstruction += '\\n\\n' + newInstructions;\n } else {\n llmRequest.config.systemInstruction = newInstructions;\n }\n}\n\n /**\n * Appends tools to the request.\n * @param tools The tools to append.\n */\nexport function appendTools(\n llmRequest: LlmRequest,\n tools: BaseTool[],\n ): void {\n if (!tools?.length) {\n return;\n }\n\n const functionDeclarations: FunctionDeclaration[] = [];\n for (const tool of tools) {\n const declaration = tool._getDeclaration();\n if (declaration) {\n functionDeclarations.push(declaration);\n llmRequest.toolsDict[tool.name] = tool;\n }\n }\n\n if (functionDeclarations.length) {\n if (!llmRequest.config) {\n llmRequest.config = {};\n }\n if (!llmRequest.config.tools) {\n llmRequest.config.tools = [];\n }\n llmRequest.config.tools.push({functionDeclarations});\n }\n}\n\n /**\n * Sets the output schema for the request.\n *\n * @param schema The JSON Schema object to set as the output schema.\n */\nexport function setOutputSchema(\n llmRequest: LlmRequest,\n schema: SchemaUnion,\n ): void {\n if (!llmRequest.config) {\n llmRequest.config = {};\n }\n llmRequest.config.responseSchema = schema;\n llmRequest.config.responseMimeType = 'application/json';\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Blob, createPartFromText, FileData, FinishReason, GenerateContentResponse, GoogleGenAI, Part} from '@google/genai';\n\nimport {isBrowser} from '../utils/env_aware_utils.js';\nimport {logger} from '../utils/logger.js';\nimport {isGemini3PreviewModel} from '../utils/model_name.js';\nimport {GoogleLLMVariant} from '../utils/variant_utils.js';\nimport {version} from '../version.js';\n\nimport {BaseLlm} from './base_llm.js';\nimport {BaseLlmConnection} from './base_llm_connection.js';\nimport {GeminiLlmConnection} from './gemini_llm_connection.js';\nimport {LlmRequest} from './llm_request.js';\nimport {createLlmResponse, LlmResponse} from './llm_response.js';\n\nconst AGENT_ENGINE_TELEMETRY_TAG = 'remote_reasoning_engine';\nconst AGENT_ENGINE_TELEMETRY_ENV_VARIABLE_NAME = 'GOOGLE_CLOUD_AGENT_ENGINE_ID';\n\n/**\n * Default API endpoint for Gemini 3 preview models.\n * Gemini 3 preview models require the aiplatform.googleapis.com endpoint with\n * the publishers/google path prefix.\n *\n * The SDK constructs URLs like: ${baseUrl}/models/${model}:generateContent\n * But Gemini 3 preview needs: https://aiplatform.googleapis.com/v1/publishers/google/models/${model}:generateContent\n *\n * So we set the baseUrl to include the path prefix up to (but not including) /models/\n */\nconst GEMINI3_PREVIEW_API_ENDPOINT = 'https://aiplatform.googleapis.com/v1/publishers/google';\n\n/**\n * The parameters for creating a Gemini instance.\n */\nexport interface GeminiParams {\n /**\n * The name of the model to use. Defaults to 'gemini-2.5-flash'.\n */\n model?: string;\n /**\n * The API key to use for the Gemini API. If not provided, it will look for\n * the GOOGLE_GENAI_API_KEY or GEMINI_API_KEY environment variable.\n */\n apiKey?: string;\n /**\n * Whether to use Vertex AI. If true, `project`, `location`\n * should be provided.\n */\n vertexai?: boolean;\n /**\n * The Vertex AI project ID. Required if `vertexai` is true.\n */\n project?: string;\n /**\n * The Vertex AI location. Required if `vertexai` is true.\n */\n location?: string;\n /**\n * Headers to merge with internally crafted headers.\n */\n headers?: Record<string, string>;\n /**\n * Custom API endpoint URL. If not provided, uses the default endpoint\n * based on the model type:\n * - Gemini 3 preview models: aiplatform.googleapis.com\n * - Other models: uses SDK default (generativelanguage.googleapis.com)\n *\n * Can also be set via GEMINI_API_ENDPOINT environment variable.\n */\n apiEndpoint?: string;\n}\n\n/**\n * Integration for Gemini models.\n */\nexport class Gemini extends BaseLlm {\n private readonly apiKey?: string;\n private readonly vertexai: boolean;\n private readonly project?: string;\n private readonly location?: string;\n private readonly headers?: Record<string, string>;\n private readonly apiEndpoint?: string;\n private readonly isGemini3Preview: boolean;\n\n /**\n * @param params The parameters for creating a Gemini instance.\n */\n constructor({\n model,\n apiKey,\n vertexai,\n project,\n location,\n headers,\n apiEndpoint,\n }: GeminiParams) {\n if (!model) {\n model = 'gemini-2.5-flash';\n }\n\n super({model});\n\n this.project = project;\n this.location = location;\n this.apiKey = apiKey;\n this.headers = headers;\n this.isGemini3Preview = isGemini3PreviewModel(model);\n\n const canReadEnv = typeof process === 'object';\n\n // Handle API endpoint configuration\n this.apiEndpoint = apiEndpoint;\n if (!this.apiEndpoint && canReadEnv) {\n this.apiEndpoint = process.env['GEMINI_API_ENDPOINT'];\n }\n // For Gemini 3 preview models, use the aiplatform.googleapis.com endpoint by default\n if (!this.apiEndpoint && this.isGemini3Preview) {\n this.apiEndpoint = GEMINI3_PREVIEW_API_ENDPOINT;\n logger.info(`Using Gemini 3 preview endpoint: ${this.apiEndpoint}`);\n }\n\n // Determine vertexai mode from constructor or environment\n let useVertexAI = !!vertexai;\n if (!useVertexAI && canReadEnv) {\n const vertexAIfromEnv = process.env['GOOGLE_GENAI_USE_VERTEXAI'];\n if (vertexAIfromEnv) {\n useVertexAI =\n vertexAIfromEnv.toLowerCase() === 'true' || vertexAIfromEnv === '1';\n }\n }\n\n // For Gemini 3 preview models, force API key mode instead of Vertex AI.\n // This is because Gemini 3 preview requires a special endpoint path\n // (publishers/google/models/) that is not compatible with standard Vertex AI\n // SDK configuration. The custom apiEndpoint is only applied in non-Vertex AI mode.\n if (this.isGemini3Preview && useVertexAI) {\n // Check if API key is available before switching modes\n const availableApiKey = apiKey ||\n (canReadEnv ? (process.env['GOOGLE_GENAI_API_KEY'] || process.env['GEMINI_API_KEY']) : undefined);\n if (availableApiKey) {\n logger.info('Gemini 3 preview detected with Vertex AI mode. Switching to API key mode for correct endpoint handling.');\n useVertexAI = false;\n this.apiKey = availableApiKey;\n } else {\n logger.warn('Gemini 3 preview requires API key authentication for correct endpoint handling. ' +\n 'Set GEMINI_API_KEY or GOOGLE_GENAI_API_KEY environment variable for best compatibility.');\n }\n }\n\n this.vertexai = useVertexAI;\n\n if (this.vertexai) {\n if (canReadEnv && !this.project) {\n this.project = process.env['GOOGLE_CLOUD_PROJECT'];\n }\n if (canReadEnv && !this.location) {\n this.location = process.env['GOOGLE_CLOUD_LOCATION'];\n }\n if (!this.project) {\n throw new Error(\n 'VertexAI project must be provided via constructor or GOOGLE_CLOUD_PROJECT environment variable.');\n }\n if (!this.location) {\n throw new Error(\n 'VertexAI location must be provided via constructor or GOOGLE_CLOUD_LOCATION environment variable.');\n }\n } else {\n if (!this.apiKey && canReadEnv) {\n this.apiKey = process.env['GOOGLE_GENAI_API_KEY'] ||\n process.env['GEMINI_API_KEY'];\n }\n if (!this.apiKey) {\n throw new Error(\n 'API key must be provided via constructor or GOOGLE_GENAI_API_KEY or GEMINI_API_KEY environment variable.');\n }\n }\n }\n\n /**\n * A list of model name patterns that are supported by this LLM.\n *\n * @returns A list of supported models.\n */\n static override readonly supportedModels: Array<string|RegExp> = [\n /gemini-.*/,\n // fine-tuned vertex endpoint pattern\n /projects\\/.+\\/locations\\/.+\\/endpoints\\/.+/,\n // vertex gemini long name\n /projects\\/.+\\/locations\\/.+\\/publishers\\/google\\/models\\/gemini.+/,\n ];\n\n private _apiClient?: GoogleGenAI;\n private _apiBackend?: GoogleLLMVariant;\n private _trackingHeaders?: Record<string, string>;\n private _liveApiVersion?: string;\n private _liveApiClient?: GoogleGenAI;\n\n /**\n * Sends a request to the Gemini model.\n *\n * @param llmRequest LlmRequest, the request to send to the Gemini model.\n * @param stream bool = false, whether to do streaming call.\n * @yields LlmResponse: The model response.\n */\n override async *\n generateContentAsync(\n llmRequest: LlmRequest,\n stream = false,\n ): AsyncGenerator<LlmResponse, void> {\n this.preprocessRequest(llmRequest);\n this.maybeAppendUserContent(llmRequest);\n logger.info(\n `Sending out request, model: ${llmRequest.model}, backend: ${\n this.apiBackend}, stream: ${stream}`,\n );\n\n if (llmRequest.config?.httpOptions) {\n llmRequest.config.httpOptions.headers = {\n ...llmRequest.config.httpOptions.headers,\n ...this.trackingHeaders,\n };\n }\n\n if (stream) {\n const streamResult = await this.apiClient.models.generateContentStream({\n model: llmRequest.model ?? this.model,\n contents: llmRequest.contents,\n config: llmRequest.config,\n });\n let thoughtText = '';\n let text = '';\n let usageMetadata;\n let lastResponse: GenerateContentResponse|undefined;\n\n // TODO - b/425992518: verify the type of streaming response is correct.\n for await (const response of streamResult) {\n lastResponse = response;\n const llmResponse = createLlmResponse(response);\n usageMetadata = llmResponse.usageMetadata;\n const firstPart = llmResponse.content?.parts?.[0];\n // Accumulates the text and thought text from the first part.\n if (firstPart?.text) {\n if ('thought' in firstPart && firstPart.thought) {\n thoughtText += firstPart.text;\n } else {\n text += firstPart.text;\n }\n llmResponse.partial = true;\n } else if (\n (thoughtText || text) && (!firstPart || !firstPart.inlineData)) {\n // Flushes the data if there's no more text.\n const parts: Part[] = [];\n if (thoughtText) {\n parts.push({text: thoughtText, thought: true});\n }\n if (text) {\n parts.push(createPartFromText(text));\n }\n yield {\n content: {\n role: 'model',\n parts,\n },\n usageMetadata: llmResponse.usageMetadata,\n };\n thoughtText = '';\n text = '';\n }\n yield llmResponse;\n }\n if ((text || thoughtText) &&\n lastResponse?.candidates?.[0]?.finishReason === FinishReason.STOP) {\n const parts: Part[] = [];\n if (thoughtText) {\n parts.push({text: thoughtText, thought: true} as Part);\n }\n if (text) {\n parts.push({text: text});\n }\n yield {\n content: {\n role: 'model',\n parts,\n },\n usageMetadata,\n };\n }\n } else {\n const response = await this.apiClient.models.generateContent({\n model: llmRequest.model ?? this.model,\n contents: llmRequest.contents,\n config: llmRequest.config,\n });\n yield createLlmResponse(response);\n }\n }\n\n get apiClient(): GoogleGenAI {\n if (this._apiClient) {\n return this._apiClient;\n }\n\n const combinedHeaders = {\n ...this.trackingHeaders,\n ...this.headers,\n }\n\n if (this.vertexai) {\n this._apiClient = new GoogleGenAI({\n vertexai: this.vertexai,\n project: this.project,\n location: this.location,\n httpOptions: {headers: combinedHeaders},\n });\n }\n else {\n // Build httpOptions with optional baseUrl for Gemini 3 preview models\n const httpOptions: Record<string, unknown> = {headers: combinedHeaders};\n if (this.apiEndpoint) {\n httpOptions.baseUrl = this.apiEndpoint;\n logger.debug(`Using custom API endpoint: ${this.apiEndpoint}`);\n\n // For Gemini 3 preview models on aiplatform.googleapis.com, we need to:\n // 1. Use the baseUrl that includes /v1/publishers/google path\n // 2. Prevent the SDK from adding its own API version prefix\n // The baseUrl already contains the version, so we don't need apiVersion\n if (this.isGemini3Preview) {\n // Set empty apiVersion to prevent SDK from adding version prefix\n // since the version is already included in the baseUrl\n httpOptions.apiVersion = '';\n logger.info(`Gemini 3 preview mode: using direct API path without version prefix`);\n }\n }\n\n // Explicitly set vertexai: false to prevent SDK from auto-detecting\n // Vertex AI mode based on environment (e.g., GCP credentials on Cloud Run).\n // This ensures the API key authentication and custom baseUrl are used.\n this._apiClient = new GoogleGenAI({\n apiKey: this.apiKey,\n vertexai: false,\n httpOptions,\n });\n }\n return this._apiClient;\n }\n\n get apiBackend(): GoogleLLMVariant {\n if (!this._apiBackend) {\n this._apiBackend = this.apiClient.vertexai ? GoogleLLMVariant.VERTEX_AI :\n GoogleLLMVariant.GEMINI_API;\n }\n return this._apiBackend;\n }\n\n get liveApiVersion(): string {\n if (!this._liveApiVersion) {\n this._liveApiVersion = this.apiBackend === GoogleLLMVariant.VERTEX_AI ?\n 'v1beta1' :\n 'v1alpha';\n }\n return this._liveApiVersion;\n }\n\n get liveApiClient(): GoogleGenAI {\n if (!this._liveApiClient) {\n const httpOptions: Record<string, unknown> = {\n headers: this.trackingHeaders,\n apiVersion: this.liveApiVersion,\n };\n if (this.apiEndpoint) {\n httpOptions.baseUrl = this.apiEndpoint;\n\n // For Gemini 3 preview models, the baseUrl already contains the version\n // so we don't need the SDK to add another version prefix\n if (this.isGemini3Preview) {\n httpOptions.apiVersion = '';\n }\n }\n\n this._liveApiClient = new GoogleGenAI({\n apiKey: this.apiKey,\n httpOptions,\n });\n }\n return this._liveApiClient;\n }\n\n /**\n * Connects to the Gemini model and returns an llm connection.\n *\n * @param llmRequest LlmRequest, the request to send to the Gemini model.\n * @returns BaseLlmConnection, the connection to the Gemini model.\n */\n override async connect(llmRequest: LlmRequest): Promise<BaseLlmConnection> {\n // add tracking headers to custom headers and set api_version given\n // the customized http options will override the one set in the api client\n // constructor\n if (llmRequest.liveConnectConfig?.httpOptions) {\n if (!llmRequest.liveConnectConfig.httpOptions.headers) {\n llmRequest.liveConnectConfig.httpOptions.headers = {};\n }\n Object.assign(\n llmRequest.liveConnectConfig.httpOptions.headers,\n this.trackingHeaders,\n );\n // For Gemini 3 preview, the baseUrl already contains the version\n // so we use empty apiVersion to prevent double version prefix\n llmRequest.liveConnectConfig.httpOptions.apiVersion =\n this.isGemini3Preview ? '' : this.liveApiVersion;\n }\n\n if (llmRequest.config?.systemInstruction) {\n llmRequest.liveConnectConfig.systemInstruction = {\n role: 'system',\n // TODO - b/425992518: validate type casting works well.\n parts:\n [createPartFromText(llmRequest.config.systemInstruction as string)],\n };\n }\n\n llmRequest.liveConnectConfig.tools = llmRequest.config?.tools;\n\n const liveSession = await this.liveApiClient.live.connect({\n model: llmRequest.model ?? this.model,\n config: llmRequest.liveConnectConfig,\n callbacks: {\n // TODO - b/425992518: GenAI SDK inconsistent API, missing methods.\n onmessage: () => {},\n },\n });\n return new GeminiLlmConnection(liveSession);\n }\n\n private preprocessRequest(llmRequest: LlmRequest): void {\n if (this.apiBackend === GoogleLLMVariant.GEMINI_API) {\n if (llmRequest.config) {\n // Using API key from Google AI Studio to call model doesn't support\n // labels.\n (llmRequest.config as any).labels = undefined;\n }\n if (llmRequest.contents) {\n for (const content of llmRequest.contents) {\n if (!content.parts) continue;\n for (const part of content.parts) {\n removeDisplayNameIfPresent(part.inlineData);\n removeDisplayNameIfPresent(part.fileData);\n }\n }\n }\n }\n }\n}\n\nfunction removeDisplayNameIfPresent(\n dataObj: Blob|FileData|undefined,\n ): void {\n // display_name is not supported for Gemini API (non-vertex)\n if (dataObj && (dataObj as FileData).displayName) {\n (dataObj as FileData).displayName = undefined;\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * The Google LLM variant to use.\n * see\n * https://google.github.io/adk-docs/get-started/quickstart/#set-up-the-model\n */\nexport enum GoogleLLMVariant {\n /**\n * For using credentials from Google Vertex AI\n */\n VERTEX_AI = 'VERTEX_AI',\n\n /**\n * For using API Key from Google AI Studio\n */\n GEMINI_API = 'GEMINI_API',\n}\n\n/**\n * Gets the Google LLM variant to use.\n */\nexport function getGoogleLlmVariant() {\n return getBooleanEnvVar('GOOGLE_GENAI_USE_VERTEXAI') ?\n GoogleLLMVariant.VERTEX_AI :\n GoogleLLMVariant.GEMINI_API;\n}\n\n/**\n * Gets the boolean value of the given environment variable.\n *\n * @param envVar The environment variable to get the value of.\n * @return The boolean value of the environment variable.\n */\nfunction getBooleanEnvVar(envVar: string): boolean {\n if (!process.env) {\n return false;\n }\n\n const envVarValue = (process.env[envVar] || '').toLowerCase();\n\n return ['true', '1'].includes(envVar.toLowerCase());\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Blob, Content, FunctionResponse, Session,} from '@google/genai';\n\nimport {logger} from '../utils/logger.js';\n\nimport {BaseLlmConnection} from './base_llm_connection.js';\nimport {LlmResponse} from './llm_response.js';\n\n/** The Gemini model connection. */\nexport class GeminiLlmConnection implements BaseLlmConnection {\n constructor(\n private readonly geminiSession: Session,\n ) {}\n\n /**\n * Sends the conversation history to the gemini model.\n *\n * You call this method right after setting up the model connection.\n * The model will respond if the last content is from user, otherwise it will\n * wait for new user input before responding.\n *\n * @param history The conversation history to send to the model.\n */\n async sendHistory(history: Content[]): Promise<void> {\n // We ignore any audio from user during the agent transfer phase.\n const contents = history.filter(\n (content) => content.parts && content.parts[0]?.text,\n );\n\n if (contents.length > 0) {\n this.geminiSession.sendClientContent({\n turns: contents,\n turnComplete: contents[contents.length - 1].role === 'user',\n });\n } else {\n logger.info('no content is sent');\n }\n }\n\n /**\n * Sends a user content to the gemini model.\n *\n * The model will respond immediately upon receiving the content.\n * If you send function responses, all parts in the content should be function\n * responses.\n *\n * @param content The content to send to the model.\n */\n async sendContent(content: Content): Promise<void> {\n if (!content.parts) {\n throw new Error('Content must have parts.');\n }\n if (content.parts[0].functionResponse) {\n // All parts have to be function responses.\n const functionResponses =\n content.parts.map((part) => part.functionResponse)\n .filter((fr): fr is FunctionResponse => !!fr);\n logger.debug('Sending LLM function response:', functionResponses);\n this.geminiSession.sendToolResponse({\n functionResponses,\n });\n } else {\n logger.debug('Sending LLM new content', content);\n this.geminiSession.sendClientContent({\n turns: [content],\n turnComplete: true,\n });\n }\n }\n\n /**\n * Sends a chunk of audio or a frame of video to the model in realtime.\n *\n * @param blob The blob to send to the model.\n */\n async sendRealtime(blob: Blob): Promise<void> {\n logger.debug('Sending LLM Blob:', blob);\n this.geminiSession.sendRealtimeInput({media: blob});\n }\n\n /**\n * Builds a full text response.\n *\n * The text should not be partial and the returned LlmResponse is not be\n * partial.\n *\n * @param text The text to be included in the response.\n * @returns An LlmResponse containing the full text.\n */\n private buildFullTextResponse(text: string): LlmResponse {\n return {\n content: {\n role: 'model',\n parts: [{text}],\n },\n };\n }\n\n // TODO(b/425992518): GenAI SDK inconsistent API, missing methods.\n async * receive(): AsyncGenerator<LlmResponse, void, void> {\n throw new Error('Not Implemented.');\n }\n\n /**\n * Closes the llm server connection.\n */\n async close(): Promise<void> {\n this.geminiSession.close();\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Content, FinishReason, GenerateContentResponse, GenerateContentResponseUsageMetadata, GroundingMetadata, LiveServerSessionResumptionUpdate, Transcription,} from '@google/genai';\n\n/**\n * LLM response class that provides the first candidate response from the\n * model if available. Otherwise, returns error code and message.\n */\nexport interface LlmResponse {\n /**\n * The content of the response.\n */\n content?: Content;\n\n /**\n * The grounding metadata of the response.\n */\n groundingMetadata?: GroundingMetadata;\n\n /**\n * Indicates whether the text content is part of a unfinished text stream.\n * Only used for streaming mode and when the content is plain text.\n */\n partial?: boolean;\n\n /**\n * Indicates whether the response from the model is complete.\n * Only used for streaming mode.\n */\n turnComplete?: boolean;\n\n /**\n * Error code if the response is an error. Code varies by model.\n */\n errorCode?: string;\n\n /**\n * Error message if the response is an error.\n */\n errorMessage?: string;\n\n /**\n * Flag indicating that LLM was interrupted when generating the content.\n * Usually it's due to user interruption during a bidi streaming.\n */\n interrupted?: boolean;\n\n /**\n * The custom metadata of the LlmResponse.\n * An optional key-value pair to label an LlmResponse.\n * NOTE: the entire object must be JSON serializable.\n */\n customMetadata?: {[key: string]: any};\n\n /**\n * The usage metadata of the LlmResponse.\n */\n usageMetadata?: GenerateContentResponseUsageMetadata;\n\n /**\n * The finish reason of the response.\n */\n finishReason?: FinishReason;\n\n /**\n * The session resumption update of the LlmResponse\n */\n liveSessionResumptionUpdate?: LiveServerSessionResumptionUpdate;\n\n /**\n * Audio transcription of user input.\n */\n inputTranscription?: Transcription;\n\n /**\n * Audio transcription of model output.\n */\n outputTranscription?: Transcription;\n}\n\n/**\n * Creates an LlmResponse from a GenerateContentResponse.\n *\n * @param response The GenerateContentResponse to create the\n * LlmResponse from.\n * @returns The LlmResponse.\n */\nexport function createLlmResponse(\n response: GenerateContentResponse,\n ): LlmResponse {\n const usageMetadata = response.usageMetadata;\n\n if (response.candidates && response.candidates.length > 0) {\n const candidate = response.candidates[0];\n if (candidate.content?.parts && candidate.content.parts.length > 0) {\n return {\n content: candidate.content,\n groundingMetadata: candidate.groundingMetadata,\n usageMetadata: usageMetadata,\n finishReason: candidate.finishReason,\n };\n }\n\n return {\n errorCode: candidate.finishReason,\n errorMessage: candidate.finishMessage,\n usageMetadata: usageMetadata,\n finishReason: candidate.finishReason,\n };\n }\n\n if (response.promptFeedback) {\n return {\n errorCode: response.promptFeedback.blockReason,\n errorMessage: response.promptFeedback.blockReasonMessage,\n usageMetadata: usageMetadata,\n };\n }\n\n // The ultimate fallback for an unknown error state\n return {\n errorCode: 'UNKNOWN_ERROR',\n errorMessage: 'Unknown error.',\n usageMetadata: usageMetadata,\n };\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {logger} from '../utils/logger.js';\n\nimport {BaseLlm} from './base_llm.js';\nimport {Gemini} from './google_llm.js';\n\n/**\n * type[BaseLlm] equivalent in TypeScript, represents a class that can be new-ed\n * to create a BaseLlm instance.\n */\nexport type BaseLlmType = (new (params: {model: string}) => BaseLlm)&{\n readonly supportedModels: Array<string|RegExp>;\n};\n\n/**\n * A simple LRU cache.\n */\n// TODO - b/425992518: consider remove this. model resolution is not frequent.\nclass LRUCache<K, V> {\n private readonly maxSize: number;\n private cache: Map<K, V>;\n\n constructor(maxSize: number) {\n this.maxSize = maxSize;\n this.cache = new Map<K, V>();\n }\n\n get(key: K): V|undefined {\n const item = this.cache.get(key);\n if (item) {\n // Map maintians insertion order.\n this.cache.delete(key);\n this.cache.set(key, item);\n }\n return item;\n }\n\n set(key: K, value: V): void {\n if (this.cache.size >= this.maxSize && !this.cache.has(key)) {\n const lruKey = this.cache.keys().next().value;\n if (lruKey !== undefined) {\n this.cache.delete(lruKey);\n }\n }\n this.cache.set(key, value);\n }\n}\n\n/**\n * Registry for LLMs.\n */\nexport class LLMRegistry {\n /**\n * Key is the regex that matches the model name.\n * Value is the class that implements the model.\n */\n private static llmRegistryDict: Map<string|RegExp, BaseLlmType> = new Map();\n private static resolveCache = new LRUCache<string, BaseLlmType>(32);\n\n /**\n * Creates a new LLM instance.\n * @param model The model name.\n * @returns The LLM instance.\n */\n static newLlm(model: string): BaseLlm {\n return new (LLMRegistry.resolve(model))({model});\n }\n\n private static _register(modelNameRegex: string|RegExp, llmCls: BaseLlmType) {\n if (LLMRegistry.llmRegistryDict.has(modelNameRegex)) {\n logger.info(\n `Updating LLM class for ${modelNameRegex} from ${\n LLMRegistry.llmRegistryDict.get(modelNameRegex)} to ${llmCls}`,\n );\n }\n LLMRegistry.llmRegistryDict.set(modelNameRegex, llmCls);\n }\n\n /**\n * Registers a new LLM class.\n * @param llmCls The class that implements the model.\n */\n static register<T extends BaseLlm>(\n llmCls: (new(params: {model: string}) => T)&{\n readonly supportedModels: Array<string|RegExp>;\n }) {\n for (const regex of llmCls.supportedModels) {\n LLMRegistry._register(regex, llmCls);\n }\n }\n\n /**\n * Resolves the model to a BaseLlm subclass.\n * @param model The model name.\n * @returns The BaseLlm subclass.\n * @throws If the model is not found.\n */\n static resolve(model: string): BaseLlmType {\n const cachedLlm = LLMRegistry.resolveCache.get(model);\n if (cachedLlm) {\n return cachedLlm;\n }\n\n for (const [regex, llmClass] of LLMRegistry.llmRegistryDict.entries()) {\n // Replicates Python's `re.fullmatch` by anchoring the regex\n // to the start (^) and end ($) of the string.\n // TODO - b/425992518: validate it works well.\n const pattern = new RegExp(\n `^${regex instanceof RegExp ? regex.source : regex}$`,\n regex instanceof RegExp ? regex.flags : undefined,\n );\n if (pattern.test(model)) {\n LLMRegistry.resolveCache.set(model, llmClass);\n return llmClass;\n }\n }\n\n throw new Error(`Model ${model} not found.`);\n }\n}\n\n/** Registers default LLM factories, e.g. for Gemini models. */\nLLMRegistry.register(Gemini);\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {FunctionDeclaration, Tool} from '@google/genai';\n\nimport {LlmRequest} from '../models/llm_request.js';\nimport {getGoogleLlmVariant} from '../utils/variant_utils.js';\n\nimport {ToolContext} from './tool_context.js';\n\n/**\n * The parameters for `runAsync`.\n */\nexport interface RunAsyncToolRequest {\n args: Record<string, unknown>;\n toolContext: ToolContext;\n}\n\n/**\n * The parameters for `processLlmRequest`.\n */\nexport interface ToolProcessLlmRequest {\n toolContext: ToolContext;\n llmRequest: LlmRequest;\n}\n\n/**\n * Parameters for the BaseTool constructor.\n */\nexport interface BaseToolParams {\n name: string;\n description: string;\n isLongRunning?: boolean;\n}\n\n/**\n * The base class for all tools.\n */\nexport abstract class BaseTool {\n readonly name: string;\n readonly description: string;\n readonly isLongRunning: boolean;\n\n /**\n * Base constructor for a tool.\n *\n * @param params The parameters for `BaseTool`.\n */\n constructor(params: BaseToolParams) {\n this.name = params.name;\n this.description = params.description;\n this.isLongRunning = params.isLongRunning ?? false;\n }\n\n /**\n * Gets the OpenAPI specification of this tool in the form of a\n * FunctionDeclaration.\n *\n * NOTE\n * - Required if subclass uses the default implementation of\n * `processLlmRequest` to add function declaration to LLM request.\n * - Otherwise, can be skipped, e.g. for a built-in GoogleSearch tool for\n * Gemini.\n *\n * @return The FunctionDeclaration of this tool, or undefined if it doesn't\n * need to be added to LlmRequest.config.\n */\n _getDeclaration(): FunctionDeclaration|undefined {\n return undefined;\n }\n\n /**\n * Runs the tool with the given arguments and context.\n *\n * NOTE\n * - Required if this tool needs to run at the client side.\n * - Otherwise, can be skipped, e.g. for a built-in GoogleSearch tool for\n * Gemini.\n *\n * @param request The request to run the tool.\n * @return A promise that resolves to the tool response.\n */\n abstract runAsync(request: RunAsyncToolRequest): Promise<unknown>;\n\n /**\n * Processes the outgoing LLM request for this tool.\n *\n * Use cases:\n * - Most common use case is adding this tool to the LLM request.\n * - Some tools may just preprocess the LLM request before it's sent out.\n *\n * @param request The request to process the LLM request.\n */\n async processLlmRequest({toolContext, llmRequest}: ToolProcessLlmRequest):\n Promise<void> {\n const functionDeclaration = this._getDeclaration();\n if (!functionDeclaration) {\n return;\n }\n\n llmRequest.toolsDict[this.name] = this;\n\n const tool = findToolWithFunctionDeclarations(llmRequest);\n if (tool) {\n if (!tool.functionDeclarations) {\n tool.functionDeclarations = [];\n }\n\n tool.functionDeclarations.push(functionDeclaration);\n } else {\n llmRequest.config = llmRequest.config || {};\n llmRequest.config.tools = llmRequest.config.tools || [];\n llmRequest.config.tools.push({\n functionDeclarations: [functionDeclaration],\n });\n }\n }\n\n /**\n * The Google API LLM variant to use.\n */\n get apiVariant() {\n return getGoogleLlmVariant();\n }\n}\n\nfunction findToolWithFunctionDeclarations(llmRequest: LlmRequest): Tool|\n undefined {\n return (llmRequest.config?.tools ||\n []).find(tool => 'functionDeclarations' in tool) as Tool |\n undefined;\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {FunctionDeclaration, Schema, Type} from '@google/genai';\nimport {type infer as zInfer, ZodObject} from 'zod';\n\nimport {isZodObject, zodObjectToSchema} from '../utils/simple_zod_to_json.js';\n\nimport {BaseTool, RunAsyncToolRequest} from './base_tool.js';\nimport {ToolContext} from './tool_context.js';\n\n/**\n * Input parameters of the function tool.\n */\nexport type ToolInputParameters =|undefined|ZodObject<any>|Schema;\n\n/*\n * The arguments of the function tool.\n */\nexport type ToolExecuteArgument<TParameters extends ToolInputParameters> =\n TParameters extends ZodObject<any>?\n zInfer<TParameters>:\n TParameters extends Schema ? unknown : string;\n\n/*\n * The function to execute by the tool.\n */\ntype ToolExecuteFunction<\n TParameters extends ToolInputParameters,\n> = (\n input: ToolExecuteArgument<TParameters>,\n tool_context?: ToolContext,\n) => Promise<unknown> | unknown;\n\n/**\n * The configuration options for creating a function-based tool.\n * The `name`, `description` and `parameters` fields are used to generate the\n * tool definition that is passed to the LLM prompt.\n *\n * Note: Unlike Python's ADK, JSDoc on the `execute` function is ignored\n * for tool definition generation.\n */\nexport type ToolOptions<\n TParameters extends ToolInputParameters,\n> = {\n name?: string;\n description: string;\n parameters?: TParameters;\n execute: ToolExecuteFunction<TParameters>;\n isLongRunning?: boolean;\n};\n\nfunction toSchema<TParameters extends ToolInputParameters>(\n parameters: TParameters): Schema {\n if (parameters === undefined) {\n return {type: Type.OBJECT, properties: {}};\n }\n\n if (isZodObject(parameters)) {\n return zodObjectToSchema(parameters);\n }\n\n return parameters;\n}\n\nexport class FunctionTool<\n TParameters extends ToolInputParameters = undefined,\n> extends BaseTool {\n // User defined function.\n private readonly execute: ToolExecuteFunction<TParameters>;\n // Typed input parameters.\n private readonly parameters?: TParameters;\n\n /**\n * The constructor acts as the user-friendly factory.\n * @param options The configuration for the tool.\n */\n constructor(options: ToolOptions<TParameters>) {\n const name = options.name ?? (options.execute as any).name;\n if (!name) {\n throw new Error(\n 'Tool name cannot be empty. Either name the `execute` function or provide a `name`.',\n );\n }\n super({\n name,\n description: options.description,\n isLongRunning: options.isLongRunning\n });\n this.execute = options.execute;\n this.parameters = options.parameters;\n }\n\n /**\n * Provide a schema for the function.\n */\n override _getDeclaration(): FunctionDeclaration {\n return {\n name: this.name,\n description: this.description,\n parameters: toSchema(this.parameters),\n };\n }\n\n /**\n * Logic for running the tool.\n */\n override async runAsync(req: RunAsyncToolRequest): Promise<unknown> {\n try {\n let validatedArgs: unknown = req.args;\n if (this.parameters instanceof ZodObject) {\n validatedArgs = this.parameters.parse(req.args);\n }\n return await this.execute(\n validatedArgs as ToolExecuteArgument<TParameters>, req.toolContext);\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n throw new Error(`Error in tool '${this.name}': ${errorMessage}`);\n }\n }\n}", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Schema, Type} from '@google/genai';\nimport {z, ZodObject, ZodTypeAny} from 'zod';\n\n/**\n * Returns true if the given object is a V3 ZodObject.\n */\nexport function isZodObject(obj: unknown): obj is ZodObject<any> {\n return (\n obj !== null && typeof obj === 'object' &&\n (obj as any)._def?.typeName === 'ZodObject');\n}\n\n// TODO(b/425992518): consider conversion to FunctionDeclaration directly.\n\nfunction parseZodType(zodType: ZodTypeAny): Schema|undefined {\n const def = zodType._def;\n if (!def) {\n return {};\n }\n const description = def.description;\n const result: Schema = {};\n if (description) result.description = description;\n\n const returnResult = (result: Schema) => {\n if (result.description === undefined) {\n delete result.description;\n }\n return result;\n };\n\n switch (def.typeName) {\n case z.ZodFirstPartyTypeKind.ZodString:\n result.type = Type.STRING;\n for (const check of def.checks || []) {\n if (check.kind === 'min')\n result.minLength = check.value.toString();\n else if (check.kind === 'max')\n result.maxLength = check.value.toString();\n else if (check.kind === 'email')\n result.format = 'email';\n else if (check.kind === 'uuid')\n result.format = 'uuid';\n else if (check.kind === 'url')\n result.format = 'uri';\n else if (check.kind === 'regex')\n result.pattern = check.regex.source;\n }\n return returnResult(result);\n\n case z.ZodFirstPartyTypeKind.ZodNumber:\n result.type = Type.NUMBER;\n for (const check of def.checks || []) {\n if (check.kind === 'min')\n result.minimum = check.value;\n else if (check.kind === 'max')\n result.maximum = check.value;\n else if (check.kind === 'int')\n result.type = Type.INTEGER;\n }\n return returnResult(result);\n\n case z.ZodFirstPartyTypeKind.ZodBoolean:\n result.type = Type.BOOLEAN;\n return returnResult(result);\n\n case z.ZodFirstPartyTypeKind.ZodArray:\n result.type = Type.ARRAY;\n result.items = parseZodType(def.type);\n if (def.minLength) result.minItems = def.minLength.value.toString();\n if (def.maxLength) result.maxItems = def.maxLength.value.toString();\n return returnResult(result);\n\n case z.ZodFirstPartyTypeKind.ZodObject: {\n const nestedSchema = zodObjectToSchema(zodType as ZodObject<any>);\n return nestedSchema as Schema;\n }\n\n case z.ZodFirstPartyTypeKind.ZodLiteral:\n const literalType = typeof def.value;\n result.enum = [def.value.toString()];\n\n if (literalType === 'string') {\n result.type = Type.STRING;\n } else if (literalType === 'number') {\n result.type = Type.NUMBER;\n } else if (literalType === 'boolean') {\n result.type = Type.BOOLEAN;\n } else if (def.value === null) {\n result.type = Type.NULL;\n } else {\n throw new Error(`Unsupported ZodLiteral value type: ${literalType}`);\n }\n\n return returnResult(result);\n\n case z.ZodFirstPartyTypeKind.ZodEnum:\n result.type = Type.STRING;\n result.enum = def.values;\n return returnResult(result);\n\n case z.ZodFirstPartyTypeKind.ZodNativeEnum:\n result.type = Type.STRING;\n result.enum = Object.values(def.values);\n return returnResult(result);\n\n case z.ZodFirstPartyTypeKind.ZodUnion:\n result.anyOf = def.options.map(parseZodType);\n return returnResult(result);\n\n case z.ZodFirstPartyTypeKind.ZodOptional:\n return parseZodType(def.innerType);\n case z.ZodFirstPartyTypeKind.ZodNullable:\n const nullableInner = parseZodType(def.innerType);\n return nullableInner ?\n returnResult({\n anyOf: [nullableInner, {type: Type.NULL}],\n ...(description && {description})\n }) :\n returnResult({type: Type.NULL, ...(description && {description})});\n case z.ZodFirstPartyTypeKind.ZodDefault:\n const defaultInner = parseZodType(def.innerType);\n if (defaultInner) defaultInner.default = def.defaultValue();\n return defaultInner;\n case z.ZodFirstPartyTypeKind.ZodBranded:\n return parseZodType(def.type);\n case z.ZodFirstPartyTypeKind.ZodReadonly:\n return parseZodType(def.innerType);\n case z.ZodFirstPartyTypeKind.ZodNull:\n result.type = Type.NULL;\n return returnResult(result);\n case z.ZodFirstPartyTypeKind.ZodAny:\n case z.ZodFirstPartyTypeKind.ZodUnknown:\n return returnResult({...(description && {description})});\n default:\n throw new Error(`Unsupported Zod type: ${def.typeName}`);\n }\n}\n\nexport function zodObjectToSchema(schema: ZodObject<any>): Schema {\n if (schema._def.typeName !== z.ZodFirstPartyTypeKind.ZodObject) {\n throw new Error('Expected a ZodObject');\n }\n\n const shape = schema.shape;\n const properties: Record<string, Schema> = {};\n const required: string[] = [];\n\n for (const key in shape) {\n const fieldSchema = shape[key];\n const parsedField = parseZodType(fieldSchema);\n if (parsedField) {\n properties[key] = parsedField;\n }\n\n let currentSchema = fieldSchema;\n let isOptional = false;\n while (currentSchema._def.typeName ===\n z.ZodFirstPartyTypeKind.ZodOptional ||\n currentSchema._def.typeName === z.ZodFirstPartyTypeKind.ZodDefault) {\n isOptional = true;\n currentSchema = currentSchema._def.innerType;\n }\n if (!isOptional) {\n required.push(key);\n }\n }\n\n const catchall = schema._def.catchall;\n let additionalProperties: boolean|Schema = false;\n if (catchall && catchall._def.typeName !== z.ZodFirstPartyTypeKind.ZodNever) {\n additionalProperties = parseZodType(catchall) || true;\n } else {\n additionalProperties = schema._def.unknownKeys === 'passthrough';\n }\n return {\n type: Type.OBJECT,\n properties,\n required: required.length > 0 ? required : [],\n ...(schema._def.description ? {description: schema._def.description} : {}),\n };\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {InvocationContext} from '../agents/invocation_context.js';\nimport {Event} from '../events/event.js';\nimport {LlmRequest} from '../models/llm_request.js';\nimport {LlmResponse} from '../models/llm_response.js';\n\n/**\n * Base class for LLM request processor.\n */\nexport abstract class BaseLlmRequestProcessor {\n /**\n * Runs the processor.\n */\n abstract runAsync(\n invocationContext: InvocationContext,\n llmRequest: LlmRequest): AsyncGenerator<Event, void, void>;\n}\n\n/**\n * Base class for LLM response processor.\n */\nexport abstract class BaseLlmResponseProcessor {\n /**\n * Processes the LLM response.\n */\n abstract runAsync(\n invocationContext: InvocationContext,\n llmResponse: LlmResponse): AsyncGenerator<Event, void, void>;\n}", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {Content} from '@google/genai';\n\nimport {createEvent, Event, getFunctionCalls, getFunctionResponses} from '../events/event.js';\nimport {deepClone} from '../utils/deep_clone.js';\n\nimport {removeClientFunctionCallId, REQUEST_CONFIRMATION_FUNCTION_CALL_NAME, REQUEST_EUC_FUNCTION_CALL_NAME} from './functions.js';\n\n/**\n * Get the contents for the LLM request.\n *\n * @param events: A list of all session events.\n * @param agentName: The name of the agent.\n * @param currentBranch: The current branch of the agent.\n *\n * @returns A list of processed contents.\n */\nexport function getContents(\n events: Event[], agentName: string, currentBranch?: string): Content[] {\n const filteredEvents: Event[] = [];\n\n for (const event of events) {\n // Skip events without content, or generated neither by user nor by model.\n // E.g. events purely for mutating session states.\n // Also skip events with empty parts array (can happen during streaming with parallel tool calls)\n if (!event.content?.role || !event.content.parts?.length) {\n continue;\n }\n\n // Skip events not in the current branch.\n // TODO - b/425992518: inefficient, a tire search is better.\n if (currentBranch && event.branch &&\n !currentBranch.startsWith(event.branch)) {\n continue;\n }\n\n if (isAuthEvent(event)) {\n continue;\n }\n\n if (isToolConfirmationEvent(event)) {\n continue;\n }\n\n filteredEvents.push(\n isEventFromAnotherAgent(agentName, event) ? convertForeignEvent(event) :\n event);\n }\n\n let resultEvents = rearrangeEventsForLatestFunctionResponse(filteredEvents);\n resultEvents =\n rearrangeEventsForAsyncFunctionResponsesInHistory(resultEvents);\n const contents = [];\n for (const event of resultEvents) {\n const content = deepClone(event.content) as Content;\n removeClientFunctionCallId(content);\n contents.push(content);\n }\n return contents;\n}\n\n/**\n * Get contents for the current turn only (no conversation history).\n *\n * When include_contents='none', we want to include:\n * - The current user input\n * - Tool calls and responses from the current turn\n * But exclude conversation history from previous turns.\n *\n * In multi-agent scenarios, the \"current turn\" for an agent starts from an\n * actual user or from another agent.\n *\n * @param events: A list of all session events.\n * @param agentName: The name of the agent.\n * @param currentBranch: The current branch of the agent.\n *\n * @returns A list of contents for the current turn only, preserving context\n * needed for proper tool execution while excluding conversation history.\n */\nexport function getCurrentTurnContents(\n events: Event[],\n agentName: string,\n currentBranch?: string,\n ): Content[] {\n // Find the latest event that starts the current turn and process from there.\n for (let i = events.length - 1; i >= 0; i--) {\n const event = events[i];\n if (event.author === 'user' || isEventFromAnotherAgent(agentName, event)) {\n return getContents(events.slice(i), agentName, currentBranch);\n }\n }\n\n return [];\n}\n\n/**\n * Whether the event is an auth event.\n *\n * An auth event is an event that contains a function call or response\n * related to requesting end-user credentials (EUC). These events are\n * skipped when constructing the content for the LLM request.\n */\nfunction isAuthEvent(event: Event): boolean {\n if (!event.content?.parts) {\n return false;\n }\n for (const part of event.content.parts) {\n if (part.functionCall?.name === REQUEST_EUC_FUNCTION_CALL_NAME ||\n part.functionResponse?.name === REQUEST_EUC_FUNCTION_CALL_NAME) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Whether the event is a tool confirmation event.\n *\n * A tool confirmation event is an event that contains a function call or\n * response related to requesting confirmation for a tool call. These events\n * are skipped when constructing the content for the LLM request.\n */\nfunction isToolConfirmationEvent(event: Event): boolean {\n if (!event.content?.parts) {\n return false;\n }\n for (const part of event.content.parts) {\n if (part.functionCall?.name === REQUEST_CONFIRMATION_FUNCTION_CALL_NAME ||\n part.functionResponse?.name ===\n REQUEST_CONFIRMATION_FUNCTION_CALL_NAME) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Whether the event is from another agent.\n */\nfunction isEventFromAnotherAgent(agentName: string, event: Event): boolean {\n return !!agentName && event.author !== agentName && event.author !== 'user';\n}\n\n/**\n * Formats an event authored by another agent to a user-content event.\n *\n * This is to provide another agent's output as context to the current agent,\n * so that current agent can continue to respond, such as summarizing previous\n * agent's reply, etc.\n *\n * @param event The event to convert.\n *\n * @returns The converted event.\n */\nfunction convertForeignEvent(event: Event): Event {\n if (!event.content?.parts?.length) {\n return event;\n }\n\n const content: Content = {\n role: 'user',\n parts: [{\n text: 'For context:',\n }],\n };\n\n for (const part of event.content.parts) {\n // Exclude thoughts from the context.\n // TODO - b/425992518: filtring should be configurable.\n if (part.text && !part.thought) {\n content.parts?.push({\n text: `[${event.author}] said: ${part.text}`,\n });\n } else if (part.functionCall) {\n const argsText = safeStringify(part.functionCall.args);\n content.parts?.push({\n text: `[${event.author}] called tool \\`${\n part.functionCall.name}\\` with parameters: ${argsText}`,\n });\n } else if (part.functionResponse) {\n const responseText = safeStringify(part.functionResponse.response);\n content.parts?.push({\n text: `[${event.author}] tool \\`${\n part.functionResponse.name}\\` returned result: ${responseText}`,\n });\n } else {\n content.parts?.push(part);\n }\n }\n\n return createEvent({\n invocationId: event.invocationId,\n author: 'user',\n content,\n branch: event.branch,\n timestamp: event.timestamp,\n });\n}\n\n/**\n * Merges a list of function_response events into one event.\n *\n * The key goal is to ensure:\n * 1. function_call and function_response are always of the same number.\n * 2. The function_call and function_response are consecutively in the content.\n *\n * @param events: A list of function_response events.\n *\n * NOTE:\n * function_response_events must fulfill these requirements:\n * 1. The list is in increasing order of timestamp;\n * 2. the first event is the initial function_response event;\n * 3. all later events should contain at least one function_response part that\n * related to the function_call event. Caveat: This implementation doesn't\n * support when a parallel function_call event contains async function_call of\n * the same name.\n *\n * @returns\n * A merged event, that is\n * 1. All later function_response will replace function_response part in\n * the initial function_response event.\n * 2. All non-function_response parts will be appended to the part list of\n * the initial function_response event.\n */\nfunction mergeFunctionResponseEvents(events: Event[]): Event {\n if (events.length === 0) {\n throw new Error('Cannot merge an empty list of events.');\n }\n\n const mergedEvent = createEvent(events[0]);\n const partsInMergedEvent = mergedEvent.content?.parts || [];\n\n if (partsInMergedEvent.length === 0) {\n throw new Error('There should be at least one function_response part.');\n }\n\n const partIndicesInMergedEvent: Record<string, number> = {};\n for (let i = 0; i < partsInMergedEvent.length; i++) {\n const part = partsInMergedEvent[i];\n if (part.functionResponse && part.functionResponse.id) {\n partIndicesInMergedEvent[part.functionResponse.id] = i;\n }\n }\n\n for (const event of events.slice(1)) {\n if (!event.content || !event.content.parts) {\n throw new Error('There should be at least one function_response part.');\n }\n for (const part of event.content.parts) {\n if (part.functionResponse && part.functionResponse.id) {\n const functionCallId = part.functionResponse.id;\n if (functionCallId in partIndicesInMergedEvent) {\n partsInMergedEvent[partIndicesInMergedEvent[functionCallId]] = part;\n } else {\n partsInMergedEvent.push(part);\n partIndicesInMergedEvent[functionCallId] =\n partsInMergedEvent.length - 1;\n }\n } else {\n partsInMergedEvent.push(part);\n }\n }\n }\n\n return mergedEvent;\n}\n\n/**\n * Rearrange the async functionResponse events in the history.\n */\nfunction rearrangeEventsForLatestFunctionResponse(\n events: Event[],\n ): Event[] {\n if (events.length === 0) {\n return events;\n }\n\n const latestEvent = events[events.length - 1];\n const functionResponses = getFunctionResponses(latestEvent);\n\n // No need to process, since the latest event is not functionResponse.\n if (!functionResponses?.length) {\n return events;\n }\n\n let functionResponsesIds = new Set<string>(\n functionResponses\n .filter((response): response is {id: string} => !!response.id)\n .map((response) => response.id),\n );\n\n // No need to rearrange if the second latest event already contains the\n // corresponding function calls for the latest function responses.\n const secondLatestEvent = events.at(-2);\n if (secondLatestEvent) {\n const functionCallsFromSecondLatest = getFunctionCalls(secondLatestEvent);\n if (functionCallsFromSecondLatest) {\n for (const functionCall of functionCallsFromSecondLatest) {\n if (functionCall.id && functionResponsesIds.has(functionCall.id)) {\n return events;\n }\n }\n }\n }\n\n // Look for corresponding function call event reversely.\n let functionCallEventIdx = -1;\n for (let idx = events.length - 2; idx >= 0; idx--) {\n const event = events[idx];\n const functionCalls = getFunctionCalls(event);\n if (!functionCalls?.length) {\n continue;\n }\n\n for (const functionCall of functionCalls) {\n if (functionCall.id && functionResponsesIds.has(functionCall.id)) {\n functionCallEventIdx = idx;\n const functionCallIds = new Set<string>(\n functionCalls.map(fc => fc.id).filter((id): id is string => !!id),\n );\n\n // Check if functionResponsesIds is a subset of functionCallIds\n const isSubset = Array.from(functionResponsesIds)\n .every(id => functionCallIds.has(id));\n\n if (!isSubset) {\n throw new Error(\n 'Last response event should only contain the responses for the' +\n ' function calls in the same function call event. Function' +\n ` call ids found : ${\n Array.from(functionCallIds)\n .join(', ')}, function response` +\n ` ids provided: ${\n Array.from(functionResponsesIds).join(', ')}`,\n );\n }\n // Expand the function call events to collect all function responses\n // from the function call event to the last response event.\n // TODO - b/425992518: bad practice, state can mutated multiple times.\n functionResponsesIds = functionCallIds;\n break;\n }\n }\n }\n\n if (functionCallEventIdx === -1) {\n throw new Error(\n `No function call event found for function responses ids: ${\n Array\n .from(\n functionResponsesIds,\n )\n .join(', ')}`,\n );\n }\n\n // Collect all function response events between the function call event\n // and the last function response event\n const functionResponseEvents: Event[] = [];\n for (let idx = functionCallEventIdx + 1; idx < events.length - 1; idx++) {\n const event = events[idx];\n const responses = getFunctionResponses(event);\n if (responses &&\n responses.some(\n (response) =>\n response.id && functionResponsesIds.has(response.id))) {\n functionResponseEvents.push(event);\n }\n }\n functionResponseEvents.push(events[events.length - 1]);\n\n const resultEvents = events.slice(0, functionCallEventIdx + 1);\n resultEvents.push(mergeFunctionResponseEvents(functionResponseEvents));\n\n return resultEvents;\n}\n\n/**\n * Rearrange the events for the latest function_response.\n *\n * If the latest function_response is for an async function_call, all events\n * between the initial function_call and the latest function_response will be\n * removed.\n *\n * @param event: A list of events.\n *\n * @returns A list of events with the latest function_response rearranged.\n */\nfunction rearrangeEventsForAsyncFunctionResponsesInHistory(\n events: Event[],\n ): Event[] {\n const functionCallIdToResponseEventIndex: Map<string, number> = new Map();\n\n // First pass: Map function_call_id to the index of their\n // corresponding response events.\n for (let i = 0; i < events.length; i++) {\n const event = events[i];\n const functionResponses = getFunctionResponses(event);\n if (functionResponses?.length) {\n for (const functionResponse of functionResponses) {\n if (!functionResponse.id) {\n continue;\n }\n\n functionCallIdToResponseEventIndex.set(functionResponse.id, i);\n }\n }\n }\n\n const resultEvents: Event[] = [];\n\n // Second pass: Build the new ordered list of events.\n for (const event of events) {\n // If the event contains function responses, it will be handled when\n // its corresponding function_call is encountered, so skip it for now.\n if (getFunctionResponses(event).length > 0) {\n continue;\n }\n\n const functionCalls = getFunctionCalls(event);\n if (functionCalls?.length) {\n const functionResponseEventsIndices: Set<number> = new Set();\n for (const functionCall of functionCalls) {\n const functionCallId = functionCall.id;\n if (functionCallId &&\n functionCallIdToResponseEventIndex.has(functionCallId)) {\n functionResponseEventsIndices.add(\n functionCallIdToResponseEventIndex.get(functionCallId)!,\n );\n }\n }\n\n resultEvents.push(event);\n\n if (functionResponseEventsIndices.size === 0) {\n continue;\n }\n\n if (functionResponseEventsIndices.size === 1) {\n const [responseIndex] = [...functionResponseEventsIndices];\n resultEvents.push(events[responseIndex]);\n } else {\n const indicesArray =\n Array.from(functionResponseEventsIndices).sort((a, b) => a - b);\n const eventsToMerge = indicesArray.map((index) => events[index]);\n resultEvents.push(mergeFunctionResponseEvents(eventsToMerge));\n }\n } else {\n resultEvents.push(event);\n }\n }\n\n return resultEvents;\n}\n\n/**\n * Safely stringifies an object, handling circular references.\n */\nfunction safeStringify(obj: unknown): string {\n if (typeof obj === 'string') {\n return obj;\n }\n try {\n return JSON.stringify(obj);\n } catch (e) {\n return String(obj);\n }\n}\n\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {State} from '../sessions/state.js';\nimport {ReadonlyContext} from './readonly_context.js';\n\n/**\n * Populates values in the instruction template, e.g. state, artifact, etc.\n *\n * ```\n * async function buildInstruction(\n * readonlyContext: ReadonlyContext,\n * ): Promise<string> {\n * return await injectSessionState(\n * 'You can inject a state variable like {var_name} or an artifact ' +\n * '{artifact.file_name} into the instruction template.',\n * readonlyContext,\n * );\n * }\n *\n * const agent = new LlmAgent({\n * model: 'gemini-1.5-flash',\n * name: 'agent',\n * instruction: buildInstruction,\n * });\n * ```\n *\n * @param template The instruction template.\n * @param readonlyContext The read-only context\n * @returns The instruction template with values populated.\n */\nexport async function injectSessionState(\n template: string,\n readonlyContext: ReadonlyContext,\n ): Promise<string> {\n const invocationContext = readonlyContext.invocationContext;\n\n /**\n * Replaces a matched string in the template with the corresponding value from\n * the context.\n *\n * @param match The matched string in the template.\n * @returns The replaced string.\n */\n async function replaceMatchedKeyWithItsValue(match: RegExpMatchArray):\n Promise<string> {\n // Step 1: extract the key from the match\n let key = match[0].replace(/^\\{+/, '').replace(/\\}+$/, '').trim();\n const isOptional = key.endsWith('?');\n if (isOptional) {\n key = key.slice(0, -1);\n }\n\n // Step 2: handle artifact injection\n if (key.startsWith('artifact.')) {\n const fileName = key.substring('artifact.'.length);\n if (invocationContext.artifactService === undefined) {\n throw new Error('Artifact service is not initialized.');\n }\n const artifact = await invocationContext.artifactService.loadArtifact({\n appName: invocationContext.session.appName,\n userId: invocationContext.session.userId,\n sessionId: invocationContext.session.id,\n filename: fileName,\n });\n if (!artifact) {\n throw new Error(`Artifact ${fileName} not found.`);\n }\n return String(artifact);\n }\n\n // Step 3: Handle state variable injection.\n if (!isValidStateName(key)) {\n return match[0];\n }\n\n if (key in invocationContext.session.state) {\n return String(invocationContext.session.state[key]);\n }\n\n if (isOptional) {\n return '';\n }\n\n throw new Error(`Context variable not found: \\`${key}\\`.`);\n }\n // TODO - b/425992518: enable concurrent repalcement with key deduplication.\n const pattern = /\\{+[^{}]*}+/g;\n const result: string[] = [];\n let lastEnd = 0;\n const matches = template.matchAll(pattern);\n\n for (const match of matches) {\n result.push(template.slice(lastEnd, match.index));\n const replacement = await replaceMatchedKeyWithItsValue(match);\n result.push(replacement);\n lastEnd = match.index! + match[0].length;\n }\n result.push(template.slice(lastEnd));\n return result.join('');\n}\n\n\n/**\n * An IIFE that checks if the JavaScript runtime supports Unicode property\n * escapes (`\\p{...}`) in regular expressions and returns a RegExp object that\n * is used for all subsequent calls to isIdentifier().\n */\nconst isIdentifierPattern = (() => {\n return /^[a-zA-Z_][a-zA-Z0-9_]*$/;\n})();\n\n/**\n * Checks if a string is a valid identifier.\n */\nfunction isIdentifier(s: string): boolean {\n if (s === '' || s === undefined) {\n return false;\n }\n\n return isIdentifierPattern.test(s);\n}\n\nconst VALID_PREFIXES = [State.APP_PREFIX, State.USER_PREFIX, State.TEMP_PREFIX];\n/**\n * Checks if a variable name is a valid state name.\n * A valid state name is either:\n * - <identifier>\n * - <prefix>:<identifier>\n *\n * @param variableName The variable name to check.\n * @returns True if the variable name is valid, False otherwise.\n */\nfunction isValidStateName(variableName: string): boolean {\n const parts = variableName.split(':');\n if (parts.length === 0 || parts.length > 2) {\n return false;\n }\n if (parts.length === 1) {\n return isIdentifier(variableName);\n }\n if (VALID_PREFIXES.includes(parts[0] + ':')) {\n return isIdentifier(parts[1]);\n }\n return false;\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {AudioTranscriptionConfig, Modality, ProactivityConfig, RealtimeInputConfig, SpeechConfig} from '@google/genai';\n\nimport {logger} from '../utils/logger.js';\n\n/**\n * The streaming mode for the run config.\n */\nexport enum StreamingMode {\n NONE = 'none',\n SSE = 'sse',\n BIDI = 'bidi',\n}\n\n/**\n * Configs for runtime behavior of agents.\n */\nexport interface RunConfig {\n /**\n * Speech configuration for the live agent.\n */\n speechConfig?: SpeechConfig;\n\n /**\n * The output modalities. If not set, it's default to AUDIO.\n */\n responseModalities?: Modality[];\n\n /**\n * Whether or not to save the input blobs as artifacts.\n */\n saveInputBlobsAsArtifacts?: boolean;\n\n /**\n * Whether to support CFC (Compositional Function Calling). Only applicable\n * for StreamingMode.SSE. If it's true. the LIVE API will be invoked. Since\n * only LIVE API supports CFC\n *\n * WARNING: This feature is **experimental** and its API or behavior may\n * change in future releases.\n */\n supportCfc?: boolean;\n\n /**\n * Streaming mode, None or StreamingMode.SSE or StreamingMode.BIDI.\n */\n streamingMode?: StreamingMode;\n\n /**\n * Output audio transcription config.\n */\n outputAudioTranscription?: AudioTranscriptionConfig;\n\n /**\n * Input transcription for live agents with audio input from user.\n */\n inputAudioTranscription?: AudioTranscriptionConfig;\n\n /**\n * If enabled, the model will detect emotions and adapt its responses\n * accordingly.\n */\n enableAffectiveDialog?: boolean;\n\n /**\n * Configures the proactivity of the model. This allows the model to respond\n * proactively to the input and to ignore irrelevant input.\n */\n proactivity?: ProactivityConfig;\n\n /**\n * Realtime input config for live agents with audio input from user.\n */\n realtimeInputConfig?: RealtimeInputConfig;\n\n /**\n * A limit on the total number of llm calls for a given run.\n *\n * Valid Values:\n * - More than 0 and less than sys.maxsize: The bound on the number of llm\n * calls is enforced, if the value is set in this range.\n * - Less than or equal to 0: This allows for unbounded number of llm calls.\n */\n maxLlmCalls?: number;\n}\n\nexport function createRunConfig(params: Partial<RunConfig> = {}) {\n return {\n saveInputBlobsAsArtifacts: false,\n supportCfc: false,\n enableAffectiveDialog: false,\n streamingMode: StreamingMode.NONE,\n maxLlmCalls: validateMaxLlmCalls(params.maxLlmCalls || 500),\n ...params,\n };\n}\n\nfunction validateMaxLlmCalls(value: number): number {\n if (value > Number.MAX_SAFE_INTEGER) {\n throw new Error(\n `maxLlmCalls should be less than ${Number.MAX_SAFE_INTEGER}.`,\n );\n }\n\n if (value <= 0) {\n logger.warn(\n 'maxLlmCalls is less than or equal to 0. This will result in no enforcement on total number of llm calls that will be made for a run. This may not be ideal, as this could result in a never ending communication between the model and the agent in certain cases.');\n }\n return value;\n}", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Event} from '../events/event.js';\n\nimport {BaseAgent, BaseAgentConfig} from './base_agent.js';\nimport {InvocationContext} from './invocation_context.js';\n\n/**\n * The configuration options for creating a loop agent.\n */\nexport interface LoopAgentConfig extends BaseAgentConfig {\n /**\n * The maximum number of iterations the loop agent will run.\n *\n * If not provided, the loop agent will run indefinitely.\n */\n maxIterations?: number;\n}\n\n/**\n * A shell agent that run its sub-agents in a loop.\n *\n * When sub-agent generates an event with escalate or max_iterations are\n * reached, the loop agent will stop.\n */\nexport class LoopAgent extends BaseAgent {\n private readonly maxIterations: number;\n\n constructor(config: LoopAgentConfig) {\n super(config);\n this.maxIterations = config.maxIterations ?? Number.MAX_SAFE_INTEGER;\n }\n\n protected async *\n runAsyncImpl(\n context: InvocationContext,\n ): AsyncGenerator<Event, void, void> {\n let iteration = 0;\n\n while (iteration < this.maxIterations) {\n for (const subAgent of this.subAgents) {\n let shouldExit = false;\n for await (const event of subAgent.runAsync(context)) {\n yield event;\n\n if (event.actions.escalate) {\n shouldExit = true;\n }\n }\n\n if (shouldExit) {\n return;\n }\n }\n\n iteration++;\n }\n\n return;\n }\n\n protected async *\n runLiveImpl(\n context: InvocationContext,\n ): AsyncGenerator<Event, void, void> {\n throw new Error('This is not supported yet for LoopAgent.');\n }\n}", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Event} from '../events/event.js';\n\nimport {BaseAgent} from './base_agent.js';\nimport {InvocationContext} from './invocation_context.js';\n\n/**\n * A shell agent that run its sub-agents in parallel in isolated manner.\n *\n * This approach is beneficial for scenarios requiring multiple perspectives or\n * attempts on a single task, such as:\n *\n * - Running different algorithms simultaneously.\n * - Generating multiple responses for review by a subsequent evaluation agent.\n */\nexport class ParallelAgent extends BaseAgent {\n protected async *\n runAsyncImpl(\n context: InvocationContext,\n ): AsyncGenerator<Event, void, void> {\n const agentRuns = this.subAgents.map(\n subAgent => subAgent.runAsync(\n createBranchCtxForSubAgent(this, subAgent, context)));\n\n for await (const event of mergeAgentRuns(agentRuns)) {\n yield event;\n }\n }\n\n protected async *\n runLiveImpl(\n context: InvocationContext,\n ): AsyncGenerator<Event, void, void> {\n throw new Error('This is not supported yet for ParallelAgent.');\n }\n}\n\n/**\n * Create isolated branch for every sub-agent.\n */\nfunction createBranchCtxForSubAgent(\n agent: BaseAgent,\n subAgent: BaseAgent,\n originalContext: InvocationContext,\n ): InvocationContext {\n const invocationContext = new InvocationContext(originalContext);\n const branchSuffix = `${agent.name}.${subAgent.name}`;\n invocationContext.branch = invocationContext.branch ?\n `${invocationContext.branch}.${branchSuffix}` :\n branchSuffix;\n\n return invocationContext;\n}\n\n/**\n * Merges the agent run event generator.\n *\n * This implementation guarantees for each agent, it won't move on until the\n * generated event is processed by upstream runner.\n *\n * @param agentRuns A list of async generators that yield events from each\n * agent.\n *\n * @returns A list of async generators that yield events from each agent.\n *\n * @yield The next event from the merged generator.\n */\nasync function*\n mergeAgentRuns(agentRuns: AsyncGenerator<Event, void, void>[]):\n AsyncGenerator<Event, void, void> {\n const pendingPromises = new Map<\n number, Promise<{result: IteratorResult<Event>; index: number}>>();\n\n for (const [index, generator] of agentRuns.entries()) {\n const promise = generator.next().then(result => ({result, index}));\n pendingPromises.set(index, promise);\n }\n\n while (pendingPromises.size > 0) {\n const {result, index} = await Promise.race(pendingPromises.values());\n\n if (result.done) {\n pendingPromises.delete(index);\n continue;\n }\n\n yield result.value;\n\n const nextPromise =\n agentRuns[index].next().then(result => ({result, index}));\n pendingPromises.set(index, nextPromise);\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {Event} from '../events/event.js';\nimport {FunctionTool} from '../tools/function_tool.js';\n\nimport {BaseAgent} from './base_agent.js';\nimport {InvocationContext} from './invocation_context.js';\nimport {LlmAgent} from './llm_agent.js';\nimport {ReadonlyContext} from './readonly_context.js';\n\nconst TASK_COMPLETED_TOOL_NAME = 'task_completed';\n\n/**\n * A shell agent that runs its sub-agents in a sequential order.\n */\nexport class SequentialAgent extends BaseAgent {\n protected async *\n runAsyncImpl(\n context: InvocationContext,\n ): AsyncGenerator<Event, void, void> {\n for (const subAgent of this.subAgents) {\n for await (const event of subAgent.runAsync(context)) {\n yield event;\n }\n }\n }\n\n /**\n * Implementation for live SequentialAgent.\n *\n * Compared to the non-live case, live agents process a continuous stream of\n * audio or video, so there is no way to tell if it's finished and should pass\n * to the next agent or not. So we introduce a task_completed() function so\n * the model can call this function to signal that it's finished the task and\n * we can move on to the next agent.\n *\n * @param context: The invocation context of the agent.\n */\n protected async *\n runLiveImpl(\n context: InvocationContext,\n ): AsyncGenerator<Event, void, void> {\n for (const subAgent of this.subAgents) {\n if (subAgent instanceof LlmAgent) {\n const agentTools =\n await subAgent.canonicalTools(new ReadonlyContext(context));\n const taskCompletedToolAlreadyAdded =\n agentTools.some(tool => tool.name === TASK_COMPLETED_TOOL_NAME);\n\n if (!taskCompletedToolAlreadyAdded) {\n subAgent.tools.push(new FunctionTool({\n name: TASK_COMPLETED_TOOL_NAME,\n description: `Signals that the model has successfully completed the user's question or task.`,\n execute: () => 'Task completion signaled.'\n }));\n subAgent.instruction +=\n `If you finished the user's request according to its description, call the ${\n TASK_COMPLETED_TOOL_NAME} function to exit so the next agents can take over. When calling this function, do not generate any text other than the function call.`;\n }\n }\n }\n\n for (const subAgent of this.subAgents) {\n for await (const event of subAgent.runLive(context)) {\n yield event;\n }\n }\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Part} from '@google/genai';\n\nimport {BaseArtifactService, DeleteArtifactRequest, ListArtifactKeysRequest, ListVersionsRequest, LoadArtifactRequest, SaveArtifactRequest,} from './base_artifact_service.js';\n\n/**\n * An in-memory implementation of the ArtifactService.\n */\nexport class InMemoryArtifactService implements BaseArtifactService {\n private readonly artifacts: Record<string, Part[]> = {};\n\n saveArtifact({\n appName,\n userId,\n sessionId,\n filename,\n artifact,\n }: SaveArtifactRequest): Promise<number> {\n const path = artifactPath(appName, userId, sessionId, filename);\n\n if (!this.artifacts[path]) {\n this.artifacts[path] = [];\n }\n\n const version = this.artifacts[path].length;\n this.artifacts[path].push(artifact);\n\n return Promise.resolve(version);\n }\n\n loadArtifact({\n appName,\n userId,\n sessionId,\n filename,\n version,\n }: LoadArtifactRequest): Promise<Part|undefined> {\n const path = artifactPath(appName, userId, sessionId, filename);\n const versions = this.artifacts[path];\n\n if (!versions) {\n return Promise.resolve(undefined);\n }\n\n if (version === undefined) {\n version = versions.length - 1;\n }\n\n return Promise.resolve(versions[version]);\n }\n\n listArtifactKeys({appName, userId, sessionId}: ListArtifactKeysRequest):\n Promise<string[]> {\n const sessionPrefix = `${appName}/${userId}/${sessionId}/`;\n const usernamespacePrefix = `${appName}/${userId}/user/`;\n const filenames: string[] = [];\n\n for (const path in this.artifacts) {\n if (path.startsWith(sessionPrefix)) {\n const filename = path.replace(sessionPrefix, '');\n filenames.push(filename);\n } else if (path.startsWith(usernamespacePrefix)) {\n const filename = path.replace(usernamespacePrefix, '');\n filenames.push(filename);\n }\n }\n\n return Promise.resolve(filenames.sort());\n }\n\n deleteArtifact({appName, userId, sessionId, filename}: DeleteArtifactRequest):\n Promise<void> {\n const path = artifactPath(appName, userId, sessionId, filename);\n if (!this.artifacts[path]) {\n return Promise.resolve();\n }\n delete this.artifacts[path];\n\n return Promise.resolve();\n }\n\n listVersions({appName, userId, sessionId, filename}: ListVersionsRequest):\n Promise<number[]> {\n const path = artifactPath(appName, userId, sessionId, filename);\n const artifacts = this.artifacts[path];\n\n if (!artifacts) {\n return Promise.resolve([]);\n }\n\n let versions: number[] = [];\n for (let i = 0; i < artifacts.length; i++) {\n versions.push(i);\n }\n\n return Promise.resolve(versions);\n }\n}\n\n/**\n * Constructs the path to the artifact.\n *\n * @param appName The app name.\n * @param userId The user ID.\n * @param sessionId The session ID.\n * @param filename The filename.\n * @return The path to the artifact.\n */\nfunction artifactPath(\n appName: string,\n userId: string,\n sessionId: string,\n filename: string,\n ): string {\n if (fileHasUserNamespace(filename)) {\n return `${appName}/${userId}/user/${filename}`;\n }\n\n return `${appName}/${userId}/${sessionId}/${filename}`;\n}\n\n/**\n * Checks if the filename has a user namespace prefix.\n *\n * @param filename The filename to check.\n * @return true if the filename has a user namespace (starts with \"user:\") false\n * otherwise.\n */\nfunction fileHasUserNamespace(filename: string): boolean {\n return filename.startsWith('user:');\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Event} from '../events/event.js';\nimport {Session} from '../sessions/session.js';\n\nimport {BaseMemoryService, SearchMemoryRequest, SearchMemoryResponse} from './base_memory_service.js';\nimport {MemoryEntry} from './memory_entry.js';\n\n/**\n * An in-memory memory service for prototyping purpose only.\n *\n * Uses keyword matching instead of semantic search.\n */\nexport class InMemoryMemoryService implements BaseMemoryService {\n private readonly memories: MemoryEntry[] = [];\n private readonly sessionEvents:\n {[userKey: string]: {[sessionId: string]: Event[]}} = {};\n\n async addSessionToMemory(session: Session): Promise<void> {\n const userKey = getUserKey(session.appName, session.userId);\n if (!this.sessionEvents[userKey]) {\n this.sessionEvents[userKey] = {};\n }\n this.sessionEvents[userKey][session.id] = session.events.filter(\n (event) => (event.content?.parts?.length ?? 0) > 0);\n }\n\n async searchMemory(req: SearchMemoryRequest): Promise<SearchMemoryResponse> {\n const userKey = getUserKey(req.appName, req.userId);\n if (!this.sessionEvents[userKey]) {\n return Promise.resolve({memories: []});\n }\n\n const wordsInQuery = req.query.toLowerCase().split(/\\s+/);\n const response: SearchMemoryResponse = {memories: []};\n\n for (const sessionEvents of Object.values(this.sessionEvents[userKey])) {\n for (const event of sessionEvents) {\n if (!event.content?.parts?.length) {\n continue;\n }\n\n const joinedText = event.content.parts.map((part) => part.text)\n .filter(text => !!text)\n .join(' ');\n const wordsInEvent = extractWordsLower(joinedText);\n if (!wordsInEvent.size) {\n continue;\n }\n\n const matchQuery =\n wordsInQuery.some(queryWord => wordsInEvent.has(queryWord));\n if (matchQuery) {\n response.memories.push({\n content: event.content,\n author: event.author,\n timestamp: formatTimestamp(event.timestamp),\n });\n }\n }\n }\n\n return response;\n }\n}\n\n/**\n * Constructs the user key from the app name and user ID.\n *\n * @param appName The app name.\n * @param userId The user ID.\n * @return The user key.\n */\nfunction getUserKey(appName: string, userId: string): string {\n return `${appName}/${userId}`;\n}\n\n/**\n * Extracts the words from the text.\n *\n * @param text The text to extract the words from.\n * @return A set of words.\n */\nfunction extractWordsLower(text: string): Set<string> {\n return new Set(\n [...text.matchAll(/[A-Za-z]+/)].map(match => match[0].toLowerCase()));\n}\n\n/**\n * Formats the timestamp to a string in ISO format.\n *\n * @param timestamp The timestamp to format.\n * @return A string representing the timestamp in ISO format.\n */\nfunction formatTimestamp(timestamp: number): string {\n return new Date(timestamp).toISOString();\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Content} from '@google/genai';\n\nimport {BaseAgent} from '../agents/base_agent.js';\nimport {CallbackContext} from '../agents/callback_context.js';\nimport {InvocationContext} from '../agents/invocation_context.js';\nimport {Event} from '../events/event.js';\nimport {LlmRequest} from '../models/llm_request.js';\nimport {LlmResponse} from '../models/llm_response.js';\nimport {BaseTool} from '../tools/base_tool.js';\nimport {ToolContext} from '../tools/tool_context.js';\n\n/**\n * Base class for creating plugins.\n *\n * Plugins provide a structured way to intercept and modify agent, tool, and\n * LLM behaviors at critical execution points in a callback manner. While agent\n * callbacks apply to a particular agent, plugins applies globally to all\n * agents added in the runner. Plugins are best used for adding custom behaviors\n * like logging, monitoring, caching, or modifying requests and responses at key\n * stages.\n *\n * A plugin can implement one or more methods of callbacks, but should not\n * implement the same method of callback for multiple times.\n *\n * Relation with [Agent\n * callbacks](https://google.github.io/adk-docs/callbacks/):\n *\n * **Execution Order**\n * Similar to Agent callbacks, Plugins are executed in the order they are\n * registered. However, Plugin and Agent Callbacks are executed sequentially,\n * with Plugins takes precedence over agent callbacks. When the callback in a\n * plugin returns a value, it will short circuit all remaining plugins and\n * agent callbacks, causing all remaining plugins and agent callbacks\n * to be skipped.\n *\n * **Change Propagation**\n * Plugins and agent callbacks can both modify the value of the input\n * parameters, including agent input, tool input, and LLM request/response, etc.\n * They work in the exactly same way. The modifications will be visible and\n * passed to the next callback in the chain. For example, if a plugin modifies\n * the tool input with before_tool_callback, the modified tool input will be\n * passed to the before_tool_callback of the next plugin, and further passed to\n * the agent callbacks if not short circuited.\n *\n * To use a plugin, implement the desired callback methods and pass an instance\n * of your custom plugin class to the ADK Runner.\n *\n * Example:\n * A simple plugin that logs every tool call.\n * ```typescript\n * class ToolLoggerPlugin extends BasePlugin {\n * constructor() {\n * super('tool_logger');\n * }\n *\n * override async beforeToolCallback(\n * {tool, toolArgs, toolContext}: {\n * tool: BaseTool,\n * toolArgs: Record<string, unknown>,\n * toolContext: ToolContext,\n * },\n * ): Promise<Record<string, unknown> | undefined> {\n * this.logger.info(\n * `[${this.name}] Calling tool '${tool.name}' with args:\n * ${JSON.stringify( toolArgs,\n * )}`,\n * );\n * return;\n * }\n *\n * override async afterToolCallback(\n * {tool, toolArgs, toolContext, result}: {\n * tool: BaseTool,\n * toolArgs: Record<string, unknown>,\n * toolContext: ToolContext,\n * result: Record<string, unknown>,\n * },\n * ): Promise<Record<string, unknown> | undefined> {\n * this.logger.info(\n * `[${this.name}] Tool '${tool.name}' finished with result:\n * ${JSON.stringify( result,\n * )}`,\n * );\n * return;\n * }\n * }\n *\n * // Add the plugin to ADK Runner\n * // runner = new Runner({\n * // ...\n * // plugins: [new ToolLoggerPlugin(), new AgentPolicyPlugin()],\n * // });\n * ```\n */\nexport abstract class BasePlugin {\n readonly name: string;\n\n /**\n * Initializes the plugin.\n *\n * @param name A unique identifier for this plugin instance.\n */\n constructor(name: string) {\n this.name = name;\n }\n\n /**\n * Callback executed when a user message is received before an invocation\n * starts.\n *\n * This callback helps logging and modifying the user message before the\n * runner starts the invocation.\n *\n * @param invocationContext The context for the entire invocation.\n * @param userMessage The message content input by user.\n * @returns An optional `Content` to be returned to the ADK. Returning a\n * value to replace the user message. Returning `undefined` to proceed\n * normally.\n */\n async onUserMessageCallback({invocationContext, userMessage}: {\n invocationContext: InvocationContext; userMessage: Content;\n }): Promise<Content|undefined> {\n return;\n }\n\n /**\n * Callback executed before the ADK runner runs.\n *\n * This is the first callback to be called in the lifecycle, ideal for global\n * setup or initialization tasks.\n *\n * @param invocationContext The context for the entire invocation, containing\n * session information, the root agent, etc.\n * @returns An optional `Event` to be returned to the ADK. Returning a value\n * to halt execution of the runner and ends the runner with that event.\n * Return `undefined` to proceed normally.\n */\n async beforeRunCallback({invocationContext}: {\n invocationContext: InvocationContext;\n }): Promise<Content|undefined> {\n return;\n }\n\n /**\n * Callback executed after an event is yielded from runner.\n *\n * This is the ideal place to make modification to the event before the event\n * is handled by the underlying agent app.\n *\n * @param invocationContext The context for the entire invocation.\n * @param event The event raised by the runner.\n * @returns An optional value. A non-`undefined` return may be used by the\n * framework to modify or replace the response. Returning `undefined`\n * allows the original response to be used.\n */\n async onEventCallback({invocationContext, event}: {\n invocationContext: InvocationContext; event: Event;\n }): Promise<Event|undefined> {\n return;\n }\n\n /**\n * Callback executed after an ADK runner run has completed.\n *\n * This is the final callback in the ADK lifecycle, suitable for cleanup,\n * final logging, or reporting tasks.\n *\n * @param invocationContext The context for the entire invocation.\n * @returns undefined\n */\n async afterRunCallback({invocationContext}: {\n invocationContext: InvocationContext;\n }): Promise<void> {\n return;\n }\n\n /**\n * Callback executed before an agent's primary logic is invoked.\n *\n * This callback can be used for logging, setup, or to short-circuit the\n * agent's execution by returning a value.\n *\n * @param agent The agent that is about to run.\n * @param callbackContext The context for the agent invocation.\n * @returns An optional `Content` object. If a value is returned, it will\n * bypass the agent's callbacks and its execution, and return this value\n * directly. Returning `undefined` allows the agent to proceed normally.\n */\n async beforeAgentCallback({agent, callbackContext}: {\n agent: BaseAgent; callbackContext: CallbackContext;\n }): Promise<Content|undefined> {\n return;\n }\n\n /**\n * Callback executed after an agent's primary logic has completed.\n *\n * This callback can be used to inspect, log, or modify the agent's final\n * result before it is returned.\n *\n * @param agent The agent that has just run.\n * @param callbackContext The context for the agent invocation.\n * @returns An optional `Content` object. If a value is returned, it will\n * replace the agent's original result. Returning `undefined` uses the\n * original, unmodified result.\n */\n async afterAgentCallback({agent, callbackContext}: {\n agent: BaseAgent; callbackContext: CallbackContext;\n }): Promise<Content|undefined> {\n return;\n }\n\n /**\n * Callback executed before a request is sent to the model.\n *\n * This provides an opportunity to inspect, log, or modify the `LlmRequest`\n * object. It can also be used to implement caching by returning a cached\n * `LlmResponse`, which would skip the actual model call.\n *\n * @param callbackContext The context for the current agent call.\n * @param llmRequest The prepared request object to be sent to the model.\n * @returns An optional value. The interpretation of a non-`undefined`\n * trigger an early exit and returns the response immediately. Returning\n * `undefined` allows the LLM request to proceed normally.\n */\n async beforeModelCallback({callbackContext, llmRequest}: {\n callbackContext: CallbackContext; llmRequest: LlmRequest;\n }): Promise<LlmResponse|undefined> {\n return;\n }\n\n /**\n * Callback executed after a response is received from the model.\n *\n * This is the ideal place to log model responses, collect metrics on token\n * usage, or perform post-processing on the raw `LlmResponse`.\n *\n * @param callbackContext The context for the current agent call.\n * @param llmResponse The response object received from the model.\n * @returns An optional value. A non-`undefined` return may be used by the\n * framework to modify or replace the response. Returning `undefined`\n * allows the original response to be used.\n */\n async afterModelCallback({callbackContext, llmResponse}: {\n callbackContext: CallbackContext; llmResponse: LlmResponse;\n }): Promise<LlmResponse|undefined> {\n return;\n }\n\n /**\n * Callback executed when a model call encounters an error.\n *\n * This callback provides an opportunity to handle model errors gracefully,\n * potentially providing alternative responses or recovery mechanisms.\n *\n * @param callbackContext The context for the current agent call.\n * @param llmRequest The request that was sent to the model when the error\n * occurred.\n * @param error The exception that was raised during model execution.\n * @returns An optional LlmResponse. If an LlmResponse is returned, it will be\n * used instead of propagating the error. Returning `undefined` allows\n * the original error to be raised.\n */\n async onModelErrorCallback({callbackContext, llmRequest, error}: {\n callbackContext: CallbackContext; llmRequest: LlmRequest; error: Error;\n }): Promise<LlmResponse|undefined> {\n return;\n }\n\n /**\n * Callback executed before a tool is called.\n *\n * This callback is useful for logging tool usage, input validation, or\n * modifying the arguments before they are passed to the tool.\n *\n * @param tool The tool instance that is about to be executed.\n * @param toolArgs The dictionary of arguments to be used for invoking the\n * tool.\n * @param toolContext The context specific to the tool execution.\n * @returns An optional dictionary. If a dictionary is returned, it will stop\n * the tool execution and return this response immediately. Returning\n * `undefined` uses the original, unmodified arguments.\n */\n async beforeToolCallback({tool, toolArgs, toolContext}: {\n tool: BaseTool; toolArgs: Record<string, unknown>; toolContext: ToolContext;\n }): Promise<Record<string, unknown>|undefined> {\n return;\n }\n\n /**\n * Callback executed after a tool has been called.\n *\n * This callback allows for inspecting, logging, or modifying the result\n * returned by a tool.\n *\n * @param tool The tool instance that has just been executed.\n * @param toolArgs The original arguments that were passed to the tool.\n * @param toolContext The context specific to the tool execution.\n * @param result The dictionary returned by the tool invocation.\n * @returns An optional dictionary. If a dictionary is returned, it will\n * **replace** the original result from the tool. This allows for\n * post-processing or altering tool outputs. Returning `undefined` uses\n * the original, unmodified result.\n */\n async afterToolCallback({tool, toolArgs, toolContext, result}: {\n tool: BaseTool; toolArgs: Record<string, unknown>; toolContext: ToolContext;\n result: Record<string, unknown>;\n }): Promise<Record<string, unknown>|undefined> {\n return;\n }\n\n /**\n * Callback executed when a tool call encounters an error.\n *\n * This callback provides an opportunity to handle tool errors gracefully,\n * potentially providing alternative responses or recovery mechanisms.\n *\n * @param tool The tool instance that encountered an error.\n * @param toolArgs The arguments that were passed to the tool.\n * @param toolContext The context specific to the tool execution.\n * @param error The exception that was raised during tool execution.\n * @returns An optional dictionary. If a dictionary is returned, it will be\n * used as the tool response instead of propagating the error. Returning\n * `undefined` allows the original error to be raised.\n */\n async onToolErrorCallback({tool, toolArgs, toolContext, error}: {\n tool: BaseTool; toolArgs: Record<string, unknown>; toolContext: ToolContext;\n error: Error;\n }): Promise<Record<string, unknown>|undefined> {\n return;\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Content} from '@google/genai';\n\nimport {BaseAgent} from '../agents/base_agent.js';\nimport {CallbackContext} from '../agents/callback_context.js';\nimport {InvocationContext} from '../agents/invocation_context.js';\nimport {Event, getFunctionCalls, getFunctionResponses, isFinalResponse} from '../events/event.js';\nimport {LlmRequest} from '../models/llm_request.js';\nimport {LlmResponse} from '../models/llm_response.js';\nimport {BaseTool} from '../tools/base_tool.js';\nimport {ToolContext} from '../tools/tool_context.js';\nimport {logger} from '../utils/logger.js';\n\nimport {BasePlugin} from './base_plugin.js';\n\n/**\n * A plugin that logs important information at each callback point.\n *\n * This plugin helps printing all critical events in the console. It is not a\n * replacement of existing logging in ADK. It rather helps terminal based\n * debugging by showing all logs in the console, and serves as a simple demo for\n * everyone to leverage when developing new plugins.\n *\n * This plugin helps users track the invocation status by logging:\n * - User messages and invocation context\n * - Agent execution flow\n * - LLM requests and responses\n * - Tool calls with arguments and results\n * - Events and final responses\n * - Errors during model and tool execution\n *\n * Example:\n * ```typescript\n * const loggingPlugin = new LoggingPlugin();\n * const runner = new Runner({\n * agents: [myAgent],\n * // ...\n * plugins: [loggingPlugin],\n * });\n * ```\n */\nexport class LoggingPlugin extends BasePlugin {\n /**\n * Initialize the logging plugin.\n *\n * @param name The name of the plugin instance.\n */\n constructor(name = 'logging_plugin') {\n super(name);\n }\n\n override async onUserMessageCallback(\n {invocationContext, userMessage}:\n {invocationContext: InvocationContext; userMessage: Content;},\n ): Promise<Content|undefined> {\n this.log('\uD83D\uDE80 USER MESSAGE RECEIVED');\n this.log(` Invocation ID: ${invocationContext.invocationId}`);\n this.log(` Session ID: ${invocationContext.session.id}`);\n this.log(` User ID: ${invocationContext.userId}`);\n this.log(` App Name: ${invocationContext.appName}`);\n this.log(` Root Agent: ${invocationContext.agent.name ?? 'Unknown'}`);\n this.log(` User Content: ${this.formatContent(userMessage)}`);\n if (invocationContext.branch) {\n this.log(` Branch: ${invocationContext.branch}`);\n }\n return undefined;\n }\n\n override async beforeRunCallback({invocationContext}: {\n invocationContext: InvocationContext;\n }): Promise<Content|undefined> {\n this.log('\uD83C\uDFC3 INVOCATION STARTING');\n this.log(` Invocation ID: ${invocationContext.invocationId}`);\n this.log(` Starting Agent: ${invocationContext.agent.name ?? 'Unknown'}`);\n return undefined;\n }\n\n override async onEventCallback({invocationContext, event}: {\n invocationContext: InvocationContext; event: Event;\n }): Promise<Event|undefined> {\n this.log('\uD83D\uDCE2 EVENT YIELDED');\n this.log(` Event ID: ${event.id}`);\n this.log(` Author: ${event.author}`);\n this.log(` Content: ${this.formatContent(event.content)}`);\n this.log(` Final Response: ${isFinalResponse(event)}`);\n\n const functionCalls = getFunctionCalls(event);\n if (functionCalls.length > 0) {\n const funcCalls = functionCalls.map((fc) => fc.name);\n this.log(` Function Calls: ${funcCalls}`);\n }\n\n const functionResponses = getFunctionResponses(event);\n if (functionResponses.length > 0) {\n const funcResponses = functionResponses.map((fr) => fr.name);\n this.log(` Function Responses: ${funcResponses}`);\n }\n\n if (event.longRunningToolIds && event.longRunningToolIds.length > 0) {\n this.log(` Long Running Tools: ${[...event.longRunningToolIds]}`);\n }\n\n return undefined;\n }\n\n override async afterRunCallback({invocationContext}: {\n invocationContext: InvocationContext;\n }): Promise<void> {\n this.log('\u2705 INVOCATION COMPLETED');\n this.log(` Invocation ID: ${invocationContext.invocationId}`);\n this.log(` Final Agent: ${invocationContext.agent.name ?? 'Unknown'}`);\n return undefined;\n }\n\n override async beforeAgentCallback({agent, callbackContext}: {\n agent: BaseAgent; callbackContext: CallbackContext;\n }): Promise<Content|undefined> {\n this.log('\uD83E\uDD16 AGENT STARTING');\n this.log(` Agent Name: ${callbackContext.agentName}`);\n this.log(` Invocation ID: ${callbackContext.invocationId}`);\n if (callbackContext.invocationContext.branch) {\n this.log(` Branch: ${callbackContext.invocationContext.branch}`);\n }\n return undefined;\n }\n\n override async afterAgentCallback({agent, callbackContext}: {\n agent: BaseAgent; callbackContext: CallbackContext;\n }): Promise<Content|undefined> {\n this.log('\uD83E\uDD16 AGENT COMPLETED');\n this.log(` Agent Name: ${callbackContext.agentName}`);\n this.log(` Invocation ID: ${callbackContext.invocationId}`);\n return undefined;\n }\n\n override async beforeModelCallback({callbackContext, llmRequest}: {\n callbackContext: CallbackContext; llmRequest: LlmRequest;\n }): Promise<LlmResponse|undefined> {\n this.log('\uD83E\uDDE0 LLM REQUEST');\n this.log(` Model: ${llmRequest.model ?? 'default'}`);\n this.log(` Agent: ${callbackContext.agentName}`);\n\n if (llmRequest.config && llmRequest.config.systemInstruction) {\n let sysInstruction = llmRequest.config.systemInstruction as string;\n if (sysInstruction.length > 200) {\n sysInstruction = sysInstruction.substring(0, 200) + '...';\n }\n this.log(` System Instruction: '${sysInstruction}'`);\n }\n\n if (llmRequest.toolsDict) {\n const toolNames = Object.keys(llmRequest.toolsDict);\n this.log(` Available Tools: ${toolNames}`);\n }\n\n return undefined;\n }\n\n override async afterModelCallback({callbackContext, llmResponse}: {\n callbackContext: CallbackContext; llmResponse: LlmResponse;\n }): Promise<LlmResponse|undefined> {\n this.log('\uD83E\uDDE0 LLM RESPONSE');\n this.log(` Agent: ${callbackContext.agentName}`);\n\n if (llmResponse.errorCode) {\n this.log(` \u274C ERROR - Code: ${llmResponse.errorCode}`);\n this.log(` Error Message: ${llmResponse.errorMessage}`);\n } else {\n this.log(` Content: ${this.formatContent(llmResponse.content)}`);\n if (llmResponse.partial) {\n this.log(` Partial: ${llmResponse.partial}`);\n }\n if (llmResponse.turnComplete !== undefined) {\n this.log(` Turn Complete: ${llmResponse.turnComplete}`);\n }\n }\n\n if (llmResponse.usageMetadata) {\n this.log(` Token Usage - Input: ${\n llmResponse.usageMetadata.promptTokenCount}, Output: ${\n llmResponse.usageMetadata.candidatesTokenCount}`);\n }\n\n return undefined;\n }\n\n override async beforeToolCallback({tool, toolArgs, toolContext}: {\n tool: BaseTool; toolArgs: Record<string, unknown>; toolContext: ToolContext;\n }): Promise<Record<string, unknown>|undefined> {\n this.log('\uD83D\uDD27 TOOL STARTING');\n this.log(` Tool Name: ${tool.name}`);\n this.log(` Agent: ${toolContext.agentName}`);\n this.log(` Function Call ID: ${toolContext.functionCallId}`);\n this.log(` Arguments: ${this.formatArgs(toolArgs)}`);\n return undefined;\n }\n\n override async afterToolCallback({tool, toolArgs, toolContext, result}: {\n tool: BaseTool; toolArgs: Record<string, unknown>; toolContext: ToolContext;\n result: Record<string, unknown>;\n }): Promise<Record<string, unknown>|undefined> {\n this.log('\uD83D\uDD27 TOOL COMPLETED');\n this.log(` Tool Name: ${tool.name}`);\n this.log(` Agent: ${toolContext.agentName}`);\n this.log(` Function Call ID: ${toolContext.functionCallId}`);\n this.log(` Result: ${this.formatArgs(result)}`);\n return undefined;\n }\n\n override async onModelErrorCallback({callbackContext, llmRequest, error}: {\n callbackContext: CallbackContext; llmRequest: LlmRequest; error: Error;\n }): Promise<LlmResponse|undefined> {\n this.log('\uD83E\uDDE0 LLM ERROR');\n this.log(` Agent: ${callbackContext.agentName}`);\n this.log(` Error: ${error}`);\n\n return undefined;\n }\n\n override async onToolErrorCallback({tool, toolArgs, toolContext, error}: {\n tool: BaseTool; toolArgs: Record<string, unknown>; toolContext: ToolContext;\n error: Error;\n }): Promise<Record<string, unknown>|undefined> {\n this.log('\uD83D\uDD27 TOOL ERROR');\n this.log(` Tool Name: ${tool.name}`);\n this.log(` Agent: ${toolContext.agentName}`);\n this.log(` Function Call ID: ${toolContext.functionCallId}`);\n this.log(` Arguments: ${this.formatArgs(toolArgs)}`);\n this.log(` Error: ${error}`);\n return undefined;\n }\n\n private log(message: string): void {\n const formattedMessage = `\\u001b[90m[${this.name}] ${message}\\u001b[0m`;\n logger.info(formattedMessage);\n }\n\n private formatContent(content?: Content, maxLength = 200): string {\n if (!content || !content.parts) {\n return 'None';\n }\n\n const parts: string[] = [];\n for (const part of content.parts) {\n if (part.text) {\n let text = part.text.trim();\n if (text.length > maxLength) {\n text = text.substring(0, maxLength) + '...';\n }\n parts.push(`text: '${text}'`);\n } else if (part.functionCall) {\n parts.push(`function_call: ${part.functionCall.name}`);\n } else if (part.functionResponse) {\n parts.push(`function_response: ${part.functionResponse.name}`);\n } else if (part.codeExecutionResult) {\n parts.push('code_execution_result');\n } else {\n parts.push('other_part');\n }\n }\n\n return parts.join(' | ');\n }\n\n private formatArgs(args: Record<string, unknown>, maxLength = 300): string {\n if (!args) {\n return '{}';\n }\n\n let formatted = JSON.stringify(args);\n if (formatted.length > maxLength) {\n formatted = formatted.substring(0, maxLength) + '...}';\n }\n return formatted;\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Content} from '@google/genai';\n\nimport {BaseAgent} from '../agents/base_agent.js';\nimport {CallbackContext} from '../agents/callback_context.js';\nimport {InvocationContext} from '../agents/invocation_context.js';\nimport {Event} from '../events/event.js';\nimport {LlmRequest} from '../models/llm_request.js';\nimport {LlmResponse} from '../models/llm_response.js';\nimport {BaseTool} from '../tools/base_tool.js';\nimport {ToolContext} from '../tools/tool_context.js';\nimport {logger} from '../utils/logger.js';\n\nimport {BasePlugin} from './base_plugin.js';\n\n/**\n * Manages the registration and execution of plugins.\n *\n * The PluginManager is an internal class that orchestrates the invocation of\n * plugin callbacks at key points in the SDK's execution lifecycle. It maintains\n * a list of registered plugins and ensures they are called in the order they\n * were registered.\n *\n * The core execution logic implements an \"early exit\" strategy: if any plugin\n * callback returns a non-`undefined` value, the execution of subsequent plugins\n * for that specific event is halted, and the returned value is propagated up\n * the call stack. This allows plugins to short-circuit operations like agent\n * runs, tool calls, or model requests.\n */\nexport class PluginManager {\n private readonly plugins: Set<BasePlugin> = new Set();\n /**\n * Initializes the plugin service.\n *\n * @param plugins An optional list of plugins to register upon\n * initialization.\n */\n constructor(plugins?: BasePlugin[]) {\n if (plugins) {\n for (const plugin of plugins) {\n this.registerPlugin(plugin);\n }\n }\n }\n\n /**\n * Registers a new plugin.\n *\n * @param plugin The plugin instance to register.\n * @throws If the same exact plugin or a plugin with the same name is already\n * registered.\n */\n registerPlugin(plugin: BasePlugin): void {\n // Short circuit for duplicate objects or duplicate names\n if (this.plugins.has(plugin)) {\n throw new Error(`Plugin '${plugin.name}' already registered.`);\n }\n if (Array.from(this.plugins).some(p => p.name === plugin.name)) {\n throw new Error(`Plugin with name '${plugin.name}' already registered.`);\n }\n\n this.plugins.add(plugin);\n\n logger.info(`Plugin '${plugin.name}' registered.`);\n }\n\n /**\n * Retrieves a registered plugin by its name.\n *\n * @param pluginName The name of the plugin to retrieve.\n * @returns The plugin instance if found, otherwise `undefined`.\n */\n getPlugin(pluginName: string): BasePlugin|undefined {\n // Set operates on strict equality, we only want to match by name\n return Array.from(this.plugins).find(p => p.name === pluginName);\n }\n\n /**\n * Runs the same callback for all plugins. This is a utility method to reduce\n * duplication below.\n *\n * @param plugins The set of plugins to run\n * @param callback A closure containing the callback method to run on each\n * plugin\n * @param callbackName The name of the function being called in the closure\n * above. Used for logging purposes.\n * @returns A promise containing the plugin method result. Must be casted to\n * the proper type for the plugin method.\n */\n private async runCallbacks(\n plugins: Set<BasePlugin>,\n callback: (plugin: BasePlugin) => Promise<unknown>,\n callbackName: string,\n ): Promise<unknown> {\n for (const plugin of plugins) {\n try {\n const result = await callback(plugin);\n if (result !== undefined) {\n logger.debug(\n `Plugin '${plugin.name}' returned a value for callback '${\n callbackName}', exiting early.`);\n return result;\n }\n } catch (e) {\n const errorMessage = `Error in plugin '${\n plugin.name}' during '${callbackName}' callback: ${e}`;\n logger.error(errorMessage);\n throw new Error(errorMessage);\n }\n }\n return undefined;\n }\n\n /**\n * Runs the `onUserMessageCallback` for all plugins.\n */\n async runOnUserMessageCallback(\n {userMessage, invocationContext}:\n {userMessage: Content; invocationContext: InvocationContext;},\n ): Promise<Content|undefined> {\n return await this.runCallbacks(\n this.plugins,\n (plugin: BasePlugin) => plugin.onUserMessageCallback(\n {userMessage, invocationContext}),\n 'onUserMessageCallback',\n ) as Content |\n undefined;\n }\n\n /**\n * Runs the `beforeRunCallback` for all plugins.\n */\n async runBeforeRunCallback({invocationContext}: {\n invocationContext: InvocationContext;\n }): Promise<Content|undefined> {\n return (await this.runCallbacks(\n this.plugins,\n (plugin: BasePlugin) =>\n plugin.beforeRunCallback({invocationContext}),\n 'beforeRunCallback',\n )) as Content |\n undefined;\n }\n\n /**\n * Runs the `afterRunCallback` for all plugins.\n */\n async runAfterRunCallback({invocationContext}: {\n invocationContext: InvocationContext;\n }): Promise<void> {\n await this.runCallbacks(\n this.plugins,\n (plugin: BasePlugin) => plugin.afterRunCallback({invocationContext}),\n 'afterRunCallback',\n );\n }\n\n /**\n * Runs the `onEventCallback` for all plugins.\n */\n async runOnEventCallback({invocationContext, event}: {\n invocationContext: InvocationContext; event: Event;\n }): Promise<Event|undefined> {\n return (await this.runCallbacks(\n this.plugins,\n (plugin: BasePlugin) =>\n plugin.onEventCallback({invocationContext, event}),\n 'onEventCallback',\n )) as Event |\n undefined;\n }\n\n /**\n * Runs the `beforeAgentCallback` for all plugins.\n */\n async runBeforeAgentCallback({agent, callbackContext}: {\n agent: BaseAgent; callbackContext: CallbackContext;\n }): Promise<Content|undefined> {\n return (await this.runCallbacks(\n this.plugins,\n (plugin: BasePlugin) =>\n plugin.beforeAgentCallback({agent, callbackContext}),\n 'beforeAgentCallback',\n )) as Content |\n undefined;\n }\n\n /**\n * Runs the `afterAgentCallback` for all plugins.\n */\n async runAfterAgentCallback({agent, callbackContext}: {\n agent: BaseAgent; callbackContext: CallbackContext;\n }): Promise<Content|undefined> {\n return (await this.runCallbacks(\n this.plugins,\n (plugin: BasePlugin) =>\n plugin.afterAgentCallback({agent, callbackContext}),\n 'afterAgentCallback',\n )) as Content |\n undefined;\n }\n\n /**\n * Runs the `beforeToolCallback` for all plugins.\n */\n async runBeforeToolCallback({tool, toolArgs, toolContext}: {\n tool: BaseTool; toolArgs: Record<string, unknown>; toolContext: ToolContext;\n }): Promise<Record<string, unknown>|undefined> {\n return (await this.runCallbacks(\n this.plugins,\n (plugin: BasePlugin) =>\n plugin.beforeToolCallback({tool, toolArgs, toolContext}),\n 'beforeToolCallback',\n )) as Record<string, unknown>|\n undefined;\n }\n\n /**\n * Runs the `afterToolCallback` for all plugins.\n */\n async runAfterToolCallback({tool, toolArgs, toolContext, result}: {\n tool: BaseTool; toolArgs: Record<string, unknown>; toolContext: ToolContext;\n result: Record<string, unknown>;\n }): Promise<Record<string, unknown>|undefined> {\n return (await this.runCallbacks(\n this.plugins,\n (plugin: BasePlugin) => plugin.afterToolCallback(\n {tool, toolArgs, toolContext, result}),\n 'afterToolCallback',\n )) as Record<string, unknown>|\n undefined;\n }\n\n /**\n * Runs the `onModelErrorCallback` for all plugins.\n */\n async runOnModelErrorCallback({callbackContext, llmRequest, error}: {\n callbackContext: CallbackContext; llmRequest: LlmRequest; error: Error;\n }): Promise<LlmResponse|undefined> {\n return (await this.runCallbacks(\n this.plugins,\n (plugin: BasePlugin) => plugin.onModelErrorCallback(\n {callbackContext, llmRequest, error}),\n 'onModelErrorCallback',\n )) as LlmResponse |\n undefined;\n }\n\n /**\n * Runs the `beforeModelCallback` for all plugins.\n */\n async runBeforeModelCallback({callbackContext, llmRequest}: {\n callbackContext: CallbackContext; llmRequest: LlmRequest;\n }): Promise<LlmResponse|undefined> {\n return (await this.runCallbacks(\n this.plugins,\n (plugin: BasePlugin) =>\n plugin.beforeModelCallback({callbackContext, llmRequest}),\n 'beforeModelCallback',\n )) as LlmResponse |\n undefined;\n }\n\n /**\n * Runs the `afterModelCallback` for all plugins.\n */\n async runAfterModelCallback({callbackContext, llmResponse}: {\n callbackContext: CallbackContext; llmResponse: LlmResponse;\n }): Promise<LlmResponse|undefined> {\n return (await this.runCallbacks(\n this.plugins,\n (plugin: BasePlugin) =>\n plugin.afterModelCallback({callbackContext, llmResponse}),\n 'afterModelCallback',\n )) as LlmResponse |\n undefined;\n }\n\n /**\n * Runs the `onToolErrorCallback` for all plugins.\n */\n async runOnToolErrorCallback({tool, toolArgs, toolContext, error}: {\n tool: BaseTool; toolArgs: Record<string, unknown>; toolContext: ToolContext;\n error: Error;\n }): Promise<Record<string, unknown>|undefined> {\n return (await this.runCallbacks(\n this.plugins,\n (plugin: BasePlugin) => plugin.onToolErrorCallback(\n {tool, toolArgs, toolContext, error}),\n 'onToolErrorCallback',\n )) as Record<string, unknown>|\n undefined;\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Content, FunctionCall, FunctionResponse} from '@google/genai';\n\nimport {Event} from '../events/event.js';\nimport {BasePlugin} from '../plugins/base_plugin.js';\nimport {BaseTool} from '../tools/base_tool.js';\nimport {ToolConfirmation} from '../tools/tool_confirmation.js';\nimport {ToolContext} from '../tools/tool_context.js';\n\n// Constants\nexport const REQUEST_CONFIRMATION_FUNCTION_CALL_NAME =\n 'adk_request_confirmation';\n\nconst TOOL_CALL_SECURITY_CHECK_STATES = 'orcas_tool_call_security_check_states';\nconst INTERMEDIATE_REQUIRE_TOOL_CALL_CONFIRMATION_ERROR =\n 'This tool call needs external confirmation before completion.';\n\n// --------------------------------------------------------------------------\n// #START Policy Engine Interface\n// --------------------------------------------------------------------------\n\n/**\n * The outcome of a policy check.\n */\nexport enum PolicyOutcome {\n // The tool call is rejected by the policy engine.\n DENY = 'DENY',\n // The tool call needs external confirmation before proceeding.\n CONFIRM = 'CONFIRM',\n // The tool call is allowed by the policy engine.\n ALLOW = 'ALLOW',\n}\n\nexport interface PolicyCheckResult {\n outcome: string;\n reason?: string;\n}\n\nexport interface ToolCallPolicyContext {\n tool: BaseTool;\n toolArgs: Record<string, unknown>;\n}\n\nexport interface BasePolicyEngine {\n evaluate(context: ToolCallPolicyContext): Promise<PolicyCheckResult>;\n}\n\nexport class InMemoryPolicyEngine implements BasePolicyEngine {\n async evaluate(context: ToolCallPolicyContext): Promise<PolicyCheckResult> {\n // Default permissive implementation\n return Promise.resolve({\n outcome: PolicyOutcome.ALLOW,\n reason: 'For prototyping purpose, all tool calls are allowed.',\n });\n }\n}\n// --------------------------------------------------------------------------\n// #END Policy Engine Interface\n// --------------------------------------------------------------------------\n\n/**\n * Security Plugin for running Orcas agents.\n */\nexport class SecurityPlugin extends BasePlugin {\n private readonly policyEngine: BasePolicyEngine;\n\n constructor(params?: {policyEngine?: BasePolicyEngine;}) {\n super('security_plugin');\n this.policyEngine = params?.policyEngine ?? new InMemoryPolicyEngine();\n }\n\n override async beforeToolCallback({\n tool,\n toolArgs,\n toolContext,\n }: {\n tool: BaseTool,\n toolArgs: {[key: string]: unknown},\n toolContext: ToolContext\n }): Promise<{[key: string]: unknown}|undefined> {\n const toolCallCheckState = this.getToolCallCheckState(toolContext);\n\n // We only check the tool call policy ONCE, when the tool call is handled\n // for the first time.\n if (!toolCallCheckState) {\n return this.checkToolCallPolicy({\n tool: tool,\n toolArgs: toolArgs,\n toolContext: toolContext,\n });\n }\n\n if (toolCallCheckState !== PolicyOutcome.CONFIRM) {\n return;\n }\n\n if (!toolContext.toolConfirmation) {\n return {partial: INTERMEDIATE_REQUIRE_TOOL_CALL_CONFIRMATION_ERROR};\n }\n\n this.setToolCallCheckState(toolContext, toolContext.toolConfirmation);\n if (!toolContext.toolConfirmation.confirmed) {\n return {\n error: 'Tool call rejected from confirmation flow.',\n };\n }\n toolContext.toolConfirmation = undefined;\n return;\n }\n\n private getToolCallCheckState(toolContext: ToolContext): string\n |ToolConfirmation|undefined {\n const {functionCallId} = toolContext;\n if (!functionCallId) {\n return;\n }\n\n const toolCallStates =\n (toolContext.state.get(TOOL_CALL_SECURITY_CHECK_STATES) as\n {[key: string]: string | ToolConfirmation}) ??\n {};\n return toolCallStates[functionCallId];\n }\n\n private setToolCallCheckState(\n toolContext: ToolContext, state: string|ToolConfirmation): void {\n const {functionCallId} = toolContext;\n if (!functionCallId) {\n return;\n }\n\n const toolCallStates =\n (toolContext.state.get(TOOL_CALL_SECURITY_CHECK_STATES) as\n {[key: string]: string | ToolConfirmation}) ??\n {};\n toolCallStates[functionCallId] = state;\n toolContext.state.set(TOOL_CALL_SECURITY_CHECK_STATES, toolCallStates);\n }\n\n private async checkToolCallPolicy({\n tool,\n toolArgs,\n toolContext,\n }: {\n tool: BaseTool,\n toolArgs: {[key: string]: any},\n toolContext: ToolContext\n }): Promise<{[key: string]: unknown}|undefined> {\n const policyCheckResult =\n await this.policyEngine.evaluate({tool, toolArgs});\n\n this.setToolCallCheckState(toolContext, policyCheckResult.outcome);\n\n switch (policyCheckResult.outcome) {\n case PolicyOutcome.DENY:\n return {\n error: `This tool call is rejected by policy engine. Reason: ${\n policyCheckResult.reason}`,\n };\n case PolicyOutcome.CONFIRM:\n toolContext.requestConfirmation({\n hint: `Policy engine requires confirmation calling tool: ${\n tool.name}. Reason: ${policyCheckResult.reason}`,\n });\n return {partial: INTERMEDIATE_REQUIRE_TOOL_CALL_CONFIRMATION_ERROR};\n case PolicyOutcome.ALLOW:\n return;\n default:\n return;\n }\n }\n}\n\n\n/**\n * Gets the ask user confirmation function calls from the event.\n * @param event The event to get the function calls from.\n * @returns The ask user confirmation function calls.\n */\nexport function getAskUserConfirmationFunctionCalls(event: Event):\n FunctionCall[] {\n if (!event.content || !event.content.parts) {\n return [];\n }\n const results: FunctionCall[] = [];\n\n for (const part of event.content.parts) {\n if (part && part.functionCall &&\n part.functionCall.name === REQUEST_CONFIRMATION_FUNCTION_CALL_NAME) {\n results.push(part.functionCall);\n }\n }\n return results;\n}", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Event} from '../events/event.js';\n\nimport {Session} from './session.js';\nimport {State} from './state.js';\n\n/**\n * The configuration of getting a session.\n */\nexport interface GetSessionConfig {\n /** The number of recent events to retrieve. */\n numRecentEvents?: number;\n /** Retrieve events after this timestamp. */\n afterTimestamp?: number;\n}\n\n/**\n * The parameters for `createSession`.\n */\nexport interface CreateSessionRequest {\n /** The name of the application. */\n appName: string;\n /** The ID of the user. */\n userId: string;\n /** The initial state of the session. */\n state?: Record<string, unknown>;\n /** The ID of the session. A new ID will be generated if not provided. */\n sessionId?: string;\n}\n\n/**\n * The parameters for `getSession`.\n */\nexport interface GetSessionRequest {\n /** The name of the application. */\n appName: string;\n /** The ID of the user. */\n userId: string;\n /** The ID of the session. */\n sessionId: string;\n /** The configurations for getting the session. */\n config?: GetSessionConfig;\n}\n\n/**\n * The parameters for `listSessions`.\n */\nexport interface ListSessionsRequest {\n /** The name of the application. */\n appName: string;\n /** The ID of the user. */\n userId: string;\n}\n\n/**\n * The parameters for `deleteSession`.\n */\nexport interface DeleteSessionRequest {\n /** The name of the application. */\n appName: string;\n /** The ID of the user. */\n userId: string;\n /** The ID of the session. */\n sessionId: string;\n}\n\n/**\n * The parameters for `appendEvent`.\n */\nexport interface AppendEventRequest {\n /** The session to append the event to. */\n session: Session;\n /** The event to append. */\n event: Event;\n}\n\n/**\n * The response of listing sessions.\n *\n * The events and states are not set within each Session object.\n */\nexport interface ListSessionsResponse {\n /** A list of sessions. */\n sessions: Session[];\n}\n\n/**\n * Base class for session services.\n *\n * The service provides a set of methods for managing sessions and events.\n */\n// TODO - b/425992518: can held session internally to make the API simpler.\nexport abstract class BaseSessionService {\n /**\n * Creates a new session.\n *\n * @param request The request to create a session.\n * @return A promise that resolves to the newly created session instance.\n */\n abstract createSession(request: CreateSessionRequest): Promise<Session>;\n\n /**\n * Gets a session.\n *\n * @param request The request to get a session.\n * @return A promise that resolves to the session instance or undefined if not\n * found.\n */\n abstract getSession(request: GetSessionRequest): Promise<Session|undefined>;\n\n /**\n * Lists sessions for a user.\n *\n * @param request The request to list sessions.\n * @return A promise that resolves to a list of sessions for the user.\n */\n abstract listSessions(request: ListSessionsRequest):\n Promise<ListSessionsResponse>;\n\n /**\n * Deletes a session.\n *\n * @param request The request to delete a session.\n * @return A promise that resolves when the session is deleted.\n */\n abstract deleteSession(request: DeleteSessionRequest): Promise<void>;\n\n /**\n * Appends an event to a session.\n *\n * @param request The request to append an event.\n * @return A promise that resolves to the event that was appended.\n */\n async appendEvent({session, event}: AppendEventRequest): Promise<Event> {\n if (event.partial) {\n return event;\n }\n\n this.updateSessionState({session, event});\n session.events.push(event);\n\n return event;\n }\n\n /**\n * Updates the session state based on the event.\n *\n * @param request The request to update the session state.\n */\n private updateSessionState({session, event}: AppendEventRequest): void {\n if (!event.actions || !event.actions.stateDelta) {\n return;\n }\n for (const [key, value] of Object.entries(event.actions.stateDelta)) {\n if (key.startsWith(State.TEMP_PREFIX)) {\n continue;\n }\n session.state[key] = value;\n }\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Event} from '../events/event.js';\n\n/**\n * Represents a session in a conversation between agents and users.\n */\nexport interface Session {\n /**\n * The unique identifier of the session.\n */\n id: string;\n\n /**\n * The name of the app.\n */\n appName: string;\n\n /**\n * The id of the user.\n */\n userId: string;\n\n /**\n * The state of the session.\n */\n state: Record<string, unknown>;\n\n /**\n * The events of the session, e.g. user input, model response, function\n * call/response, etc.\n */\n events: Event[];\n\n /**\n * The last update time of the session.\n */\n lastUpdateTime: number;\n}\n\n/**\n * Creates a session from a partial session.\n *\n * @param params The partial session to create the session from.\n * @returns The session.\n */\nexport function createSession(params: Partial<Session>&{\n id: string;\n appName: string;\n}): Session {\n return {\n id: params.id,\n appName: params.appName,\n userId: params.userId || '',\n state: params.state || {},\n events: params.events || [],\n lastUpdateTime: params.lastUpdateTime || 0,\n };\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Event} from '../events/event.js';\nimport {deepClone} from '../utils/deep_clone.js';\nimport {randomUUID} from '../utils/env_aware_utils.js';\nimport {logger} from '../utils/logger.js';\n\nimport {AppendEventRequest, BaseSessionService, CreateSessionRequest, DeleteSessionRequest, GetSessionConfig, GetSessionRequest, ListSessionsRequest, ListSessionsResponse} from './base_session_service.js';\nimport {createSession, Session} from './session.js';\nimport {State} from './state.js';\n\n/**\n * An in-memory implementation of the session service.\n */\nexport class InMemorySessionService extends BaseSessionService {\n /**\n * A map from app name to a map from user ID to a map from session ID to\n * session.\n */\n private sessions:\n Record<string, Record<string, Record<string, Session>>> = {};\n\n /**\n * A map from app name to a map from user ID to a map from key to the value.\n */\n private userState:\n Record<string, Record<string, Record<string, unknown>>> = {};\n\n /**\n * A map from app name to a map from key to the value.\n */\n private appState: Record<string, Record<string, unknown>> = {};\n\n createSession({appName, userId, state, sessionId}: CreateSessionRequest):\n Promise<Session> {\n const session = createSession({\n id: sessionId || randomUUID(),\n appName,\n userId,\n state,\n events: [],\n lastUpdateTime: Date.now(),\n });\n\n if (!this.sessions[appName]) {\n this.sessions[appName] = {};\n }\n if (!this.sessions[appName][userId]) {\n this.sessions[appName][userId] = {};\n }\n\n this.sessions[appName][userId][session.id] = session;\n\n return Promise.resolve(\n this.mergeState(appName, userId, deepClone(session)));\n }\n\n getSession({appName, userId, sessionId, config}: GetSessionRequest):\n Promise<Session|undefined> {\n if (!this.sessions[appName] || !this.sessions[appName][userId] ||\n !this.sessions[appName][userId][sessionId]) {\n return Promise.resolve(undefined);\n }\n\n const session: Session = this.sessions[appName][userId][sessionId];\n const copiedSession = deepClone(session);\n\n if (config) {\n if (config.numRecentEvents) {\n copiedSession.events =\n copiedSession.events.slice(-config.numRecentEvents);\n }\n if (config.afterTimestamp) {\n let i = copiedSession.events.length - 1;\n while (i >= 0) {\n if (copiedSession.events[i].timestamp < config.afterTimestamp) {\n break;\n }\n i--;\n }\n if (i >= 0) {\n copiedSession.events = copiedSession.events.slice(i + 1);\n }\n }\n }\n\n return Promise.resolve(this.mergeState(appName, userId, copiedSession));\n }\n\n listSessions({appName, userId}: ListSessionsRequest):\n Promise<ListSessionsResponse> {\n if (!this.sessions[appName] || !this.sessions[appName][userId]) {\n return Promise.resolve({sessions: []});\n }\n\n const sessionsWithoutEvents: Session[] = [];\n for (const session of Object.values(this.sessions[appName][userId])) {\n sessionsWithoutEvents.push(createSession({\n id: session.id,\n appName: session.appName,\n userId: session.userId,\n state: {},\n events: [],\n lastUpdateTime: session.lastUpdateTime,\n }));\n }\n\n return Promise.resolve({sessions: sessionsWithoutEvents});\n }\n\n async deleteSession({appName, userId, sessionId}: DeleteSessionRequest):\n Promise<void> {\n const session = await this.getSession({appName, userId, sessionId});\n\n if (!session) {\n return;\n }\n\n delete this.sessions[appName][userId][sessionId];\n }\n\n override async appendEvent({session, event}: AppendEventRequest):\n Promise<Event> {\n await super.appendEvent({session, event});\n session.lastUpdateTime = event.timestamp;\n\n const appName = session.appName;\n const userId = session.userId;\n const sessionId = session.id;\n\n const warning = (message: string) => {\n logger.warn(`Failed to append event to session ${sessionId}: ${message}`);\n };\n\n if (!this.sessions[appName]) {\n warning(`appName ${appName} not in sessions`);\n return event;\n }\n\n if (!this.sessions[appName][userId]) {\n warning(`userId ${userId} not in sessions[appName]`);\n return event;\n }\n\n if (!this.sessions[appName][userId][sessionId]) {\n warning(`sessionId ${sessionId} not in sessions[appName][userId]`);\n return event;\n }\n\n if (event.actions && event.actions.stateDelta) {\n for (const key of Object.keys(event.actions.stateDelta)) {\n if (key.startsWith(State.APP_PREFIX)) {\n this.appState[appName] = this.appState[appName] || {};\n this.appState[appName][key.replace(State.APP_PREFIX, '')] =\n event.actions.stateDelta[key];\n }\n\n if (key.startsWith(State.USER_PREFIX)) {\n this.userState[appName] = this.userState[appName] || {};\n this.userState[appName][userId] =\n this.userState[appName][userId] || {};\n this.userState[appName][userId][key.replace(State.USER_PREFIX, '')] =\n event.actions.stateDelta[key];\n }\n }\n }\n\n const storageSession: Session = this.sessions[appName][userId][sessionId];\n await super.appendEvent({session: storageSession, event});\n\n storageSession.lastUpdateTime = event.timestamp;\n\n return event;\n }\n\n private mergeState(\n appName: string,\n userId: string,\n copiedSession: Session,\n ): Session {\n if (this.appState[appName]) {\n for (const key of Object.keys(this.appState[appName])) {\n copiedSession.state[State.APP_PREFIX + key] =\n this.appState[appName][key];\n }\n }\n\n if (!this.userState[appName] || !this.userState[appName][userId]) {\n return copiedSession;\n }\n\n for (const key of Object.keys(this.userState[appName][userId])) {\n copiedSession.state[State.USER_PREFIX + key] =\n this.userState[appName][userId][key];\n }\n return copiedSession;\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Content, createPartFromText} from '@google/genai';\nimport {trace} from '@opentelemetry/api';\n\nimport {BaseAgent} from '../agents/base_agent.js';\nimport {InvocationContext, newInvocationContextId} from '../agents/invocation_context.js';\nimport {LlmAgent} from '../agents/llm_agent.js';\nimport {createRunConfig, RunConfig} from '../agents/run_config.js';\nimport {BaseArtifactService} from '../artifacts/base_artifact_service.js';\nimport {BaseCredentialService} from '../auth/credential_service/base_credential_service.js';\nimport {createEvent, Event, getFunctionCalls} from '../events/event.js';\nimport {createEventActions} from '../events/event_actions.js';\nimport {BaseMemoryService} from '../memory/base_memory_service.js';\nimport {BasePlugin} from '../plugins/base_plugin.js';\nimport {PluginManager} from '../plugins/plugin_manager.js';\nimport {BaseSessionService} from '../sessions/base_session_service.js';\nimport {Session} from '../sessions/session.js';\nimport {logger} from '../utils/logger.js';\n\ninterface RunnerInput {\n appName: string;\n agent: BaseAgent;\n plugins?: BasePlugin[];\n artifactService?: BaseArtifactService;\n sessionService: BaseSessionService;\n memoryService?: BaseMemoryService;\n credentialService?: BaseCredentialService;\n}\n\nexport class Runner {\n readonly appName: string;\n readonly agent: BaseAgent;\n readonly pluginManager: PluginManager;\n readonly artifactService?: BaseArtifactService;\n readonly sessionService: BaseSessionService;\n readonly memoryService?: BaseMemoryService;\n readonly credentialService?: BaseCredentialService;\n\n constructor(input: RunnerInput) {\n this.appName = input.appName;\n this.agent = input.agent;\n this.pluginManager = new PluginManager(input.plugins ?? []);\n this.artifactService = input.artifactService;\n this.sessionService = input.sessionService;\n this.memoryService = input.memoryService;\n this.credentialService = input.credentialService;\n }\n\n /**\n * Runs the agent with the given message, and returns an async generator of\n * events.\n *\n * @param userId The user ID of the session.\n * @param sessionId The session ID of the session.\n * @param newMessage A new message to append to the session.\n * @param stateDelta An optional state delta to apply to the session.\n * @param runConfig The run config for the agent.\n * @yields The events generated by the agent.\n */\n // TODO - b/425992518: user, sessionId, and runConfig can be internalized.\n async * runAsync({\n userId,\n sessionId,\n newMessage,\n stateDelta,\n runConfig,\n }: {\n userId: string; sessionId: string; newMessage: Content;\n stateDelta?: Record<string, any>;\n runConfig?: RunConfig;\n }): AsyncGenerator<Event, void, undefined> {\n runConfig = createRunConfig(runConfig);\n // =========================================================================\n // Setup the session and invocation context\n // =========================================================================\n const span = trace.getTracer('gcp.vertex.agent').startSpan('invocation');\n try {\n const session =\n await this.sessionService.getSession({appName: this.appName, userId, sessionId});\n\n if (!session) {\n throw new Error(`Session not found: ${sessionId}`);\n }\n\n if (runConfig.supportCfc && this.agent instanceof LlmAgent) {\n const modelName = this.agent.canonicalModel.model;\n if (!modelName.startsWith('gemini-2')) {\n throw new Error(`CFC is not supported for model: ${\n modelName} in agent: ${this.agent.name}`);\n }\n }\n\n const invocationContext = new InvocationContext({\n artifactService: this.artifactService,\n sessionService: this.sessionService,\n memoryService: this.memoryService,\n credentialService: this.credentialService,\n invocationId: newInvocationContextId(),\n agent: this.agent,\n session,\n userContent: newMessage,\n runConfig,\n pluginManager: this.pluginManager,\n });\n\n // =========================================================================\n // Preprocess plugins on user message\n // =========================================================================\n const pluginUserMessage =\n await this.pluginManager.runOnUserMessageCallback({\n userMessage: newMessage,\n invocationContext,\n });\n if (pluginUserMessage) {\n newMessage = pluginUserMessage as Content;\n }\n\n // =========================================================================\n // Append user message to session\n // =========================================================================\n if (newMessage) {\n if (!newMessage.parts?.length) {\n throw new Error('No parts in the newMessage.');\n }\n\n // Directly saves the artifacts (if applicable) in the user message and\n // replaces the artifact data with a file name placeholder.\n // TODO - b/425992518: fix Runner<>>ArtifactService leaky abstraction.\n if (runConfig.saveInputBlobsAsArtifacts) {\n await this.saveArtifacts(\n invocationContext.invocationId, session.userId, session.id,\n newMessage);\n }\n // Append the user message to the session with optional state delta.\n await this.sessionService.appendEvent({\n session,\n event: createEvent({\n invocationId: invocationContext.invocationId,\n author: 'user',\n actions: stateDelta ? createEventActions({stateDelta}) : undefined,\n content: newMessage,\n }),\n });\n }\n\n // =========================================================================\n // Determine which agent should handle the workflow resumption.\n // =========================================================================\n invocationContext.agent =\n this.determineAgentForResumption(session, this.agent);\n\n // =========================================================================\n // Run the agent with the plugins (aka hooks to apply in the lifecycle)\n // =========================================================================\n // Step 1: Run the before_run callbacks to see if we should early exit.\n const beforeRunCallbackResponse =\n await this.pluginManager.runBeforeRunCallback({invocationContext});\n\n if (beforeRunCallbackResponse) {\n const earlyExitEvent = createEvent({\n invocationId: invocationContext.invocationId,\n author: 'model',\n content: beforeRunCallbackResponse,\n });\n // TODO: b/447446338 - In the future, do *not* save live call audio\n // content to session This is a feature in Python ADK\n await this.sessionService.appendEvent({session, event: earlyExitEvent});\n yield earlyExitEvent;\n\n } else {\n // Step 2: Otherwise continue with normal execution\n for await (const event of invocationContext.agent.runAsync(\n invocationContext)) {\n if (!event.partial) {\n await this.sessionService.appendEvent({session, event});\n }\n // Step 3: Run the on_event callbacks to optionally modify the event.\n const modifiedEvent = await this.pluginManager.runOnEventCallback(\n {invocationContext, event});\n if (modifiedEvent) {\n yield modifiedEvent;\n } else {\n yield event;\n }\n }\n }\n // Step 4: Run the after_run callbacks to optionally modify the context.\n await this.pluginManager.runAfterRunCallback({invocationContext});\n } finally {\n span.end();\n }\n }\n\n /**\n * Saves artifacts from the message parts and replaces the inline data with\n * a file name placeholder.\n *\n * @param invocationId The current invocation ID.\n * @param userId The user ID of the session.\n * @param sessionId The session ID of the session.\n * @param message The message containing parts to process.\n */\n private async saveArtifacts(\n invocationId: string, userId: string, sessionId: string,\n message: Content): Promise<void> {\n if (!this.artifactService || !message.parts?.length) {\n return;\n }\n\n for (let i = 0; i < message.parts.length; i++) {\n const part = message.parts[i];\n if (!part.inlineData) {\n continue;\n }\n const fileName = `artifact_${invocationId}_${i}`;\n // TODO - b/425992518: group appname, userId, sessionId as a key.\n await this.artifactService.saveArtifact({\n appName: this.appName,\n userId,\n sessionId,\n filename: fileName,\n artifact: part,\n });\n // TODO - b/425992518: potentially buggy if accidentally exposed to LLM.\n message.parts[i] = createPartFromText(\n `Uploaded file: ${fileName}. It is saved into artifacts`);\n }\n }\n\n /**\n * Determines the next agent to run to continue the session. This is primarily\n * used for session resumption.\n */\n // TODO - b/425992518: This is where LRO integration should happen.\n // Needs clean up before we can generalize it.\n private determineAgentForResumption(session: Session, rootAgent: BaseAgent):\n BaseAgent {\n // =========================================================================\n // Case 1: If the last event is a function response, this returns the\n // agent that made the original function call.\n // =========================================================================\n const event = findEventByLastFunctionResponseId(session.events);\n if (event && event.author) {\n return rootAgent.findAgent(event.author) || rootAgent;\n }\n\n // =========================================================================\n // Case 2: Otherwise, find the last agent that emitted a message and is\n // transferable across the agent tree.\n // =========================================================================\n // TODO - b/425992518: Optimize this, not going to work for long sessions.\n // TODO - b/425992518: The behavior is dynamic, needs better documentation.\n for (let i = session.events.length - 1; i >= 0; i--) {\n logger.info('event: ', JSON.stringify(session.events[i]));\n const event = session.events[i];\n if (event.author === 'user' || !event.author) {\n continue;\n }\n\n if (event.author === rootAgent.name) {\n return rootAgent;\n }\n\n const agent = rootAgent.findSubAgent(event.author!);\n if (!agent) {\n logger.warn(`Event from an unknown agent: ${event.author}, event id: ${\n event.id}`);\n continue;\n }\n if (this.isRoutableLlmAgent(agent)) {\n return agent;\n }\n }\n // =========================================================================\n // Case 3: default to root agent.\n // =========================================================================\n return rootAgent;\n }\n\n /**\n * Whether the agent to run can transfer to any other agent in the agent tree.\n *\n * An agent is transferable if:\n * - It is an instance of `LlmAgent`.\n * - All its ancestors are also transferable (i.e., they have\n * `disallowTransferToParent` set to false).\n *\n * @param agentToRun The agent to check for transferability.\n * @returns True if the agent can transfer, False otherwise.\n */\n private isRoutableLlmAgent(agentToRun: BaseAgent): boolean {\n let agent: BaseAgent|undefined = agentToRun;\n while (agent) {\n if (!(agent instanceof LlmAgent)) {\n return false;\n }\n if (agent.disallowTransferToParent) {\n return false;\n }\n agent = agent.parentAgent;\n }\n return true;\n }\n // TODO - b/425992518: Implement runLive and related methods.\n}\n\n/**\n * It iterates through the events in reverse order, and returns the event\n * containing a function call with a functionCall.id matching the\n * functionResponse.id from the last event in the session.\n */\n// TODO - b/425992518: a hack that used event log as transaction log. Fix.\nfunction findEventByLastFunctionResponseId(events: Event[]): Event|null {\n if (!events.length) {\n return null;\n }\n\n const lastEvent = events[events.length - 1];\n const functionCallId =\n lastEvent.content?.parts?.find((part) => part.functionResponse)\n ?.functionResponse?.id;\n if (!functionCallId) {\n return null;\n }\n\n // TODO - b/425992518: inefficient search, fix.\n for (let i = events.length - 2; i >= 0; i--) {\n const event = events[i];\n // Looking for the system long running request euc function call.\n const functionCalls = getFunctionCalls(event);\n if (!functionCalls) {\n continue;\n }\n\n for (const functionCall of functionCalls) {\n if (functionCall.id === functionCallId) {\n return event;\n }\n }\n }\n return null;\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {BaseAgent} from '../agents/base_agent.js';\nimport {InMemoryArtifactService} from '../artifacts/in_memory_artifact_service.js';\nimport {InMemoryMemoryService} from '../memory/in_memory_memory_service.js';\nimport {BasePlugin} from '../plugins/base_plugin.js';\nimport {InMemorySessionService} from '../sessions/in_memory_session_service.js';\n\nimport {Runner} from './runner.js';\n\nexport class InMemoryRunner extends Runner {\n constructor({\n agent,\n appName = 'InMemoryRunner',\n plugins = [],\n }: {agent: BaseAgent; appName?: string; plugins?: BasePlugin[];}) {\n super({\n appName,\n agent,\n plugins,\n artifactService: new InMemoryArtifactService(),\n sessionService: new InMemorySessionService(),\n memoryService: new InMemoryMemoryService(),\n });\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Content, FunctionDeclaration, Type} from '@google/genai';\n\nimport {BaseAgent} from '../agents/base_agent.js';\nimport {LlmAgent} from '../agents/llm_agent.js';\nimport {Event} from '../events/event.js';\nimport {InMemoryMemoryService} from '../memory/in_memory_memory_service.js';\nimport {Runner} from '../runner/runner.js';\nimport {InMemorySessionService} from '../sessions/in_memory_session_service.js';\nimport {GoogleLLMVariant} from '../utils/variant_utils.js';\n\nimport {BaseTool, RunAsyncToolRequest} from './base_tool.js';\nimport {ForwardingArtifactService} from './forwarding_artifact_service.js';\nimport {ToolContext} from './tool_context.js';\n\n/**\n * The configuration of the agent tool.\n */\nexport interface AgentToolConfig {\n /**\n * The reference to the agent instance.\n */\n agent: BaseAgent;\n\n /**\n * Whether to skip summarization of the agent output.\n */\n skipSummarization?: boolean;\n}\n\n/**\n * A tool that wraps an agent.\n *\n * This tool allows an agent to be called as a tool within a larger\n * application. The agent's input schema is used to define the tool's input\n * parameters, and the agent's output is returned as the tool's result.\n *\n * @param config: The configuration of the agent tool.\n */\nexport class AgentTool extends BaseTool {\n private readonly agent: BaseAgent;\n\n private readonly skipSummarization: boolean;\n\n constructor(config: AgentToolConfig) {\n super(\n {name: config.agent.name, description: config.agent.description || ''});\n this.agent = config.agent;\n this.skipSummarization = config.skipSummarization || false;\n }\n\n override _getDeclaration(): FunctionDeclaration {\n let declaration: FunctionDeclaration;\n\n if (this.agent instanceof LlmAgent && this.agent.inputSchema) {\n declaration = {\n name: this.name,\n description: this.description,\n // TODO(b/425992518): We should not use the agent's input schema as is.\n // It should be validated and possibly transformed. Consider similar\n // logic to one we have in Python ADK.\n parameters: this.agent.inputSchema,\n };\n } else {\n declaration = {\n name: this.name,\n description: this.description,\n parameters: {\n type: Type.OBJECT,\n properties: {\n 'request': {\n type: Type.STRING,\n },\n },\n required: ['request'],\n },\n };\n }\n\n if (this.apiVariant !== GoogleLLMVariant.GEMINI_API) {\n const hasOutputSchema =\n this.agent instanceof LlmAgent && this.agent.outputSchema;\n declaration.response =\n hasOutputSchema ? {type: Type.OBJECT} : {type: Type.STRING};\n }\n\n return declaration;\n }\n\n override async runAsync({args, toolContext}: RunAsyncToolRequest):\n Promise<unknown> {\n if (this.skipSummarization) {\n toolContext.actions.skipSummarization = true;\n }\n\n const hasInputSchema =\n this.agent instanceof LlmAgent && this.agent.inputSchema;\n const content: Content = {\n role: 'user',\n parts: [\n {\n // TODO(b/425992518): Should be validated. Consider similar\n // logic to one we have in Python ADK.\n text: hasInputSchema ? JSON.stringify(args) :\n args['request'] as string,\n },\n ],\n };\n\n const runner = new Runner({\n appName: this.agent.name,\n agent: this.agent,\n artifactService: new ForwardingArtifactService(toolContext),\n sessionService: new InMemorySessionService(),\n memoryService: new InMemoryMemoryService(),\n credentialService: toolContext.invocationContext.credentialService,\n });\n\n const session = await runner.sessionService.createSession({\n appName: this.agent.name,\n userId: 'tmp_user',\n state: toolContext.state.toRecord(),\n });\n\n let lastEvent: Event|undefined;\n for await (const event of runner.runAsync({\n userId: session.userId,\n sessionId: session.id,\n newMessage: content,\n })) {\n if (event.actions.stateDelta) {\n toolContext.state.update(event.actions.stateDelta);\n }\n\n lastEvent = event;\n }\n\n if (!lastEvent?.content?.parts?.length) {\n return '';\n }\n\n const hasOutputSchema =\n this.agent instanceof LlmAgent && this.agent.outputSchema;\n\n const mergetText = lastEvent.content.parts.map((part) => part.text)\n .filter((text) => text)\n .join('\\n');\n\n // TODO - b/425992518: In case of output schema, the output should be\n // validated. Consider similar logic to one we have in Python ADK.\n return hasOutputSchema ? JSON.parse(mergetText) : mergetText;\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Part} from '@google/genai';\n\nimport {InvocationContext} from '../agents/invocation_context.js';\nimport {BaseArtifactService, DeleteArtifactRequest, ListArtifactKeysRequest, ListVersionsRequest, LoadArtifactRequest, SaveArtifactRequest,} from '../artifacts/base_artifact_service.js';\n\nimport {ToolContext} from './tool_context.js';\n\n/**\n * Artifact service that forwards to the parent tool context.\n */\nexport class ForwardingArtifactService implements BaseArtifactService {\n private readonly invocationContext: InvocationContext;\n\n constructor(private readonly toolContext: ToolContext) {\n this.invocationContext = toolContext.invocationContext;\n }\n\n // TODO - b/425992518: Remove unnecessary parameters. We should rethink the\n // abstraction layer to make it more clear.\n async saveArtifact(request: SaveArtifactRequest): Promise<number> {\n return this.toolContext.saveArtifact(request.filename, request.artifact);\n }\n\n async loadArtifact(request: LoadArtifactRequest): Promise<Part|undefined> {\n return this.toolContext.loadArtifact(request.filename, request.version);\n }\n\n async listArtifactKeys(request: ListArtifactKeysRequest): Promise<string[]> {\n return this.toolContext.listArtifacts();\n }\n\n async deleteArtifact(request: DeleteArtifactRequest): Promise<void> {\n if (!this.toolContext.invocationContext.artifactService) {\n throw new Error('Artifact service is not initialized.');\n }\n\n return this.toolContext.invocationContext.artifactService.deleteArtifact(\n request);\n }\n\n async listVersions(request: ListVersionsRequest): Promise<number[]> {\n if (!this.toolContext.invocationContext.artifactService) {\n throw new Error('Artifact service is not initialized.');\n }\n\n return this.toolContext.invocationContext.artifactService.listVersions(\n request);\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {ReadonlyContext} from '../agents/readonly_context.js';\nimport {LlmRequest} from '../models/llm_request.js';\n\nimport {BaseTool} from './base_tool.js';\nimport {ToolContext} from './tool_context.js';\n\n/**\n * Function to decide whether a tool should be exposed to LLM. Toolset\n * implementer could consider whether to accept such instance in the toolset's\n * constructor and apply the predicate in getTools method.\n */\nexport type ToolPredicate =\n (tool: BaseTool, readonlyContext: ReadonlyContext) => boolean;\n\n/**\n * Base class for toolset.\n *\n * A toolset is a collection of tools that can be used by an agent.\n */\nexport abstract class BaseToolset {\n constructor(readonly toolFilter: ToolPredicate|string[]) {}\n\n /**\n * Returns the tools that should be exposed to LLM.\n *\n * @param context Context used to filter tools available to the agent. If\n * not defined, all tools in the toolset are returned.\n * @return A Promise that resolves to the list of tools.\n */\n abstract getTools(context?: ReadonlyContext): Promise<BaseTool[]>;\n\n /**\n * Closes the toolset.\n *\n * NOTE: This method is invoked, for example, at the end of an agent server's\n * lifecycle or when the toolset is no longer needed. Implementations\n * should ensure that any open connections, files, or other managed\n * resources are properly released to prevent leaks.\n *\n * @return A Promise that resolves when the toolset is closed.\n */\n abstract close(): Promise<void>;\n\n /**\n * Returns whether the tool should be exposed to LLM.\n *\n * @param tool The tool to check.\n * @param context Context used to filter tools available to the agent.\n * @return Whether the tool should be exposed to LLM.\n */\n protected isToolSelected(tool: BaseTool, context: ReadonlyContext): boolean {\n if (!this.toolFilter) {\n return true;\n }\n\n if (typeof this.toolFilter === 'function') {\n return this.toolFilter(tool, context);\n }\n\n if (Array.isArray(this.toolFilter)) {\n return (this.toolFilter as string[]).includes(tool.name);\n }\n\n return false;\n }\n\n /**\n * Processes the outgoing LLM request for this toolset. This method will be\n * called before each tool processes the llm request.\n *\n * Use cases:\n * - Instead of let each tool process the llm request, we can let the toolset\n * process the llm request. e.g. ComputerUseToolset can add computer use\n * tool to the llm request.\n *\n * @param toolContext The context of the tool.\n * @param llmRequest The outgoing LLM request, mutable this method.\n */\n async processLlmRequest(\n toolContext: ToolContext,\n llmRequest: LlmRequest,\n ): Promise<void> {}\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {GenerateContentConfig} from '@google/genai';\n\nimport {LlmRequest} from '../models/llm_request.js';\nimport {isGemini1Model, isGeminiModel} from '../utils/model_name.js';\n\nimport {BaseTool, RunAsyncToolRequest, ToolProcessLlmRequest} from './base_tool.js';\nimport {ToolContext} from './tool_context.js';\n\n/**\n * A built-in tool that is automatically invoked by Gemini 2 models to retrieve\n * search results from Google Search.\n *\n * This tool operates internally within the model and does not require or\n * perform local code execution.\n */\nclass GoogleSearchTool extends BaseTool {\n constructor() {\n super({name: 'google_search', description: 'Google Search Tool'});\n }\n\n runAsync(request: RunAsyncToolRequest): Promise<unknown> {\n // This is a built-in tool on server side, it's triggered by setting the\n // corresponding request parameters.\n return Promise.resolve();\n }\n\n override async processLlmRequest({toolContext, llmRequest}:\n ToolProcessLlmRequest):\n Promise<void> {\n if (!llmRequest.model) {\n return;\n }\n\n llmRequest.config = llmRequest.config || {} as GenerateContentConfig;\n llmRequest.config.tools = llmRequest.config.tools || [];\n\n if (isGemini1Model(llmRequest.model)) {\n if (llmRequest.config.tools.length > 0) {\n throw new Error(\n 'Google search tool can not be used with other tools in Gemini 1.x.',\n );\n }\n\n llmRequest.config.tools.push({\n googleSearchRetrieval: {},\n });\n\n return;\n }\n\n if (isGeminiModel(llmRequest.model)) {\n llmRequest.config.tools.push({\n googleSearch: {},\n });\n\n return;\n }\n\n throw new Error(\n `Google search tool is not supported for model ${llmRequest.model}`,\n );\n }\n}\n\n/**\n * A global instance of GoogleSearchTool.\n */\nexport const GOOGLE_SEARCH = new GoogleSearchTool();\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {FunctionDeclaration} from '@google/genai';\n\nimport {FunctionTool, ToolInputParameters, ToolOptions,} from './function_tool.js';\n\n/**\n * A function tool that returns the result asynchronously.\n *\n * This tool is used for long-running operations that may take a significant\n * amount of time to complete. The framework will call the function. Once the\n * function returns, the response will be returned asynchronously to the\n * framework which is identified by the function_call_id.\n */\n\nconst LONG_RUNNING_INSTRUCTION = `\n\nNOTE: This is a long-running operation. Do not call this tool again if it has already returned some intermediate or pending status.`;\n\nexport class LongRunningFunctionTool<\n TParameters extends ToolInputParameters = undefined,\n> extends FunctionTool<TParameters> {\n /**\n * The constructor acts as the user-friendly factory.\n * @param options The configuration for the tool.\n */\n constructor(options: ToolOptions<TParameters>) {\n super({...options, isLongRunning: true});\n }\n\n /**\n * Provide a schema for the function.\n */\n override _getDeclaration(): FunctionDeclaration {\n const declaration = super._getDeclaration();\n if (declaration.description) {\n declaration.description += LONG_RUNNING_INSTRUCTION;\n } else {\n declaration.description = LONG_RUNNING_INSTRUCTION.trimStart();\n }\n return declaration;\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Client} from '@modelcontextprotocol/sdk/client/index.js';\nimport {StdioClientTransport, StdioServerParameters} from '@modelcontextprotocol/sdk/client/stdio.js';\nimport {StreamableHTTPClientTransport} from '@modelcontextprotocol/sdk/client/streamableHttp.js';\n\n/**\n * Defines the parameters for establishing a connection to an MCP server using\n * standard input/output (stdio). This is typically used for running MCP servers\n * as local child processes.\n */\nexport interface StdioConnectionParams {\n type: 'StdioConnectionParams';\n serverParams: StdioServerParameters;\n timeout?: Number;\n}\n\n/**\n * Defines the parameters for establishing a connection to an MCP server over\n * HTTP using Server-Sent Events (SSE) for streaming.\n *\n * Usage:\n * const connectionParams: StreamableHTTPConnectionParams = {\n * type: 'StreamableHTTPConnectionParams',\n * url: 'http://localhost:8788/mcp'\n * };\n */\nexport interface StreamableHTTPConnectionParams {\n type: 'StreamableHTTPConnectionParams';\n url: string;\n header?: Record<string, unknown>;\n timeout?: Number;\n sseReadTimeout?: Number;\n terminateOnClose?: boolean;\n}\n\n/**\n * A union of all supported MCP connection parameter types.\n */\nexport type MCPConnectionParams =\n StdioConnectionParams|StreamableHTTPConnectionParams;\n\n/**\n * Manages Model Context Protocol (MCP) client sessions.\n *\n * This class is responsible for establishing and managing connections to MCP\n * servers. It supports different transport protocols like Standard I/O (Stdio)\n * and Server-Sent Events (SSE) over HTTP, determined by the provided\n * connection parameters.\n *\n * The primary purpose of this manager is to abstract away the details of\n * session creation and connection handling, providing a simple interface for\n * creating new MCP client instances that can be used to interact with\n * remote tools.\n */\nexport class MCPSessionManager {\n private readonly connectionParams: MCPConnectionParams;\n\n constructor(connectionParams: MCPConnectionParams) {\n this.connectionParams = connectionParams;\n }\n\n async createSession(): Promise<Client> {\n const client = new Client({name: 'MCPClient', version: '1.0.0'});\n\n switch (this.connectionParams.type) {\n case 'StdioConnectionParams':\n await client.connect(\n new StdioClientTransport(this.connectionParams.serverParams));\n break;\n case 'StreamableHTTPConnectionParams':\n await client.connect(new StreamableHTTPClientTransport(\n new URL(this.connectionParams.url)));\n break;\n default:\n // Triggers compile error if a case is missing.\n const _exhaustiveCheck: never = this.connectionParams;\n break;\n }\n\n return client;\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Schema, Type} from '@google/genai';\nimport {z} from 'zod';\n\nconst MCPToolSchema = z.object({\n type: z.literal('object'),\n properties: z.record(z.unknown()).optional(),\n required: z.string().array().optional(),\n});\ntype MCPToolSchema = z.infer<typeof MCPToolSchema>;\n\nfunction toGeminiType(mcpType: string): Type {\n switch (mcpType.toLowerCase()) {\n case 'text':\n case 'string':\n return Type.STRING;\n case 'number':\n return Type.NUMBER;\n case 'boolean':\n return Type.BOOLEAN;\n case 'integer':\n return Type.INTEGER;\n case 'array':\n return Type.ARRAY;\n case 'object':\n return Type.OBJECT;\n default:\n return Type.TYPE_UNSPECIFIED;\n }\n}\n\nexport function toGeminiSchema(mcpSchema?: MCPToolSchema): Schema|undefined {\n if (!mcpSchema) {\n return undefined;\n }\n\n function recursiveConvert(mcp: any): Schema {\n const geminiType = toGeminiType(mcp.type);\n const geminiSchema:\n Schema = {type: geminiType, description: mcp.description};\n\n if (geminiType === Type.OBJECT) {\n geminiSchema.properties = {};\n if (mcp.properties) {\n for (const name in mcp.properties) {\n geminiSchema.properties[name] =\n recursiveConvert(mcp.properties[name]);\n }\n }\n geminiSchema.required = mcp.required;\n } else if (geminiType === Type.ARRAY) {\n if (mcp.items) {\n geminiSchema.items = recursiveConvert(mcp.items);\n }\n }\n return geminiSchema;\n }\n return recursiveConvert(mcpSchema);\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {FunctionDeclaration} from '@google/genai';\nimport {CallToolRequest, CallToolResult, Tool} from '@modelcontextprotocol/sdk/types.js';\n\nimport {toGeminiSchema} from '../../utils/gemini_schema_util.js';\nimport {BaseTool, RunAsyncToolRequest} from '../base_tool.js';\n\nimport {MCPSessionManager} from './mcp_session_manager.js';\n\n/**\n * Represents a tool exposed via the Model Context Protocol (MCP).\n *\n * This class acts as a wrapper around a tool definition received from an MCP\n * server. It translates the MCP tool's schema into a format compatible with\n * the Gemini AI platform (FunctionDeclaration) and handles the remote\n * execution of the tool by communicating with the MCP server through an\n * {@link MCPSessionManager}.\n *\n * When an LLM decides to call this tool, the `runAsync` method will be\n * invoked, which in turn establishes an MCP session, sends a `callTool`\n * request with the provided arguments, and returns the result from the\n * remote tool.\n */\nexport class MCPTool extends BaseTool {\n private readonly mcpTool: Tool;\n private readonly mcpSessionManager: MCPSessionManager;\n\n constructor(mcpTool: Tool, mcpSessionManager: MCPSessionManager) {\n super({name: mcpTool.name, description: mcpTool.description || ''});\n this.mcpTool = mcpTool;\n this.mcpSessionManager = mcpSessionManager;\n }\n\n override _getDeclaration(): FunctionDeclaration {\n let declaration: FunctionDeclaration;\n declaration = {\n name: this.mcpTool.name,\n description: this.mcpTool.description,\n parameters: toGeminiSchema(this.mcpTool.inputSchema),\n // TODO: need revisit, refer to this\n // https://modelcontextprotocol.io/specification/2025-06-18/server/tools#tool-result\n response: toGeminiSchema(this.mcpTool.outputSchema),\n };\n return declaration;\n }\n\n override async runAsync(request: RunAsyncToolRequest): Promise<unknown> {\n const session = await this.mcpSessionManager.createSession();\n\n const callRequest: CallToolRequest = {} as CallToolRequest;\n callRequest.params = {name: this.mcpTool.name, arguments: request.args};\n\n return await session.callTool(callRequest.params) as CallToolResult;\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {ListToolsResult} from '@modelcontextprotocol/sdk/types.js';\n\nimport {ReadonlyContext} from '../../agents/readonly_context.js';\nimport {logger} from '../../utils/logger.js';\nimport {BaseTool} from '../base_tool.js';\nimport {BaseToolset, ToolPredicate} from '../base_toolset.js';\n\nimport {MCPConnectionParams, MCPSessionManager} from './mcp_session_manager.js';\nimport {MCPTool} from './mcp_tool.js';\n\n/**\n * A toolset that dynamically discovers and provides tools from a Model Context\n * Protocol (MCP) server.\n *\n * This class connects to an MCP server, retrieves the list of available tools,\n * and wraps each of them in an {@link MCPTool} instance. This allows the agent\n * to seamlessly use tools from an external MCP-compliant service.\n *\n * The toolset can be configured with a filter to selectively expose a subset\n * of the tools provided by the MCP server.\n *\n * Usage:\n * import { MCPToolset } from '@paean-ai/adk';\n * import { StreamableHTTPConnectionParamsSchema } from '@paean-ai/adk';\n *\n * const connectionParams = StreamableHTTPConnectionParamsSchema.parse({\n * type: \"StreamableHTTPConnectionParams\",\n * url: \"http://localhost:8788/mcp\"\n * });\n *\n * const mcpToolset = new MCPToolset(connectionParams);\n * const tools = await mcpToolset.getTools();\n *\n */\nexport class MCPToolset extends BaseToolset {\n private readonly mcpSessionManager: MCPSessionManager;\n\n constructor(\n connectionParams: MCPConnectionParams,\n toolFilter: ToolPredicate|string[] = []) {\n super(toolFilter);\n this.mcpSessionManager = new MCPSessionManager(connectionParams);\n }\n\n async getTools(context?: ReadonlyContext): Promise<BaseTool[]> {\n const session = await this.mcpSessionManager.createSession();\n\n const listResult = await session.listTools() as ListToolsResult;\n logger.debug(`number of tools: ${listResult.tools.length}`)\n for (const tool of listResult.tools) {\n logger.debug(`tool: ${tool.name}`)\n }\n\n // TODO: respect context (e.g. tool filter)\n return listResult.tools.map(\n (tool) => new MCPTool(tool, this.mcpSessionManager));\n }\n\n async close(): Promise<void> {}\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Bucket, Storage} from '@google-cloud/storage';\nimport {createPartFromBase64, createPartFromText, Part} from '@google/genai';\n\nimport {BaseArtifactService, DeleteArtifactRequest, ListArtifactKeysRequest, ListVersionsRequest, LoadArtifactRequest, SaveArtifactRequest} from './base_artifact_service.js';\n\nexport class GcsArtifactService implements BaseArtifactService {\n private readonly bucket: Bucket;\n\n constructor(bucket: string) {\n this.bucket = new Storage().bucket(bucket);\n }\n\n async saveArtifact(request: SaveArtifactRequest): Promise<number> {\n const versions = await this.listVersions(request);\n const version = versions.length > 0 ? Math.max(...versions) + 1 : 0;\n const file = this.bucket.file(getFileName({\n ...request,\n version,\n }));\n\n if (request.artifact.inlineData) {\n await file.save(JSON.stringify(request.artifact.inlineData.data), {\n contentType: request.artifact.inlineData.mimeType,\n });\n\n return version;\n }\n\n if (request.artifact.text) {\n await file.save(request.artifact.text, {\n contentType: 'text/plain',\n });\n\n return version;\n }\n\n throw new Error('Artifact must have either inlineData or text.')\n }\n\n async loadArtifact(request: LoadArtifactRequest): Promise<Part|undefined> {\n let version = request.version;\n if (version === undefined) {\n const versions = await this.listVersions(request);\n\n if (versions.length === 0) {\n return undefined;\n }\n\n version = Math.max(...versions);\n }\n\n const file = this.bucket.file(getFileName({\n ...request,\n version,\n }));\n const [[metadata], [rawDataBuffer]] =\n await Promise.all([file.getMetadata(), file.download()]);\n\n if (metadata.contentType === 'text/plain') {\n return createPartFromText(rawDataBuffer.toString('utf-8'));\n }\n\n return createPartFromBase64(\n rawDataBuffer.toString('base64'), metadata.contentType!);\n }\n\n async listArtifactKeys(request: ListArtifactKeysRequest): Promise<string[]> {\n const fileNames: string[] = [];\n const sessionPrefix =\n `${request.appName}/${request.userId}/${request.sessionId}/`;\n const usernamePrefix = `${request.appName}/${request.userId}/user/`;\n const [\n [sessionFiles],\n [userSessionFiles],\n ] =\n await Promise.all([\n this.bucket.getFiles({prefix: sessionPrefix}),\n this.bucket.getFiles({prefix: usernamePrefix}),\n ]);\n\n for (const file of sessionFiles) {\n fileNames.push(file.name.split('/').pop()!);\n }\n for (const file of userSessionFiles) {\n fileNames.push(file.name.split('/').pop()!);\n }\n\n return fileNames.sort((a, b) => a.localeCompare(b));\n }\n\n async deleteArtifact(request: DeleteArtifactRequest): Promise<void> {\n const versions = await this.listVersions(request);\n\n await Promise.all(versions.map(version => {\n const file = this.bucket.file(getFileName({\n ...request,\n version,\n }));\n\n return file.delete();\n }));\n\n return\n }\n\n async listVersions(request: ListVersionsRequest): Promise<number[]> {\n const prefix = getFileName(request);\n const [files] = await this.bucket.getFiles({prefix});\n const versions = [];\n for (const file of files) {\n const version = file.name.split('/').pop()!;\n versions.push(parseInt(version, 10));\n }\n\n return versions\n }\n}\n\nfunction getFileName({\n appName,\n userId,\n sessionId,\n filename,\n version,\n}: LoadArtifactRequest): string {\n if (filename.startsWith('user:')) {\n return `${appName}/${userId}/user/${filename}/${version}`;\n }\n return `${appName}/${userId}/${sessionId}/${filename}/${version}`;\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {trace, metrics} from '@opentelemetry/api';\nimport {logs} from '@opentelemetry/api-logs';\nimport {LoggerProvider, LogRecordProcessor, BatchLogRecordProcessor} from '@opentelemetry/sdk-logs';\nimport {MetricReader, MeterProvider, PeriodicExportingMetricReader} from '@opentelemetry/sdk-metrics';\nimport {detectResources, Resource} from '@opentelemetry/resources';\nimport {SpanProcessor, BatchSpanProcessor} from '@opentelemetry/sdk-trace-base';\nimport {NodeTracerProvider} from '@opentelemetry/sdk-trace-node';\nimport {OTLPTraceExporter} from '@opentelemetry/exporter-trace-otlp-http';\nimport {OTLPMetricExporter} from '@opentelemetry/exporter-metrics-otlp-http';\nimport {OTLPLogExporter} from '@opentelemetry/exporter-logs-otlp-http';\n\nexport interface OtelExportersConfig {\n enableTracing?: boolean;\n enableMetrics?: boolean;\n enableLogging?: boolean;\n}\n\n/**\n * Configuration hooks for OpenTelemetry setup.\n * \n * This interface defines the structure for configuring OpenTelemetry\n * components including span processors, metric readers, and log record processors.\n */\nexport interface OTelHooks {\n spanProcessors?: SpanProcessor[];\n metricReaders?: MetricReader[];\n logRecordProcessors?: LogRecordProcessor[];\n}\n\n/**\n * Sets up OTel providers if hooks for a given telemetry type were passed.\n *\n * Additionally adds generic OTLP exporters based on following env variables:\n * OTEL_EXPORTER_OTLP_ENDPOINT\n * OTEL_EXPORTER_OTLP_TRACES_ENDPOINT\n * OTEL_EXPORTER_OTLP_METRICS_ENDPOINT\n * OTEL_EXPORTER_OTLP_LOGS_ENDPOINT\n * See https://opentelemetry.io/docs/languages/sdk-configuration/otlp-exporter/\n * for how they are used.\n *\n * If a provider for a specific telemetry type was already globally set -\n * this function will not override it or register more exporters.\n *\n * @experimental (Experimental, subject to change)\n * \n * @param otelHooksToSetup per-telemetry-type processors and readers to be added\n * to OTel providers. If no hooks for a specific telemetry type are passed -\n * provider will not be set.\n * @param otelResource OTel resource to use in providers.\n * If empty - default OTel resource detection will be used.\n */\nexport function maybeSetOtelProviders(\n otelHooksToSetup: OTelHooks[] = [],\n otelResource?: Resource\n): void {\n const resource = otelResource || getOtelResource();\n const allHooks = [...otelHooksToSetup, getOtelExporters()];\n const spanProcessors = allHooks.flatMap(hooks => hooks.spanProcessors || []);\n const metricReaders = allHooks.flatMap(hooks => hooks.metricReaders || []);\n const logRecordProcessors = allHooks.flatMap(hooks => hooks.logRecordProcessors || []);\n\n if (spanProcessors.length > 0) {\n const tracerProvider = new NodeTracerProvider({\n resource,\n spanProcessors\n });\n tracerProvider.register();\n trace.setGlobalTracerProvider(tracerProvider);\n }\n\n if (metricReaders.length > 0) {\n const meterProvider = new MeterProvider({\n readers: metricReaders,\n resource,\n });\n metrics.setGlobalMeterProvider(meterProvider);\n }\n\n if (logRecordProcessors.length > 0) {\n const loggerProvider = new LoggerProvider({\n resource,\n processors: logRecordProcessors,\n });\n // logs is experimental, reference to https://open-telemetry.github.io/opentelemetry-js/modules/_opentelemetry_api-logs.html#alpha-software---use-at-your-own-risk\n logs.setGlobalLoggerProvider(loggerProvider);\n }\n}\n\n/**\n * Gets the OTel resource with environment variable detection.\n * \n * The resource detection populates resource labels from\n * environment variables like OTEL_SERVICE_NAME and OTEL_RESOURCE_ATTRIBUTES.\n * \n * @returns A Resource object with detected attributes\n */\nfunction getOtelResource(): Resource {\n return detectResources({\n detectors: [],\n });\n}\n\n/**\n * Gets OTel exporters configuration based on environment variables.\n * \n * @returns OtelExportersConfig with flags based on environment variables\n */\nfunction getOtelExportersConfig(): OtelExportersConfig {\n return {\n enableTracing: !!(process.env.OTEL_EXPORTER_OTLP_ENDPOINT || process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT),\n enableMetrics: !!(process.env.OTEL_EXPORTER_OTLP_ENDPOINT || process.env.OTEL_EXPORTER_OTLP_METRICS_ENDPOINT),\n enableLogging: !!(process.env.OTEL_EXPORTER_OTLP_ENDPOINT || process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT),\n };\n}\n\n/**\n * Gets OTel exporters based on configuration.\n * \n * @param config Configuration for which exporters to enable\n * @returns OTelHooks containing configured exporters\n */\nfunction getOtelExporters(config = getOtelExportersConfig()): OTelHooks {\n const { enableTracing, enableMetrics, enableLogging } = config;\n return {\n spanProcessors: enableTracing ? [new BatchSpanProcessor(new OTLPTraceExporter())] : [],\n metricReaders: enableMetrics ? [new PeriodicExportingMetricReader({ exporter: new OTLPMetricExporter() })] : [],\n logRecordProcessors: enableLogging ? [new BatchLogRecordProcessor(new OTLPLogExporter())] : [],\n };\n}", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {GoogleAuth} from 'google-auth-library';\nimport {PeriodicExportingMetricReader} from '@opentelemetry/sdk-metrics';\nimport {detectResources, Resource} from '@opentelemetry/resources';\nimport {gcpDetector} from '@opentelemetry/resource-detector-gcp';\nimport {TraceExporter} from '@google-cloud/opentelemetry-cloud-trace-exporter';\nimport {BatchSpanProcessor} from '@opentelemetry/sdk-trace-base';\nimport {MetricExporter} from '@google-cloud/opentelemetry-cloud-monitoring-exporter';\n\nimport {logger} from '../utils/logger.js';\n\nimport {OtelExportersConfig, OTelHooks} from './setup.js';\n\nconst GCP_PROJECT_ERROR_MESSAGE = \n 'Cannot determine GCP Project. OTel GCP Exporters cannot be set up. ' +\n 'Please make sure to log into correct GCP Project.';\n\nasync function getGcpProjectId(): Promise<string | undefined> {\n try {\n const auth = new GoogleAuth();\n const projectId = await auth.getProjectId();\n return projectId || undefined;\n } catch (error) {\n return undefined;\n }\n}\n\nexport async function getGcpExporters(config: OtelExportersConfig = {}): Promise<OTelHooks> {\n const {\n enableTracing = false,\n enableMetrics = false,\n // enableCloudLogging = false,\n } = config;\n\n const projectId = await getGcpProjectId();\n if (!projectId) {\n logger.warn(GCP_PROJECT_ERROR_MESSAGE);\n return {};\n }\n\n return {\n spanProcessors: enableTracing ? [\n new BatchSpanProcessor(new TraceExporter({ projectId })),\n ] : [],\n metricReaders: enableMetrics ? [\n new PeriodicExportingMetricReader({\n exporter: new MetricExporter({ projectId }),\n exportIntervalMillis: 5000,\n }),\n ] : [],\n logRecordProcessors: [],\n };\n}\n\nexport function getGcpResource(): Resource {\n return detectResources({ detectors: [gcpDetector] });\n}"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["trace", "createEventActions", "state", "mergeEventActions", "sources", "target", "result", "source", "createEvent", "params", "createNewEventId", "createEventActions", "isFinalResponse", "event", "getFunctionCalls", "getFunctionResponses", "hasTrailingCodeExecutionResult", "funcCalls", "part", "funcResponses", "_a", "stringifyContent", "ASCII_LETTERS_AND_NUMBERS", "id", "i", "State", "value", "delta", "key", "defaultValue", "ReadonlyContext", "invocationContext", "State", "CallbackContext", "ReadonlyContext", "invocationContext", "eventActions", "createEventActions", "State", "filename", "version", "artifact", "isBrowser", "UUID_MASK", "randomUUID", "uuid", "i", "randomValue", "base64Decode", "data", "isBrowser", "InvocationCostManager", "runConfig", "InvocationContext", "params", "newInvocationContextId", "randomUUID", "BaseAgent", "config", "validateAgentName", "getRootAgent", "getCannonicalCallback", "parentContext", "span", "trace", "context", "beforeAgentCallbackEvent", "event", "afterAgentCallbackEvent", "name", "subAgent", "result", "InvocationContext", "invocationContext", "callbackContext", "CallbackContext", "callback", "content", "createEvent", "isIdentifier", "str", "rootAgent", "callbacks", "createUserContent", "AuthHandler", "authConfig", "state", "credentialKey", "_a", "_b", "authSchemeType", "ToolConfirmation", "hint", "confirmed", "payload", "ToolContext", "CallbackContext", "invocationContext", "eventActions", "functionCallId", "toolConfirmation", "authConfig", "authHandler", "AuthHandler", "query", "hint", "payload", "ToolConfirmation", "LogLevel", "logLevel", "setLogLevel", "level", "SimpleLogger", "args", "getColoredPrefix", "LOG_LEVEL_STR", "CONSOLE_COLOR_MAP", "RESET_COLOR", "logger", "AF_FUNCTION_CALL_ID_PREFIX", "REQUEST_EUC_FUNCTION_CALL_NAME", "REQUEST_CONFIRMATION_FUNCTION_CALL_NAME", "functionsExportedForTestingOnly", "handleFunctionCallList", "generateClientFunctionCallId", "randomUUID", "populateClientFunctionCallId", "modelResponseEvent", "functionCalls", "getFunctionCalls", "functionCall", "removeClientFunctionCallId", "content", "part", "getLongRunningFunctionCalls", "toolsDict", "longRunningToolIds", "generateAuthEvent", "invocationContext", "functionResponseEvent", "_a", "parts", "functionCallId", "authConfig", "requestEucFunctionCall", "createEvent", "generateRequestConfirmationEvent", "functionCallEvent", "_b", "toolConfirmation", "originalFunctionCall", "call", "requestConfirmationFunctionCall", "callToolAsync", "tool", "args", "toolContext", "logger", "handleFunctionCallsAsync", "beforeToolCallbacks", "afterToolCallbacks", "filters", "toolConfirmationDict", "functionResponseEvents", "filteredFunctionCalls", "getToolAndContext", "functionArgs", "functionResponse", "functionResponseError", "callback", "e", "onToolErrorResponse", "alteredFunctionResponse", "createUserContent", "mergedEvent", "mergeParallelFunctionResponseEvents", "ToolContext", "mergedParts", "event", "baseEvent", "actionsList", "mergedActions", "mergeEventActions", "LiveRequestQueue", "req", "resolve", "closeRequest", "content", "blob", "request", "z", "BaseCodeExecutor", "MODEL_NAME_PATTERN", "extractModelName", "modelString", "match", "isGeminiModel", "isGemini1Model", "isGemini2Model", "isGemini3PreviewModel", "modelString", "modelName", "extractModelName", "BuiltInCodeExecutor", "BaseCodeExecutor", "params", "llmRequest", "isGemini2Model", "Language", "Outcome", "deepClone", "obj", "extractCodeAndTruncateContent", "content", "codeBlockDelimiters", "_a", "i", "part", "textParts", "firstTextPart", "deepClone", "responseText", "leadingDelimiterPattern", "d", "trailingDelimiterPattern", "match", "prefix", "codeStr", "buildExecutableCodePart", "code", "Language", "buildCodeExecutionResultPart", "codeExecutionResult", "Outcome", "finalResult", "f", "convertCodeExecutionParts", "codeBlockDelimiter", "executionResultDelimiters", "lastPart", "CONTEXT_KEY", "SESSION_ID_KEY", "PROCESSED_FILE_NAMES_KEY", "INPUT_FILE_KEY", "ERROR_COUNT_KEY", "CODE_EXECUTION_RESULTS_KEY", "CodeExecutorContext", "sessionState", "_a", "deepClone", "executionId", "fileNames", "inputFiles", "invocationId", "errorCounts", "code", "resultStdout", "resultStderr", "codeExecutionResults", "version", "ADK_LABEL", "LANGUAGE_LABEL", "AGENT_ENGINE_TELEMETRY_TAG", "AGENT_ENGINE_TELEMETRY_ENV_VARIABLE_NAME", "_getDefaultLabels", "frameworkLabel", "version", "isBrowser", "languageLabel", "getClientLabels", "BASE_MODEL_SYMBOL", "isBaseLlm", "obj", "_a", "BaseLlm", "model", "headerValue", "getClientLabels", "llmRequest", "appendInstructions", "llmRequest", "instructions", "newInstructions", "setOutputSchema", "llmRequest", "schema", "createPartFromText", "FinishReason", "GoogleGenAI", "getGoogleLlmVariant", "getBooleanEnvVar", "envVar", "envVarValue", "GeminiLlmConnection", "geminiSession", "history", "contents", "content", "_a", "logger", "functionResponses", "part", "fr", "blob", "text", "createLlmResponse", "response", "_a", "usageMetadata", "candidate", "GEMINI3_PREVIEW_API_ENDPOINT", "Gemini", "BaseLlm", "model", "apiKey", "vertexai", "project", "location", "headers", "apiEndpoint", "isGemini3PreviewModel", "canReadEnv", "logger", "useVertexAI", "vertexAIfromEnv", "availableApiKey", "llmRequest", "stream", "_a", "_b", "_c", "_d", "_e", "_f", "_g", "streamResult", "thoughtText", "text", "usageMetadata", "lastResponse", "response", "llmResponse", "createLlmResponse", "firstPart", "parts", "createPartFromText", "FinishReason", "combinedHeaders", "GoogleGenAI", "httpOptions", "liveSession", "GeminiLlmConnection", "content", "part", "removeDisplayNameIfPresent", "dataObj", "LRUCache", "maxSize", "key", "item", "value", "lruKey", "_LLMRegistry", "model", "modelNameRegex", "llmCls", "logger", "regex", "cachedLlm", "llmClass", "LLMRegistry", "Gemini", "BaseTool", "params", "_a", "toolContext", "llmRequest", "functionDeclaration", "tool", "findToolWithFunctionDeclarations", "getGoogleLlmVariant", "Type", "ZodObject", "Type", "z", "isZodObject", "obj", "_a", "parseZodType", "zodType", "def", "description", "result", "returnResult", "check", "zodObjectToSchema", "literalType", "nullableInner", "defaultInner", "schema", "shape", "properties", "required", "key", "fieldSchema", "parsedField", "currentSchema", "isOptional", "catchall", "additionalProperties", "toSchema", "parameters", "Type", "isZodObject", "zodObjectToSchema", "FunctionTool", "BaseTool", "options", "_a", "name", "req", "validatedArgs", "ZodObject", "error", "errorMessage", "BaseLlmRequestProcessor", "getContents", "events", "agentName", "currentBranch", "_a", "_b", "filteredEvents", "event", "isAuthEvent", "isToolConfirmationEvent", "isEventFromAnotherAgent", "convertForeignEvent", "resultEvents", "rearrangeEventsForLatestFunctionResponse", "rearrangeEventsForAsyncFunctionResponsesInHistory", "contents", "content", "deepClone", "removeClientFunctionCallId", "getCurrentTurnContents", "i", "_c", "part", "REQUEST_EUC_FUNCTION_CALL_NAME", "REQUEST_CONFIRMATION_FUNCTION_CALL_NAME", "_d", "_e", "_f", "argsText", "safeStringify", "responseText", "createEvent", "mergeFunctionResponseEvents", "mergedEvent", "partsInMergedEvent", "partIndicesInMergedEvent", "functionCallId", "latestEvent", "functionResponses", "getFunctionResponses", "functionResponsesIds", "response", "secondLatestEvent", "functionCallsFromSecondLatest", "getFunctionCalls", "functionCall", "functionCallEventIdx", "idx", "functionCalls", "functionCallIds", "fc", "id", "functionResponseEvents", "responses", "functionCallIdToResponseEventIndex", "functionResponse", "functionResponseEventsIndices", "responseIndex", "eventsToMerge", "b", "index", "obj", "injectSessionState", "template", "readonlyContext", "invocationContext", "replaceMatchedKeyWithItsValue", "match", "key", "isOptional", "fileName", "artifact", "isValidStateName", "pattern", "result", "lastEnd", "matches", "replacement", "isIdentifierPattern", "isIdentifier", "s", "VALID_PREFIXES", "State", "variableName", "parts", "StreamingMode", "createRunConfig", "params", "validateMaxLlmCalls", "value", "logger", "ADK_AGENT_NAME_LABEL_KEY", "convertToolUnionToTools", "toolUnion", "context", "BaseTool", "BasicLlmRequestProcessor", "BaseLlmRequestProcessor", "invocationContext", "llmRequest", "_a", "agent", "LlmAgent", "setOutputSchema", "BASIC_LLM_REQUEST_PROCESSOR", "IdentityLlmRequestProcessor", "si", "appendInstructions", "IDENTITY_LLM_REQUEST_PROCESSOR", "InstructionsLlmRequestProcessor", "rootAgent", "instruction", "requireStateInjection", "ReadonlyContext", "instructionWithState", "injectSessionState", "INSTRUCTIONS_LLM_REQUEST_PROCESSOR", "ContentRequestProcessor", "getContents", "getCurrentTurnContents", "CONTENT_REQUEST_PROCESSOR", "AgentTransferLlmRequestProcessor", "FunctionTool", "z", "args", "toolContext", "transferTargets", "ToolContext", "targetAgent", "targetAgents", "instructions", "targets", "peerAgent", "AGENT_TRANSFER_LLM_REQUEST_PROCESSOR", "RequestConfirmationLlmRequestProcessor", "events", "requestConfirmationFunctionResponses", "confirmationEventIndex", "i", "event", "responses", "getFunctionResponses", "foundConfirmation", "functionResponse", "REQUEST_CONFIRMATION_FUNCTION_CALL_NAME", "toolConfirmation", "ToolConfirmation", "functionCalls", "getFunctionCalls", "toolsToResumeWithConfirmation", "toolsToResumeWithArgs", "functionCall", "originalFunctionCall", "j", "eventToCheck", "functionResponses", "fr", "toolsList", "toolsDict", "tool", "functionResponseEvent", "handleFunctionCallList", "REQUEST_CONFIRMATION_LLM_REQUEST_PROCESSOR", "CodeExecutionRequestProcessor", "runPreProcessor", "BaseCodeExecutor", "content", "delimeters", "codeExecutionParts", "convertCodeExecutionParts", "DATA_FILE_UTIL_MAP", "DATA_FILE_HELPER_LIB", "CodeExecutionResponseProcessor", "llmResponse", "runPostProcessor", "responseProcessor", "codeExecutor", "BuiltInCodeExecutor", "codeExecutorContext", "CodeExecutorContext", "State", "allInputFiles", "extractAndReplaceInlineFiles", "processedFileNames", "filesToProcess", "f", "file", "codeStr", "getDataFilePreprocessingCode", "codeContent", "buildExecutableCodePart", "deepClone", "createEvent", "executionId", "getOrSetExecutionId", "codeExecutionResult", "executionResultEvent", "postProcessCodeExecutionResult", "responseContent", "extractCodeAndTruncateContent", "savedFileNames", "part", "mimeType", "fileName", "base64Decode", "resultContent", "buildCodeExecutionResultPart", "eventActions", "createEventActions", "outputFile", "version", "getNormalizedFileName", "varName", "normalizedName", "loaderCode", "CODE_EXECUTION_REQUEST_PROCESSOR", "_LlmAgent", "BaseAgent", "config", "_b", "_c", "_d", "_e", "_f", "_g", "_h", "_i", "logger", "isBaseLlm", "LLMRegistry", "ancestorAgent", "resolvedTools", "tools", "callback", "isFinalResponse", "resultStr", "result", "e", "lastEvent", "processor", "modelResponseEvent", "createNewEventId", "mergedEvent", "populateClientFunctionCallId", "getLongRunningFunctionCalls", "handleFunctionCallsAsync", "authEvent", "generateAuthEvent", "toolConfirmationEvent", "generateRequestConfirmationEvent", "nextAgentName", "nextAgent", "agentName", "agentToRun", "beforeModelResponse", "llm", "responsesGenerator", "alteredLlmResponse", "callbackContext", "CallbackContext", "beforeModelCallbackResponse", "callbackResponse", "afterModelCallbackResponse", "responseGenerator", "response", "modelError", "onModelErrorCallbackResponse", "errorResponse", "LoopAgent", "BaseAgent", "config", "_a", "context", "iteration", "subAgent", "shouldExit", "event", "ParallelAgent", "BaseAgent", "context", "agentRuns", "subAgent", "createBranchCtxForSubAgent", "event", "mergeAgentRuns", "agent", "originalContext", "invocationContext", "InvocationContext", "branchSuffix", "pendingPromises", "index", "generator", "promise", "result", "nextPromise", "TASK_COMPLETED_TOOL_NAME", "SequentialAgent", "BaseAgent", "context", "subAgent", "event", "LlmAgent", "ReadonlyContext", "tool", "FunctionTool", "InMemoryArtifactService", "appName", "userId", "sessionId", "filename", "artifact", "path", "artifactPath", "version", "versions", "sessionPrefix", "usernamespacePrefix", "filenames", "artifacts", "i", "fileHasUserNamespace", "InMemoryMemoryService", "session", "userKey", "getUserKey", "event", "_a", "_b", "_c", "req", "wordsInQuery", "response", "sessionEvents", "joinedText", "part", "text", "wordsInEvent", "extractWordsLower", "queryWord", "formatTimestamp", "appName", "userId", "match", "timestamp", "BasePlugin", "name", "invocationContext", "userMessage", "event", "agent", "callbackContext", "llmRequest", "llmResponse", "error", "tool", "toolArgs", "toolContext", "result", "LoggingPlugin", "BasePlugin", "name", "invocationContext", "userMessage", "_a", "event", "isFinalResponse", "functionCalls", "getFunctionCalls", "funcCalls", "fc", "functionResponses", "getFunctionResponses", "funcResponses", "fr", "agent", "callbackContext", "llmRequest", "sysInstruction", "toolNames", "llmResponse", "tool", "toolArgs", "toolContext", "result", "error", "message", "formattedMessage", "logger", "content", "maxLength", "parts", "part", "text", "args", "formatted", "PluginManager", "plugins", "plugin", "p", "logger", "pluginName", "callback", "callbackName", "result", "e", "errorMessage", "userMessage", "invocationContext", "event", "agent", "callbackContext", "tool", "toolArgs", "toolContext", "llmRequest", "error", "llmResponse", "REQUEST_CONFIRMATION_FUNCTION_CALL_NAME", "TOOL_CALL_SECURITY_CHECK_STATES", "INTERMEDIATE_REQUIRE_TOOL_CALL_CONFIRMATION_ERROR", "PolicyOutcome", "InMemoryPolicyEngine", "context", "SecurityPlugin", "BasePlugin", "params", "_a", "tool", "toolArgs", "toolContext", "toolCallCheckState", "functionCallId", "state", "toolCallStates", "policyCheckResult", "getAskUserConfirmationFunctionCalls", "event", "results", "part", "BaseSessionService", "session", "event", "key", "value", "State", "createSession", "params", "InMemorySessionService", "BaseSessionService", "appName", "userId", "state", "sessionId", "session", "createSession", "randomUUID", "deepClone", "config", "copiedSession", "i", "sessionsWithoutEvents", "event", "warning", "message", "logger", "key", "State", "storageSession", "createPartFromText", "trace", "Runner", "input", "_a", "PluginManager", "userId", "sessionId", "newMessage", "stateDelta", "runConfig", "createRunConfig", "span", "trace", "session", "LlmAgent", "modelName", "invocationContext", "InvocationContext", "newInvocationContextId", "pluginUserMessage", "createEvent", "createEventActions", "beforeRunCallbackResponse", "earlyExitEvent", "event", "modifiedEvent", "invocationId", "message", "i", "part", "fileName", "createPartFromText", "rootAgent", "findEventByLastFunctionResponseId", "logger", "agent", "agentToRun", "events", "_b", "_c", "_d", "functionCallId", "functionCalls", "getFunctionCalls", "functionCall", "InMemoryRunner", "Runner", "agent", "appName", "plugins", "InMemoryArtifactService", "InMemorySessionService", "InMemoryMemoryService", "Type", "ForwardingArtifactService", "toolContext", "request", "AgentTool", "BaseTool", "config", "declaration", "LlmAgent", "Type", "hasOutputSchema", "args", "toolContext", "_a", "_b", "content", "runner", "Runner", "ForwardingArtifactService", "InMemorySessionService", "InMemoryMemoryService", "session", "lastEvent", "event", "mergetText", "part", "text", "BaseToolset", "toolFilter", "tool", "context", "toolContext", "llmRequest", "GoogleSearchTool", "BaseTool", "request", "toolContext", "llmRequest", "isGemini1Model", "isGeminiModel", "GOOGLE_SEARCH", "LONG_RUNNING_INSTRUCTION", "LongRunningFunctionTool", "FunctionTool", "options", "declaration", "Client", "StdioClientTransport", "StreamableHTTPClientTransport", "MCPSessionManager", "connectionParams", "client", "_exhaustiveCheck", "Type", "z", "MCPToolSchema", "toGeminiType", "mcpType", "toGeminiSchema", "mcpSchema", "recursiveConvert", "mcp", "geminiType", "geminiSchema", "name", "MCPTool", "BaseTool", "mcpTool", "mcpSessionManager", "declaration", "toGeminiSchema", "request", "session", "callRequest", "MCPToolset", "BaseToolset", "connectionParams", "toolFilter", "MCPSessionManager", "context", "listResult", "logger", "tool", "MCPTool", "Storage", "createPartFromBase64", "createPartFromText", "GcsArtifactService", "bucket", "request", "versions", "version", "file", "getFileName", "metadata", "rawDataBuffer", "fileNames", "sessionPrefix", "usernamePrefix", "sessionFiles", "userSessionFiles", "a", "b", "prefix", "files", "appName", "userId", "sessionId", "filename", "trace", "metrics", "logs", "LoggerProvider", "BatchLogRecordProcessor", "MeterProvider", "PeriodicExportingMetricReader", "detectResources", "BatchSpanProcessor", "NodeTracerProvider", "OTLPTraceExporter", "OTLPMetricExporter", "OTLPLogExporter", "maybeSetOtelProviders", "otelHooksToSetup", "otelResource", "resource", "getOtelResource", "allHooks", "getOtelExporters", "spanProcessors", "hooks", "metricReaders", "logRecordProcessors", "tracerProvider", "meterProvider", "loggerProvider", "getOtelExportersConfig", "config", "enableTracing", "enableMetrics", "enableLogging", "GoogleAuth", "PeriodicExportingMetricReader", "detectResources", "gcpDetector", "TraceExporter", "BatchSpanProcessor", "MetricExporter", "GCP_PROJECT_ERROR_MESSAGE", "getGcpProjectId", "GoogleAuth", "getGcpExporters", "config", "enableTracing", "enableMetrics", "projectId", "BatchSpanProcessor", "TraceExporter", "PeriodicExportingMetricReader", "MetricExporter", "logger", "getGcpResource", "detectResources", "gcpDetector"]
|
|
4
|
+
"sourcesContent": ["/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Content} from '@google/genai';\nimport {trace} from '@opentelemetry/api';\n\nimport {createEvent, Event} from '../events/event.js';\n\nimport {CallbackContext} from './callback_context.js';\nimport {InvocationContext} from './invocation_context.js';\n\ntype SingleAgentCallback = (context: CallbackContext) =>\n Promise<Content|undefined>|(Content|undefined);\n\ntype BeforeAgentCallback = SingleAgentCallback|SingleAgentCallback[];\n\ntype AfterAgentCallback = SingleAgentCallback|SingleAgentCallback[];\n\n/**\n * The config of a base agent.\n */\nexport interface BaseAgentConfig {\n name: string;\n description?: string;\n parentAgent?: BaseAgent;\n subAgents?: BaseAgent[];\n beforeAgentCallback?: BeforeAgentCallback;\n afterAgentCallback?: AfterAgentCallback;\n}\n\n/**\n * Base class for all agents in Agent Development Kit.\n */\nexport abstract class BaseAgent {\n /**\n * The agent's name.\n * Agent name must be a JS identifier and unique within the agent tree.\n * Agent name cannot be \"user\", since it's reserved for end-user's input.\n */\n readonly name: string;\n\n /**\n * Description about the agent's capability.\n *\n * The model uses this to determine whether to delegate control to the agent.\n * One-line description is enough and preferred.\n */\n readonly description?: string;\n\n /**\n * Root agent of this agent.\n */\n readonly rootAgent: BaseAgent;\n\n /**\n * The parent agent of this agent.\n *\n * Note that an agent can ONLY be added as sub-agent once.\n *\n * If you want to add one agent twice as sub-agent, consider to create two\n * agent instances with identical config, but with different name and add them\n * to the agent tree.\n *\n * The parent agent is the agent that created this agent.\n */\n parentAgent?: BaseAgent;\n\n /**\n * The sub-agents of this agent.\n */\n readonly subAgents: BaseAgent[];\n\n /**\n * Callback or list of callbacks to be invoked before the agent run.\n *\n * When a list of callbacks is provided, the callbacks will be called in the\n * order they are listed until a callback does not return undefined.\n *\n * @param callbackContext: MUST be named 'callbackContext' (enforced).\n *\n * @return Content: The content to return to the user. When the content is\n * present, the agent run will be skipped and the provided content will be\n * returned to user.\n */\n readonly beforeAgentCallback: SingleAgentCallback[];\n\n /**\n * Callback or list of callbacks to be invoked after the agent run.\n *\n * When a list of callbacks is provided, the callbacks will be called in the\n * order they are listed until a callback does not return undefined.\n *\n * @param callbackContext: MUST be named 'callbackContext' (enforced).\n *\n * @return Content: The content to return to the user. When the content is\n * present, the provided content will be used as agent response and\n * appended to event history as agent response.\n */\n readonly afterAgentCallback: SingleAgentCallback[];\n\n constructor(config: BaseAgentConfig) {\n this.name = validateAgentName(config.name);\n this.description = config.description;\n this.parentAgent = config.parentAgent;\n this.subAgents = config.subAgents || [];\n this.rootAgent = getRootAgent(this);\n this.beforeAgentCallback =\n getCannonicalCallback(config.beforeAgentCallback);\n this.afterAgentCallback = getCannonicalCallback(config.afterAgentCallback);\n\n this.setParentAgentForSubAgents();\n }\n\n /**\n * Entry method to run an agent via text-based conversation.\n *\n * @param parentContext The invocation context of the parent agent.\n * @yields The events generated by the agent.\n * @returns An AsyncGenerator that yields the events generated by the agent.\n */\n async *\n runAsync(parentContext: InvocationContext):\n AsyncGenerator<Event, void, void> {\n const span = trace.getTracer('gcp.vertex.agent')\n .startSpan(`agent_run [${this.name}]`);\n try {\n const context = this.createInvocationContext(parentContext);\n\n const beforeAgentCallbackEvent =\n await this.handleBeforeAgentCallback(context);\n if (beforeAgentCallbackEvent) {\n yield beforeAgentCallbackEvent;\n }\n\n if (context.endInvocation) {\n return;\n }\n\n for await (const event of this.runAsyncImpl(context)) {\n yield event;\n }\n\n if (context.endInvocation) {\n return;\n }\n\n const afterAgentCallbackEvent =\n await this.handleAfterAgentCallback(context);\n if (afterAgentCallbackEvent) {\n yield afterAgentCallbackEvent;\n }\n } finally {\n span.end();\n }\n }\n\n /**\n * Entry method to run an agent via video/audio-based conversation.\n *\n * @param parentContext The invocation context of the parent agent.\n * @yields The events generated by the agent.\n * @returns An AsyncGenerator that yields the events generated by the agent.\n */\n async *\n runLive(parentContext: InvocationContext):\n AsyncGenerator<Event, void, void> {\n const span = trace.getTracer('gcp.vertex.agent')\n .startSpan(`agent_run [${this.name}]`);\n try {\n // TODO(b/425992518): Implement live mode.\n throw new Error('Live mode is not implemented yet.');\n } finally {\n span.end();\n }\n }\n\n /**\n * Core logic to run this agent via text-based conversation.\n *\n * @param context The invocation context of the agent.\n * @yields The events generated by the agent.\n * @returns An AsyncGenerator that yields the events generated by the agent.\n */\n protected abstract runAsyncImpl(context: InvocationContext):\n AsyncGenerator<Event, void, void>;\n\n /**\n * Core logic to run this agent via video/audio-based conversation.\n *\n * @param context The invocation context of the agent.\n * @yields The events generated by the agent.\n * @returns An AsyncGenerator that yields the events generated by the agent.\n */\n protected abstract runLiveImpl(context: InvocationContext):\n AsyncGenerator<Event, void, void>;\n\n /**\n * Finds the agent with the given name in this agent and its descendants.\n *\n * @param name The name of the agent to find.\n * @return The agent with the given name, or undefined if not found.\n */\n findAgent(name: string): BaseAgent|undefined {\n if (this.name === name) {\n return this;\n }\n\n return this.findSubAgent(name);\n }\n\n /**\n * Finds the agent with the given name in this agent's descendants.\n *\n * @param name The name of the agent to find.\n * @return The agent with the given name, or undefined if not found.\n */\n findSubAgent(name: string): BaseAgent|undefined {\n for (const subAgent of this.subAgents) {\n const result = subAgent.findAgent(name);\n if (result) {\n return result;\n }\n }\n\n return undefined;\n }\n\n /**\n * Creates an invocation context for this agent.\n *\n * @param parentContext The invocation context of the parent agent.\n * @return The invocation context for this agent.\n */\n protected createInvocationContext(parentContext: InvocationContext):\n InvocationContext {\n return new InvocationContext({\n ...parentContext,\n agent: this,\n });\n }\n\n /**\n * Runs the before agent callback if it exists.\n *\n * @param invocationContext The invocation context of the agent.\n * @return The event to return to the user, or undefined if no event is\n * generated.\n */\n protected async handleBeforeAgentCallback(\n invocationContext: InvocationContext): Promise<Event|undefined> {\n if (this.beforeAgentCallback.length === 0) {\n return undefined;\n }\n\n const callbackContext = new CallbackContext({invocationContext});\n for (const callback of this.beforeAgentCallback) {\n const content = await callback(callbackContext);\n\n if (content) {\n invocationContext.endInvocation = true;\n\n return createEvent({\n invocationId: invocationContext.invocationId,\n author: this.name,\n branch: invocationContext.branch,\n content,\n actions: callbackContext.eventActions,\n });\n }\n }\n\n if (callbackContext.state.hasDelta()) {\n return createEvent({\n invocationId: invocationContext.invocationId,\n author: this.name,\n branch: invocationContext.branch,\n actions: callbackContext.eventActions,\n });\n }\n\n return undefined;\n }\n\n /**\n * Runs the after agent callback if it exists.\n *\n * @param invocationContext The invocation context of the agent.\n * @return The event to return to the user, or undefined if no event is\n * generated.\n */\n protected async handleAfterAgentCallback(\n invocationContext: InvocationContext): Promise<Event|undefined> {\n if (this.afterAgentCallback.length === 0) {\n return undefined;\n }\n\n const callbackContext = new CallbackContext({invocationContext});\n for (const callback of this.afterAgentCallback) {\n const content = await callback(callbackContext);\n\n if (content) {\n return createEvent({\n invocationId: invocationContext.invocationId,\n author: this.name,\n branch: invocationContext.branch,\n content,\n actions: callbackContext.eventActions,\n });\n }\n }\n\n if (callbackContext.state.hasDelta()) {\n return createEvent({\n invocationId: invocationContext.invocationId,\n author: this.name,\n branch: invocationContext.branch,\n actions: callbackContext.eventActions,\n });\n }\n\n return undefined;\n }\n\n private setParentAgentForSubAgents(): void {\n for (const subAgent of this.subAgents) {\n if (subAgent.parentAgent) {\n throw new Error(`Agent \"${\n subAgent.name}\" already has a parent agent, current parent: \"${\n subAgent.parentAgent.name}\", trying to add: \"${this.name}\"`);\n }\n\n subAgent.parentAgent = this;\n }\n }\n}\n\n/**\n * Validates the agent name.\n *\n * @param name The name of the agent.\n * @return The validated agent name.\n */\nfunction validateAgentName(name: string): string {\n if (!isIdentifier(name)) {\n throw new Error(`Found invalid agent name: \"${\n name}\". Agent name must be a valid identifier. It should start with a letter (a-z, A-Z) or an underscore (_), and can only contain letters, digits (0-9), and underscores.`);\n }\n\n if (name === 'user') {\n throw new Error(\n `Agent name cannot be 'user'. 'user' is reserved for end-user's input.`);\n }\n\n return name;\n}\n\n/**\n * Checks if the given string is a valid identifier.\n *\n * @param str The string to check.\n * @return True if the string is a valid identifier, false otherwise.\n */\nfunction isIdentifier(str: string): boolean {\n return /^[\\p{ID_Start}$_][\\p{ID_Continue}$_]*$/u.test(str);\n}\n\n/**\n * Gets the root agent of the given agent.\n *\n * @param rootAgent The root agent to get the root agent of.\n * @return The root agent.\n */\nfunction getRootAgent(rootAgent: BaseAgent): BaseAgent {\n while (rootAgent.parentAgent) {\n rootAgent = rootAgent.parentAgent;\n }\n\n return rootAgent;\n}\n\n/**\n * Gets the canonical callback from the given callback.\n *\n * @param callbacks The callback or list of callbacks to get the canonical\n * callback from.\n * @return The canonical callback.\n */\nexport function getCannonicalCallback<T>(callbacks?: T|T[]): T[] {\n if (!callbacks) {\n return [];\n }\n\n return Array.isArray(callbacks) ? callbacks : [callbacks];\n}", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {ToolConfirmation} from '../tools/tool_confirmation.js';\n\n// TODO: b/425992518 - Replace 'any' with a proper AuthConfig.\ntype AuthConfig = any;\n\n/**\n * Represents the actions attached to an event.\n */\nexport interface EventActions {\n /**\n * If true, it won't call model to summarize function response.\n * Only used for function_response event.\n */\n skipSummarization?: boolean;\n\n /**\n * Indicates that the event is updating the state with the given delta.\n */\n stateDelta: {[key: string]: unknown};\n\n /**\n * Indicates that the event is updating an artifact. key is the filename,\n * value is the version.\n */\n artifactDelta: {[key: string]: number};\n\n /**\n * If set, the event transfers to the specified agent.\n */\n transferToAgent?: string;\n\n /**\n * The agent is escalating to a higher level agent.\n */\n escalate?: boolean;\n\n /**\n * Authentication configurations requested by tool responses.\n *\n * This field will only be set by a tool response event indicating tool\n * request auth credential.\n * - Keys: The function call id. Since one function response event could\n * contain multiple function responses that correspond to multiple function\n * calls. Each function call could request different auth configs. This id is\n * used to identify the function call.\n * - Values: The requested auth config.\n */\n requestedAuthConfigs: {[key: string]: AuthConfig};\n\n /**\n * A dict of tool confirmation requested by this event, keyed by the function\n * call id.\n */\n requestedToolConfirmations: {[key: string]: ToolConfirmation};\n}\n\n/**\n * Creates an EventActions object.\n */\nexport function createEventActions(state: Partial<EventActions> = {}):\n EventActions {\n return {\n stateDelta: {},\n artifactDelta: {},\n requestedAuthConfigs: {},\n requestedToolConfirmations: {},\n ...state,\n };\n}\n\n/**\n * Merges a list of EventActions objects into a single EventActions object.\n *\n * 1. It merges dictionaries (stateDelta, artifactDelta, requestedAuthConfigs)\n * by adding all the properties from each source.\n *\n * 2. For other properties (skipSummarization,transferToAgent, escalate), the\n * last one wins.\n */\nexport function mergeEventActions(\n sources: Array<Partial<EventActions>>,\n target?: EventActions): EventActions {\n const result = createEventActions();\n\n if (target) {\n Object.assign(result, target);\n }\n\n for (const source of sources) {\n if (!source) continue;\n\n if (source.stateDelta) {\n Object.assign(result.stateDelta, source.stateDelta);\n }\n if (source.artifactDelta) {\n Object.assign(result.artifactDelta, source.artifactDelta);\n }\n if (source.requestedAuthConfigs) {\n Object.assign(result.requestedAuthConfigs, source.requestedAuthConfigs);\n }\n if (source.requestedToolConfirmations) {\n Object.assign(\n result.requestedToolConfirmations, source.requestedToolConfirmations);\n }\n\n if (source.skipSummarization !== undefined) {\n result.skipSummarization = source.skipSummarization;\n }\n if (source.transferToAgent !== undefined) {\n result.transferToAgent = source.transferToAgent;\n }\n if (source.escalate !== undefined) {\n result.escalate = source.escalate;\n }\n }\n return result;\n}", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {FunctionCall, FunctionResponse} from '@google/genai';\n\nimport {LlmResponse} from '../models/llm_response.js';\n\nimport {createEventActions, EventActions} from './event_actions.js';\n\n/**\n * Represents an event in a conversation between agents and users.\n\n It is used to store the content of the conversation, as well as the actions\n taken by the agents like function calls, etc.\n */\nexport interface Event extends LlmResponse {\n /**\n * The unique identifier of the event.\n * Do not assign the ID. It will be assigned by the session.\n */\n id: string;\n\n /**\n * The invocation ID of the event. Should be non-empty before appending to a\n * session.\n */\n invocationId: string;\n\n /**\n * \"user\" or the name of the agent, indicating who appended the event to the\n * session.\n */\n author?: string;\n\n /**\n * The actions taken by the agent.\n */\n actions: EventActions;\n\n /**\n * Set of ids of the long running function calls. Agent client will know from\n * this field about which function call is long running. Only valid for\n * function call event\n */\n longRunningToolIds?: string[];\n\n /**\n * The branch of the event.\n * The format is like agent_1.agent_2.agent_3, where agent_1 is the parent of\n * agent_2, and agent_2 is the parent of agent_3.\n *\n * Branch is used when multiple sub-agent shouldn't see their peer agents'\n * conversation history.\n */\n branch?: string;\n\n /**\n * The timestamp of the event.\n */\n timestamp: number;\n}\n\n/**\n * Creates an event from a partial event.\n *\n * @param params The partial event to create the event from.\n * @returns The event.\n */\nexport function createEvent(params: Partial<Event> = {}): Event {\n return {\n ...params,\n id: params.id || createNewEventId(),\n invocationId: params.invocationId || '',\n author: params.author,\n actions: params.actions || createEventActions(),\n longRunningToolIds: params.longRunningToolIds || [],\n branch: params.branch,\n timestamp: params.timestamp || Date.now(),\n };\n}\n\n/**\n * Returns whether the event is the final response of the agent.\n */\nexport function isFinalResponse(event: Event) {\n if (event.actions.skipSummarization ||\n (event.longRunningToolIds && event.longRunningToolIds.length > 0)) {\n return true;\n }\n\n return (\n getFunctionCalls(event).length === 0 &&\n getFunctionResponses(event).length === 0 && !event.partial &&\n !hasTrailingCodeExecutionResult(event));\n}\n\n/**\n * Returns the function calls in the event.\n */\nexport function getFunctionCalls(event: Event): FunctionCall[] {\n const funcCalls = [];\n if (event.content && event.content.parts) {\n for (const part of event.content.parts) {\n if (part.functionCall) {\n funcCalls.push(part.functionCall);\n }\n }\n }\n\n return funcCalls;\n}\n\n/**\n * Returns the function responses in the event.\n */\nexport function getFunctionResponses(event: Event): FunctionResponse[] {\n const funcResponses = [];\n if (event.content && event.content.parts) {\n for (const part of event.content.parts) {\n if (part.functionResponse) {\n funcResponses.push(part.functionResponse);\n }\n }\n }\n\n return funcResponses;\n}\n\n/**\n * Returns whether the event has a trailing code execution result.\n */\nexport function hasTrailingCodeExecutionResult(event: Event): boolean {\n if (event.content && event.content.parts?.length) {\n const lastPart = event.content.parts[event.content.parts.length - 1];\n return lastPart.codeExecutionResult !== undefined;\n }\n\n return false;\n}\n\n/**\n * Extracts and concatenates all text from the parts of a `Event` object.\n * @param event The `Event` object to process.\n *\n * @returns A single string with the combined text.\n */\nexport function stringifyContent(event: Event): string {\n if (!event.content?.parts) {\n return '';\n }\n\n return event.content.parts.map(part => part.text ?? '').join('');\n}\n\nconst ASCII_LETTERS_AND_NUMBERS =\n 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';\n\n/**\n * Generates a new unique ID for the event.\n */\nexport function createNewEventId(): string {\n let id = '';\n\n for (let i = 0; i < 8; i++) {\n id += ASCII_LETTERS_AND_NUMBERS[Math.floor(\n Math.random() * ASCII_LETTERS_AND_NUMBERS.length)];\n }\n\n return id;\n}", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * A state mapping that maintains the current value and the pending-commit\n * delta.\n */\nexport class State {\n static readonly APP_PREFIX = 'app:';\n static readonly USER_PREFIX = 'user:';\n static readonly TEMP_PREFIX = 'temp:';\n\n constructor(\n /** The current value of the state. */\n private value: Record<string, unknown> = {},\n /** The delta change to the current value that hasn't been committed. */\n private delta: Record<string, unknown> = {},\n ) {}\n\n /**\n * Returns the value of the state dict for the given key.\n *\n * @param key The key to get the value for.\n * @param defaultValue The default value to return if the key is not found.\n * @return The value of the state for the given key, or the default value if\n * not found.\n */\n get<T>(key: string, defaultValue?: T): T|undefined {\n if (key in this.delta) {\n return this.delta[key] as T;\n }\n\n if (key in this.value) {\n return this.value[key] as T;\n }\n\n return defaultValue;\n }\n\n /**\n * Sets the value of the state dict for the given key.\n *\n * @param key The key to set the value for.\n * @param value The value to set.\n */\n set(key: string, value: unknown) {\n this.value[key] = value;\n this.delta[key] = value;\n }\n\n /**\n * Whether the state has pending delta.\n */\n has(key: string): boolean {\n return key in this.value || key in this.delta;\n }\n\n /**\n * Whether the state has pending delta.\n */\n hasDelta(): boolean {\n return Object.keys(this.delta).length > 0;\n }\n\n /**\n * Updates the state dict with the given delta.\n *\n * @param delta The delta to update the state with.\n */\n update(delta: Record<string, unknown>) {\n this.delta = {...this.delta, ...delta};\n this.value = {...this.value, ...delta};\n }\n\n /**\n * Returns the state as a plain JSON object.\n */\n toRecord(): Record<string, unknown> {\n return {...this.value, ...this.delta};\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Content} from '@google/genai';\n\nimport {State} from '../sessions/state.js';\n\nimport {InvocationContext} from './invocation_context.js';\n\n/**\n * A readonly context represents the data of a single invocation of an agent.\n */\nexport class ReadonlyContext {\n constructor(readonly invocationContext: InvocationContext) {}\n\n /**\n * The user content that started this invocation.\n */\n get userContent(): Content|undefined {\n return this.invocationContext.userContent;\n }\n\n /**\n * The current invocation id.\n */\n get invocationId(): string {\n return this.invocationContext.invocationId;\n }\n\n /**\n * The current agent name.\n */\n get agentName(): string {\n return this.invocationContext.agent.name;\n }\n\n /**\n * The state of the current session.\n */\n get state(): Readonly<State> {\n return new State(this.invocationContext.session.state, {}) as\n Readonly<State>;\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Part} from '@google/genai';\n\nimport {createEventActions, EventActions} from '../events/event_actions.js';\nimport {State} from '../sessions/state.js';\n\nimport {InvocationContext} from './invocation_context.js';\nimport {ReadonlyContext} from './readonly_context.js';\n\n/**\n * The context of various callbacks within an agent run.\n */\nexport class CallbackContext extends ReadonlyContext {\n private readonly _state: State;\n\n readonly eventActions: EventActions;\n\n constructor({invocationContext, eventActions}: {\n invocationContext: InvocationContext,\n eventActions?: EventActions,\n }) {\n super(invocationContext);\n this.eventActions = eventActions || createEventActions();\n this._state = new State(\n invocationContext.session.state,\n this.eventActions.stateDelta,\n );\n }\n\n /**\n * The delta-aware state of the current session.\n */\n override get state() {\n return this._state;\n }\n\n /**\n * Loads an artifact attached to the current session.\n *\n * @param filename The filename of the artifact.\n * @param version The version of the artifact. If not provided, the latest\n * version will be used.\n * @return A promise that resolves to the loaded artifact.\n */\n loadArtifact(filename: string, version?: number): Promise<Part|undefined> {\n if (!this.invocationContext.artifactService) {\n throw new Error('Artifact service is not initialized.');\n }\n\n return this.invocationContext.artifactService.loadArtifact({\n appName: this.invocationContext.appName,\n userId: this.invocationContext.userId,\n sessionId: this.invocationContext.session.id,\n filename,\n version,\n });\n }\n\n /**\n * Saves an artifact attached to the current session.\n *\n * @param filename The filename of the artifact.\n * @param artifact The artifact to save.\n * @return A promise that resolves to the version of the saved artifact.\n */\n async saveArtifact(filename: string, artifact: Part): Promise<number> {\n if (!this.invocationContext.artifactService) {\n throw new Error('Artifact service is not initialized.');\n }\n\n const version = await this.invocationContext.artifactService.saveArtifact({\n appName: this.invocationContext.appName,\n userId: this.invocationContext.userId,\n sessionId: this.invocationContext.session.id,\n filename,\n artifact,\n });\n this.eventActions.artifactDelta[filename] = version;\n\n return version;\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * Returns true if the environment is a browser.\n */\nexport function isBrowser() {\n return typeof window !== 'undefined';\n}\n\n/**\n * Generates a random UUID.\n */\nconst UUID_MASK = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';\nexport function randomUUID() {\n let uuid = '';\n\n for (let i = 0; i < UUID_MASK.length; i++) {\n const randomValue = (Math.random() * 16) | 0;\n\n if (UUID_MASK[i] === 'x') {\n uuid += randomValue.toString(16);\n } else if (UUID_MASK[i] === 'y') {\n uuid += ((randomValue & 0x3) | 0x8).toString(16);\n } else {\n uuid += UUID_MASK[i];\n }\n }\n\n return uuid;\n}\n\n/**\n * Encodes the given string to base64.\n *\n * @param data The string to encode.\n * @return The base64-encoded string.\n */\nexport function base64Encode(data: string): string {\n if (isBrowser()) {\n return window.btoa(data);\n }\n\n return Buffer.from(data).toString('base64');\n}\n\n/**\n * Decodes the given base64 string to a string.\n *\n * @param data The base64-encoded string.\n * @return The decoded string.\n */\nexport function base64Decode(data: string): string {\n if (isBrowser()) {\n return window.atob(data);\n }\n\n return Buffer.from(data, 'base64').toString();\n}\n\n/**\n * Checks if the given string is base64-encoded.\n *\n * @param data The string to check.\n * @return True if the string is base64-encoded, false otherwise.\n */\nexport function isBase64Encoded(data: string): boolean {\n try {\n return base64Encode(base64Decode(data)) === data;\n } catch (e) {\n return false;\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Content} from '@google/genai';\n\nimport {BaseArtifactService} from '../artifacts/base_artifact_service.js';\nimport {BaseCredentialService} from '../auth/credential_service/base_credential_service.js';\nimport {BaseMemoryService} from '../memory/base_memory_service.js';\nimport {PluginManager} from '../plugins/plugin_manager.js';\nimport {BaseSessionService} from '../sessions/base_session_service.js';\nimport {Session} from '../sessions/session.js';\nimport {randomUUID} from '../utils/env_aware_utils.js';\n\nimport {ActiveStreamingTool} from './active_streaming_tool.js';\nimport {BaseAgent} from './base_agent.js';\nimport {LiveRequestQueue} from './live_request_queue.js';\nimport {RunConfig} from './run_config.js';\nimport {TranscriptionEntry} from './transcription_entry.js';\n\ninterface InvocationContextParams {\n artifactService?: BaseArtifactService;\n sessionService?: BaseSessionService;\n memoryService?: BaseMemoryService;\n credentialService?: BaseCredentialService;\n invocationId: string;\n branch?: string;\n agent: BaseAgent;\n userContent?: Content;\n session: Session;\n endInvocation?: boolean;\n transcriptionCache?: TranscriptionEntry[];\n runConfig?: RunConfig;\n liveRequestQueue?: LiveRequestQueue;\n activeStreamingTools?: Record<string, ActiveStreamingTool>;\n pluginManager: PluginManager;\n}\n\n/**\n * A container to keep track of the cost of invocation.\n *\n * While we don't expect the metrics captured here to be a direct\n * representative of monetary cost incurred in executing the current\n * invocation, they in some ways have an indirect effect.\n */\nclass InvocationCostManager {\n private numberOfLlmCalls: number = 0;\n\n /**\n * Increments the number of llm calls and enforces the limit.\n *\n * @param runConfig the run config of the invocation.\n * @throws If number of llm calls made exceed the set threshold.\n */\n incrementAndEnforceLlmCallsLimit(runConfig?: RunConfig) {\n this.numberOfLlmCalls++;\n\n if (runConfig && runConfig.maxLlmCalls! > 0 &&\n this.numberOfLlmCalls > runConfig.maxLlmCalls!) {\n throw new Error(`Max number of llm calls limit of ${\n runConfig.maxLlmCalls!} exceeded`);\n }\n }\n}\n\n/**\n * An invocation context represents the data of a single invocation of an agent.\n *\n * An invocation:\n * 1. Starts with a user message and ends with a final response.\n * 2. Can contain one or multiple agent calls.\n * 3. Is handled by runner.runAsync().\n *\n * An invocation runs an agent until it does not request to transfer to\n * another agent.\n *\n * An agent call:\n * 1. Is handled by agent.runAsync().\n * 2. Ends when agent.runAsync() ends.\n *\n * An LLM agent call is an agent with a BaseLLMFlow.\n * An LLM agent call can contain one or multiple steps.\n *\n * An LLM agent runs steps in a loop until:\n * 1. A final response is generated.\n * 2. The agent transfers to another agent.\n * 3. The end_invocation is set to true by any callbacks or tools.\n *\n * A step:\n * 1. Calls the LLM only once and yields its response.\n * 2. Calls the tools and yields their responses if requested.\n *\n * The summarization of the function response is considered another step, since\n * it is another llm call.\n * A step ends when it's done calling llm and tools, or if the end_invocation\n * is set to true at any time.\n *\n * ```\n * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 invocation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 llm_agent_call_1 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250C\u2500 agent_call_2 \u2500\u2510\n * \u250C\u2500\u2500\u2500\u2500 step_1 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250C\u2500\u2500\u2500\u2500\u2500 step_2 \u2500\u2500\u2500\u2500\u2500\u2500\u2510\n * [call_llm] [call_tool] [call_llm] [transfer]\n * ```\n */\nexport class InvocationContext {\n readonly artifactService?: BaseArtifactService;\n readonly sessionService?: BaseSessionService;\n readonly memoryService?: BaseMemoryService;\n readonly credentialService?: BaseCredentialService;\n\n /**\n * The id of this invocation context.\n */\n readonly invocationId: string;\n\n /**\n * The branch of the invocation context.\n *\n * The format is like agent_1.agent_2.agent_3, where agent_1 is the parent of\n * agent_2, and agent_2 is the parent of agent_3.\n *\n * Branch is used when multiple sub-agents shouldn't see their peer agents'\n * conversation history.\n */\n branch?: string;\n\n /**\n * The current agent of this invocation context.\n */\n agent: BaseAgent;\n\n /**\n * The user content that started this invocation.\n */\n readonly userContent?: Content;\n\n /**\n * The current session of this invocation context.\n */\n readonly session: Session;\n\n /**\n * Whether to end this invocation.\n * Set to True in callbacks or tools to terminate this invocation.\n */\n endInvocation: boolean;\n\n /**\n * Caches necessary, data audio or contents, that are needed by transcription.\n */\n transcriptionCache?: TranscriptionEntry[];\n\n /**\n * Configurations for live agents under this invocation.\n */\n runConfig?: RunConfig;\n\n /**\n * A container to keep track of different kinds of costs incurred as a part of\n * this invocation.\n */\n private readonly invocationCostManager = new InvocationCostManager();\n\n /**\n * The queue to receive live requests.\n */\n liveRequestQueue?: LiveRequestQueue;\n\n /**\n * The running streaming tools of this invocation.\n */\n activeStreamingTools?: Record<string, ActiveStreamingTool>;\n\n /**\n * The manager for keeping track of plugins in this invocation.\n */\n pluginManager: PluginManager;\n\n /**\n * @param params The parameters for creating an invocation context.\n */\n constructor(params: InvocationContextParams) {\n this.artifactService = params.artifactService;\n this.sessionService = params.sessionService;\n this.memoryService = params.memoryService;\n this.invocationId = params.invocationId;\n this.branch = params.branch;\n this.agent = params.agent;\n this.userContent = params.userContent;\n this.session = params.session;\n this.endInvocation = params.endInvocation || false;\n this.transcriptionCache = params.transcriptionCache;\n this.runConfig = params.runConfig;\n this.liveRequestQueue = params.liveRequestQueue;\n this.activeStreamingTools = params.activeStreamingTools;\n this.pluginManager = params.pluginManager;\n }\n\n /**\n * The app name of the current session.\n */\n get appName() {\n return this.session.appName;\n }\n\n /**\n * The user ID of the current session.\n */\n get userId() {\n return this.session.userId;\n }\n\n /**\n * Tracks number of llm calls made.\n *\n * @throws If number of llm calls made exceed the set threshold.\n */\n incrementLlmCallCount() {\n this.invocationCostManager.incrementAndEnforceLlmCallsLimit(this.runConfig);\n }\n}\n\nexport function newInvocationContextId(): string {\n return `e-${randomUUID()}`;\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\n// TODO - b/436079721: implement traceMergedToolCalls, traceToolCall, tracer.\nimport {Content, createUserContent, FunctionCall, Part} from '@google/genai';\n\nimport {InvocationContext} from '../agents/invocation_context.js';\nimport {createEvent, Event, getFunctionCalls} from '../events/event.js';\nimport {mergeEventActions} from '../events/event_actions.js';\nimport {BaseTool} from '../tools/base_tool.js';\nimport {ToolConfirmation} from '../tools/tool_confirmation.js';\nimport {ToolContext} from '../tools/tool_context.js';\nimport {randomUUID} from '../utils/env_aware_utils.js';\nimport {logger} from '../utils/logger.js';\n\nimport {SingleAfterToolCallback, SingleBeforeToolCallback} from './llm_agent.js';\n\nconst AF_FUNCTION_CALL_ID_PREFIX = 'adk-';\nexport const REQUEST_EUC_FUNCTION_CALL_NAME = 'adk_request_credential';\nexport const REQUEST_CONFIRMATION_FUNCTION_CALL_NAME =\n 'adk_request_confirmation';\n\n// Export these items for testing purposes only\nexport const functionsExportedForTestingOnly = {\n handleFunctionCallList,\n};\n\nexport function generateClientFunctionCallId(): string {\n return `${AF_FUNCTION_CALL_ID_PREFIX}${randomUUID()}`;\n}\n\n/**\n * Populates client-side function call IDs.\n *\n * It iterates through all function calls in the event and assigns a\n * unique client-side ID to each one that doesn't already have an ID.\n */\n// TODO - b/425992518: consider move into event.ts\nexport function populateClientFunctionCallId(\n modelResponseEvent: Event,\n ): void {\n const functionCalls = getFunctionCalls(modelResponseEvent);\n if (!functionCalls) {\n return;\n }\n for (const functionCall of functionCalls) {\n if (!functionCall.id) {\n functionCall.id = generateClientFunctionCallId();\n }\n }\n}\n// TODO - b/425992518: consider internalize in content_[processor].ts\n/**\n * Removes the client-generated function call IDs from a given content object.\n *\n * When sending content back to the server, these IDs are\n * specific to the client-side and should not be included in requests to the\n * model.\n */\nexport function removeClientFunctionCallId(content: Content): void {\n if (content && content.parts) {\n for (const part of content.parts) {\n if (part.functionCall && part.functionCall.id &&\n part.functionCall.id.startsWith(AF_FUNCTION_CALL_ID_PREFIX)) {\n part.functionCall.id = undefined;\n }\n if (part.functionResponse && part.functionResponse.id &&\n part.functionResponse.id.startsWith(AF_FUNCTION_CALL_ID_PREFIX)) {\n part.functionResponse.id = undefined;\n }\n }\n }\n}\n// TODO - b/425992518: consider internalize as part of llm_agent's runtime.\n/**\n * Returns a set of function call ids of the long running tools.\n */\nexport function getLongRunningFunctionCalls(\n functionCalls: FunctionCall[],\n toolsDict: Record<string, BaseTool>,\n ): Set<string> {\n const longRunningToolIds = new Set<string>();\n for (const functionCall of functionCalls) {\n if (functionCall.name && functionCall.name in toolsDict &&\n toolsDict[functionCall.name].isLongRunning && functionCall.id) {\n longRunningToolIds.add(functionCall.id);\n }\n }\n return longRunningToolIds;\n}\n\n// TODO - b/425992518: consider internalize as part of llm_agent's runtime.\n// The auth part of function calling is a bit hacky, need to to clarify.\n/**\n * Generates an authentication event.\n *\n * It iterates through requested auth configurations in a function response\n * event and creates a new function call for each.\n */\nexport function generateAuthEvent(\n invocationContext: InvocationContext,\n functionResponseEvent: Event,\n ): Event|undefined {\n if (!functionResponseEvent.actions?.requestedAuthConfigs) {\n return undefined;\n }\n const parts: Part[] = [];\n const longRunningToolIds = new Set<string>();\n for (const [functionCallId, authConfig] of Object.entries(\n functionResponseEvent.actions.requestedAuthConfigs,\n )) {\n const requestEucFunctionCall: FunctionCall = {\n name: REQUEST_EUC_FUNCTION_CALL_NAME,\n args: {\n 'function_call_id': functionCallId,\n 'auth_config': authConfig,\n },\n id: generateClientFunctionCallId(),\n };\n longRunningToolIds.add(requestEucFunctionCall.id!);\n parts.push({functionCall: requestEucFunctionCall});\n }\n\n return createEvent({\n invocationId: invocationContext.invocationId,\n author: invocationContext.agent.name,\n branch: invocationContext.branch,\n content: {\n parts: parts,\n role: functionResponseEvent.content!.role,\n },\n longRunningToolIds: Array.from(longRunningToolIds),\n });\n}\n\n/**\n * Generates a request confirmation event from a function response event.\n */\nexport function generateRequestConfirmationEvent({\n invocationContext,\n functionCallEvent,\n functionResponseEvent,\n}: {\n invocationContext: InvocationContext,\n functionCallEvent: Event,\n functionResponseEvent: Event\n}): Event|undefined {\n if (!functionResponseEvent.actions?.requestedToolConfirmations) {\n return;\n }\n const parts: Part[] = [];\n const longRunningToolIds = new Set<string>();\n const functionCalls = getFunctionCalls(functionCallEvent);\n\n for (const [functionCallId, toolConfirmation] of Object.entries(\n functionResponseEvent.actions.requestedToolConfirmations,\n )) {\n const originalFunctionCall =\n functionCalls.find(call => call.id === functionCallId) ?? undefined;\n if (!originalFunctionCall) {\n continue;\n }\n const requestConfirmationFunctionCall: FunctionCall = {\n name: REQUEST_CONFIRMATION_FUNCTION_CALL_NAME,\n args: {\n 'originalFunctionCall': originalFunctionCall,\n 'toolConfirmation': toolConfirmation,\n },\n id: generateClientFunctionCallId(),\n };\n longRunningToolIds.add(requestConfirmationFunctionCall.id!);\n parts.push({functionCall: requestConfirmationFunctionCall});\n }\n return createEvent({\n invocationId: invocationContext.invocationId,\n author: invocationContext.agent.name,\n branch: invocationContext.branch,\n content: {\n parts: parts,\n role: functionResponseEvent.content!.role,\n },\n longRunningToolIds: Array.from(longRunningToolIds),\n });\n}\n\nasync function callToolAsync(\n tool: BaseTool,\n args: Record<string, any>,\n toolContext: ToolContext,\n ): Promise<any> {\n // TODO - b/436079721: implement [tracer.start_as_current_span]\n logger.debug(`callToolAsync ${tool.name}`);\n return await tool.runAsync({args, toolContext});\n}\n\n/**\n * Handles function calls.\n * Runtime behavior to pay attention to:\n * - Iterate through each function call in the `functionCallEvent`:\n * - Execute before tool callbacks !!if a callback provides a response, short\n * circuit the rest.\n * - Execute the tool.\n * - Execute after tool callbacks !!if a callback provides a response, short\n * circuit the rest.\n * - If the tool is long-running and the response is null, continue. !!state\n * - Merge all function response events into a single event.\n */\nexport async function handleFunctionCallsAsync({\n invocationContext,\n functionCallEvent,\n toolsDict,\n beforeToolCallbacks,\n afterToolCallbacks,\n filters,\n toolConfirmationDict,\n}: {\n invocationContext: InvocationContext,\n functionCallEvent: Event,\n toolsDict: Record<string, BaseTool>,\n beforeToolCallbacks: SingleBeforeToolCallback[],\n afterToolCallbacks: SingleAfterToolCallback[],\n filters?: Set<string>,\n toolConfirmationDict?: Record<string, ToolConfirmation>,\n}): Promise<Event|null> {\n const functionCalls = getFunctionCalls(functionCallEvent);\n return await handleFunctionCallList({\n invocationContext: invocationContext,\n functionCalls: functionCalls,\n toolsDict: toolsDict,\n beforeToolCallbacks: beforeToolCallbacks,\n afterToolCallbacks: afterToolCallbacks,\n filters: filters,\n toolConfirmationDict: toolConfirmationDict,\n });\n}\n\n/**\n * The underlying implementation of handleFunctionCalls, but takes a list of\n * function calls instead of an event.\n * This is also used by llm_agent execution flow in preprocessing.\n */\nexport async function handleFunctionCallList({\n invocationContext,\n functionCalls,\n toolsDict,\n beforeToolCallbacks,\n afterToolCallbacks,\n filters,\n toolConfirmationDict,\n}: {\n invocationContext: InvocationContext,\n functionCalls: FunctionCall[],\n toolsDict: Record<string, BaseTool>,\n beforeToolCallbacks: SingleBeforeToolCallback[],\n afterToolCallbacks: SingleAfterToolCallback[],\n filters?: Set<string>,\n toolConfirmationDict?: Record<string, ToolConfirmation>,\n}): Promise<Event|null> {\n const functionResponseEvents: Event[] = [];\n\n // Note: only function ids INCLUDED in the filters will be executed.\n const filteredFunctionCalls = functionCalls.filter(functionCall => {\n return !filters || (functionCall.id && filters.has(functionCall.id));\n });\n\n for (const functionCall of filteredFunctionCalls) {\n let toolConfirmation = undefined;\n if (toolConfirmationDict && functionCall.id) {\n toolConfirmation = toolConfirmationDict[functionCall.id];\n }\n\n const {tool, toolContext} = getToolAndContext(\n {\n invocationContext,\n functionCall,\n toolsDict,\n toolConfirmation,\n },\n );\n\n // TODO - b/436079721: implement [tracer.start_as_current_span]\n logger.debug(`execute_tool ${tool.name}`);\n const functionArgs = functionCall.args ?? {};\n\n // Step 1: Check if plugin before_tool_callback overrides the function\n // response.\n let functionResponse = null;\n let functionResponseError: string|unknown|undefined;\n functionResponse =\n await invocationContext.pluginManager.runBeforeToolCallback({\n tool: tool,\n toolArgs: functionArgs,\n toolContext: toolContext,\n });\n\n // Step 2: If no overrides are provided from the plugins, further run the\n // canonical callback.\n // TODO - b/425992518: validate the callback response type matches.\n if (functionResponse == null) { // Cover both null and undefined\n for (const callback of beforeToolCallbacks) {\n functionResponse = await callback({\n tool: tool,\n args: functionArgs,\n context: toolContext,\n });\n if (functionResponse) {\n break;\n }\n }\n }\n\n // Step 3: Otherwise, proceed calling the tool normally.\n if (functionResponse == null) { // Cover both null and undefined\n try {\n functionResponse = await callToolAsync(\n tool,\n functionArgs,\n toolContext,\n );\n } catch (e: unknown) {\n if (e instanceof Error) {\n const onToolErrorResponse =\n await invocationContext.pluginManager.runOnToolErrorCallback(\n {\n tool: tool,\n toolArgs: functionArgs,\n toolContext: toolContext,\n error: e,\n },\n );\n\n // Set function response to the result of the error callback and\n // continue execution, do not shortcut\n if (onToolErrorResponse) {\n functionResponse = onToolErrorResponse;\n } else {\n // If the error callback returns undefined, use the error message\n // as the function response error.\n functionResponseError = e.message;\n }\n } else {\n // If the error is not an Error, use the error object as the function\n // response error.\n functionResponseError = e;\n }\n }\n }\n\n // Step 4: Check if plugin after_tool_callback overrides the function\n // response.\n let alteredFunctionResponse =\n await invocationContext.pluginManager.runAfterToolCallback({\n tool: tool,\n toolArgs: functionArgs,\n toolContext: toolContext,\n result: functionResponse,\n });\n\n // Step 5: If no overrides are provided from the plugins, further run the\n // canonical after_tool_callbacks.\n if (alteredFunctionResponse == null) { // Cover both null and undefined\n for (const callback of afterToolCallbacks) {\n alteredFunctionResponse = await callback({\n tool: tool,\n args: functionArgs,\n context: toolContext,\n response: functionResponse,\n });\n if (alteredFunctionResponse) {\n break;\n }\n }\n }\n\n // Step 6: If alternative response exists from after_tool_callback, use it\n // instead of the original function response.\n if (alteredFunctionResponse != null) {\n functionResponse = alteredFunctionResponse;\n }\n\n // TODO - b/425992518: state event polluting runtime, consider fix.\n // Allow long running function to return None as response.\n if (tool.isLongRunning && !functionResponse) {\n continue;\n }\n\n if (functionResponseError) {\n functionResponse = {error: functionResponseError};\n } else if (\n typeof functionResponse !== 'object' || functionResponse == null) {\n functionResponse = {result: functionResponse};\n }\n\n // Builds the function response event.\n const functionResponseEvent = createEvent({\n invocationId: invocationContext.invocationId,\n author: invocationContext.agent.name,\n content: createUserContent({\n functionResponse: {\n id: toolContext.functionCallId,\n name: tool.name,\n response: functionResponse,\n },\n }),\n actions: toolContext.actions,\n branch: invocationContext.branch,\n });\n\n // TODO - b/436079721: implement [traceToolCall]\n logger.debug('traceToolCall', {\n tool: tool.name,\n args: functionArgs,\n functionResponseEvent: functionResponseEvent.id,\n });\n functionResponseEvents.push(functionResponseEvent);\n }\n\n if (!functionResponseEvents.length) {\n return null;\n }\n const mergedEvent =\n mergeParallelFunctionResponseEvents(functionResponseEvents);\n\n if (functionResponseEvents.length > 1) {\n // TODO - b/436079721: implement [tracer.start_as_current_span]\n logger.debug('execute_tool (merged)');\n // TODO - b/436079721: implement [traceMergedToolCalls]\n logger.debug('traceMergedToolCalls', {\n responseEventId: mergedEvent.id,\n functionResponseEvent: mergedEvent.id,\n });\n }\n return mergedEvent;\n}\n\n// TODO - b/425992518: consider inline, which is much cleaner.\nfunction getToolAndContext(\n {\n invocationContext,\n functionCall,\n toolsDict,\n toolConfirmation,\n }: {\n invocationContext: InvocationContext,\n functionCall: FunctionCall,\n toolsDict: Record<string, BaseTool>,\n toolConfirmation?: ToolConfirmation,\n },\n ): {tool: BaseTool; toolContext: ToolContext} {\n if (!functionCall.name || !(functionCall.name in toolsDict)) {\n throw new Error(\n `Function ${functionCall.name} is not found in the toolsDict.`,\n );\n }\n\n const toolContext = new ToolContext({\n invocationContext: invocationContext,\n functionCallId: functionCall.id || undefined,\n toolConfirmation,\n });\n\n const tool = toolsDict[functionCall.name];\n\n return {tool, toolContext};\n}\n\n/**\n * Merges a list of function response events into a single event.\n */\n// TODO - b/425992518: may not need export. Can be conslidated into Event.\nexport function mergeParallelFunctionResponseEvents(\n functionResponseEvents: Event[],\n ): Event {\n if (!functionResponseEvents.length) {\n throw new Error('No function response events provided.');\n }\n\n if (functionResponseEvents.length === 1) {\n return functionResponseEvents[0];\n }\n const mergedParts: Part[] = [];\n for (const event of functionResponseEvents) {\n if (event.content && event.content.parts) {\n mergedParts.push(...event.content.parts);\n }\n }\n\n const baseEvent = functionResponseEvents[0];\n\n const actionsList = functionResponseEvents.map(event => event.actions || {});\n const mergedActions = mergeEventActions(actionsList);\n\n return createEvent({\n author: baseEvent.author,\n branch: baseEvent.branch,\n content: {role: 'user', parts: mergedParts},\n actions: mergedActions,\n timestamp: baseEvent.timestamp!,\n });\n}\n\n// TODO - b/425992518: support function call in live connection.\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {State} from '../sessions/state.js';\n\nimport {AuthCredential} from './auth_credential.js';\nimport {AuthConfig} from './auth_tool.js';\n\n// TODO(b/425992518): Implement the rest\n/**\n * A handler that handles the auth flow in Agent Development Kit to help\n * orchestrates the credential request and response flow (e.g. OAuth flow)\n * This class should only be used by Agent Development Kit.\n */\nexport class AuthHandler {\n constructor(private readonly authConfig: AuthConfig) {}\n\n getAuthResponse(state: State): AuthCredential|undefined {\n const credentialKey = 'temp:' + this.authConfig.credentialKey;\n\n return state.get<AuthCredential>(credentialKey);\n }\n\n generateAuthRequest(): AuthConfig {\n const authSchemeType = this.authConfig.authScheme.type;\n\n if (!['oauth2', 'openIdConnect'].includes(authSchemeType)) {\n return this.authConfig;\n }\n\n if (this.authConfig.exchangedAuthCredential?.oauth2?.authUri) {\n return this.authConfig;\n }\n\n if (!this.authConfig.rawAuthCredential) {\n throw new Error(`Auth Scheme ${authSchemeType} requires authCredential.`);\n }\n\n if (!this.authConfig.rawAuthCredential.oauth2) {\n throw new Error(\n `Auth Scheme ${authSchemeType} requires oauth2 in authCredential.`);\n }\n\n if (this.authConfig.rawAuthCredential.oauth2.authUri) {\n return {\n credentialKey: this.authConfig.credentialKey,\n authScheme: this.authConfig.authScheme,\n rawAuthCredential: this.authConfig.rawAuthCredential,\n exchangedAuthCredential: this.authConfig.rawAuthCredential,\n };\n }\n\n if (!this.authConfig.rawAuthCredential.oauth2.clientId ||\n !this.authConfig.rawAuthCredential.oauth2.clientSecret) {\n throw new Error(`Auth Scheme ${\n authSchemeType} requires both clientId and clientSecret in authCredential.oauth2.`);\n }\n\n return {\n credentialKey: this.authConfig.credentialKey,\n authScheme: this.authConfig.authScheme,\n rawAuthCredential: this.authConfig.rawAuthCredential,\n exchangedAuthCredential: this.generateAuthUri(),\n };\n }\n\n /**\n * Generates an response containing the auth uri for user to sign in.\n *\n * @return An AuthCredential object containing the auth URI and state.\n * @throws Error: If the authorization endpoint is not configured in the\n * auth scheme.\n */\n generateAuthUri(): AuthCredential|undefined {\n return this.authConfig.rawAuthCredential;\n // TODO - b/425992518: Implement the rest of the function\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * Represents a tool confirmation configuration.\n * @experimental (Experimental, subject to change)\n */\nexport class ToolConfirmation {\n /** The hint text for why the input is needed. */\n hint: string;\n\n /** Whether the tool excution is confirmed. */\n confirmed: boolean;\n\n /**\n * The custom data payload needed from the user to continue the flow.\n * It should be JSON serializable.\n */\n payload?: unknown;\n\n constructor({\n hint,\n confirmed,\n payload,\n }: {\n hint?: string, confirmed: boolean,\n payload?: unknown,\n }) {\n this.hint = hint ?? '';\n this.confirmed = confirmed;\n this.payload = payload;\n }\n}", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {CallbackContext} from '../agents/callback_context.js';\nimport {InvocationContext} from '../agents/invocation_context.js';\nimport {AuthCredential} from '../auth/auth_credential.js';\nimport {AuthHandler} from '../auth/auth_handler.js';\nimport {AuthConfig} from '../auth/auth_tool.js';\nimport {EventActions} from '../events/event_actions.js';\nimport {SearchMemoryResponse} from '../memory/base_memory_service.js';\nimport {ToolConfirmation} from '../tools/tool_confirmation.js';\n\n/*\n * The context of the tool.\n *\n * This class provides the context for a tool invocation, including access to\n * the invocation context, function call ID, event actions, and authentication\n * response. It also provides methods for requesting credentials, retrieving\n * authentication responses, listing artifacts, and searching memory.\n */\nexport class ToolContext extends CallbackContext {\n readonly functionCallId?: string;\n toolConfirmation?: ToolConfirmation;\n\n /**\n * @param params.invocationContext The invocation context of the tool.\n * @param params.eventActions The event actions of the current tool call.\n * @param params.functionCallId The function call id of the current tool call.\n * This id was returned in the function call event from LLM to identify a\n * function call. If LLM didn't return this id, ADK will assign one to it.\n * This id is used to map function call response to the original function\n * call.\n * @param params.toolConfirmation The tool confirmation of the current tool\n * call.\n */\n constructor({\n invocationContext,\n eventActions,\n functionCallId,\n toolConfirmation,\n }: {\n invocationContext: InvocationContext,\n eventActions?: EventActions,\n functionCallId?: string,\n toolConfirmation?: ToolConfirmation,\n }) {\n super({invocationContext, eventActions});\n this.functionCallId = functionCallId;\n this.toolConfirmation = toolConfirmation;\n }\n\n get actions(): EventActions {\n return this.eventActions;\n }\n\n requestCredential(authConfig: AuthConfig) {\n if (!this.functionCallId) {\n throw new Error('functionCallId is not set.');\n }\n\n const authHandler = new AuthHandler(authConfig);\n this.eventActions.requestedAuthConfigs[this.functionCallId] =\n authHandler.generateAuthRequest();\n }\n\n /**\n * Gets the auth credential for the given auth config.\n *\n * @param authConfig The auth config to get the auth credential for.\n * @return The auth credential for the given auth config.\n */\n getAuthResponse(authConfig: AuthConfig): AuthCredential|undefined {\n const authHandler = new AuthHandler(authConfig);\n\n return authHandler.getAuthResponse(this.state);\n }\n\n /**\n * Lists the filenames of the artifacts attached to the current session.\n *\n * @return A promise that resolves to a list of artifact filenames.\n */\n listArtifacts(): Promise<string[]> {\n if (!this.invocationContext.artifactService) {\n throw new Error('Artifact service is not initialized.');\n }\n\n return this.invocationContext.artifactService.listArtifactKeys({\n appName: this.invocationContext.session.appName,\n userId: this.invocationContext.session.userId,\n sessionId: this.invocationContext.session.id,\n });\n }\n\n /**\n * Searches the memory of the current user.\n *\n * @param query The query to search memory for.\n * @return A promise that resolves to SearchMemoryResponse containing the\n * matching memories.\n */\n searchMemory(query: string): Promise<SearchMemoryResponse> {\n if (!this.invocationContext.memoryService) {\n throw new Error('Memory service is not initialized.');\n }\n\n return this.invocationContext.memoryService.searchMemory({\n appName: this.invocationContext.session.appName,\n userId: this.invocationContext.session.userId,\n query,\n });\n }\n\n /**\n * Requests confirmation for the current tool call.\n */\n requestConfirmation({hint, payload}: {hint?: string, payload?: unknown}) {\n if (!this.functionCallId) {\n throw new Error('functionCallId is not set.');\n }\n this.eventActions.requestedToolConfirmations[this.functionCallId] =\n new ToolConfirmation({\n hint: hint,\n confirmed: false,\n payload: payload,\n });\n }\n}", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/** Log levels for the logger. */\nexport enum LogLevel {\n DEBUG = 0,\n INFO = 1,\n WARN = 2,\n ERROR = 3,\n}\n\n/**\n * Logger interface for ADK.\n */\nexport interface Logger {\n log(level: LogLevel, ...args: unknown[]): void;\n\n debug(...args: unknown[]): void;\n\n info(...args: unknown[]): void;\n\n warn(...args: unknown[]): void;\n\n error(...args: unknown[]): void;\n}\n\nlet logLevel = LogLevel.INFO;\n\n/**\n * Sets the log level for the logger.\n */\nexport function setLogLevel(level: LogLevel) {\n logLevel = level;\n}\n\n/**\n * Simple logger class for ADK.\n */\nclass SimpleLogger implements Logger {\n log(level: LogLevel, ...args: unknown[]) {\n if (level < logLevel) {\n return;\n }\n\n switch (level) {\n case LogLevel.DEBUG:\n this.debug(...args);\n break;\n case LogLevel.INFO:\n this.info(...args);\n break;\n case LogLevel.WARN:\n this.warn(...args);\n break;\n case LogLevel.ERROR:\n this.error(...args);\n break;\n default:\n throw new Error(`Unsupported log level: ${level}`);\n }\n }\n\n debug(...args: unknown[]) {\n if (logLevel > LogLevel.DEBUG) {\n return;\n }\n\n console.debug(getColoredPrefix(LogLevel.DEBUG), ...args);\n }\n\n info(...args: unknown[]) {\n if (logLevel > LogLevel.INFO) {\n return;\n }\n\n console.info(getColoredPrefix(LogLevel.INFO), ...args);\n }\n\n warn(...args: unknown[]) {\n if (logLevel > LogLevel.WARN) {\n return;\n }\n\n console.warn(getColoredPrefix(LogLevel.WARN), ...args);\n }\n\n error(...args: unknown[]) {\n if (logLevel > LogLevel.ERROR) {\n return;\n }\n\n console.error(getColoredPrefix(LogLevel.ERROR), ...args);\n }\n}\n\nconst LOG_LEVEL_STR: Record<LogLevel, string> = {\n [LogLevel.DEBUG]: 'DEBUG',\n [LogLevel.INFO]: 'INFO',\n [LogLevel.WARN]: 'WARN',\n [LogLevel.ERROR]: 'ERROR',\n};\n\nconst CONSOLE_COLOR_MAP: Record<LogLevel, string> = {\n [LogLevel.DEBUG]: '\\x1b[34m', // Blue\n [LogLevel.INFO]: '\\x1b[32m', // Green\n [LogLevel.WARN]: '\\x1b[33m', // Yellow\n [LogLevel.ERROR]: '\\x1b[31m', // Red\n};\n\nconst RESET_COLOR = '\\x1b[0m';\n\nfunction getColoredPrefix(level: LogLevel): string {\n return `${CONSOLE_COLOR_MAP[level]}[ADK ${LOG_LEVEL_STR[level]}]:${\n RESET_COLOR}`;\n}\n\n/**\n * The logger instance for ADK.\n */\nexport const logger = new SimpleLogger();", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {ActivityEnd, ActivityStart, Blob, Content} from '@google/genai';\n\n/**\n * Request sent to live agents.\n */\nexport interface LiveRequest {\n /** If set, send the content to the model in turn-by-turn mode. */\n content?: Content;\n /** If set, send the blob to the model in realtime mode. */\n blob?: Blob;\n /** If set, signal the start of user activity to the model. */\n activityStart?: ActivityStart;\n /** If set, signal the end of user activity to the model. */\n activityEnd?: ActivityEnd;\n /** If set, close the queue. */\n close?: boolean;\n}\n\n/** Function type for resolving a Promise with a LiveRequest. */\ntype PromiseResolveFn = (req: LiveRequest) => void;\n\n/**\n * Queue used to send LiveRequest in a live (bidirectional streaming) way.\n */\nexport class LiveRequestQueue {\n // Keeps track of the data that are waiting to be sent.\n private readonly queue: LiveRequest[] = [];\n // Keeps track of the promises that are waiting for data.\n private readonly resolveFnFifoQueue: PromiseResolveFn[] = [];\n private isClosed = false;\n\n /**\n * Adds a request to the queue. If there is a pending `get()` call, it\n * will be resolved with the given request.\n * @param req The request to send.\n */\n send(req: LiveRequest) {\n if (this.isClosed) {\n throw new Error('Cannot send to a closed queue.');\n }\n if (this.resolveFnFifoQueue.length > 0) {\n const resolve = this.resolveFnFifoQueue.shift()!;\n resolve(req);\n } else {\n this.queue.push(req);\n }\n }\n\n /**\n * Retrieves a request from the queue. If the queue is empty, it will\n * wait until a request is available.\n * @returns A promise that resolves with the next available request.\n */\n async get(): Promise<LiveRequest> {\n if (this.queue.length > 0) {\n return this.queue.shift()!;\n }\n if (this.isClosed) {\n return {close: true};\n }\n return new Promise<LiveRequest>((resolve) => {\n this.resolveFnFifoQueue.push(resolve);\n });\n }\n\n /**\n * Sends a close signal to the queue.\n */\n close() {\n if (this.isClosed) {\n return;\n }\n this.isClosed = true;\n\n // Satisfy pending gets with existing queue items\n while (this.resolveFnFifoQueue.length > 0 && this.queue.length > 0) {\n const resolve = this.resolveFnFifoQueue.shift()!;\n const req = this.queue.shift()!;\n resolve(req);\n }\n\n // Resolve remaining pending gets with close signal\n const closeRequest: LiveRequest = {close: true};\n while (this.resolveFnFifoQueue.length > 0) {\n const resolve = this.resolveFnFifoQueue.shift()!;\n resolve(closeRequest);\n }\n\n // Remaining items in this.queue will be drained by subsequent get() calls.\n }\n\n /**\n * Sends a content object to the queue.\n * @param content The content to send.\n */\n sendContent(content: Content) {\n this.send({content});\n }\n\n /**\n * Sends a blob to the model in realtime mode.\n * @param blob The blob to send.\n */\n sendRealtime(blob: Blob) {\n this.send({blob});\n }\n\n /**\n * Sends an activity start signal to mark the beginning of user input.\n */\n sendActivityStart() {\n this.send({activityStart: {}});\n }\n\n /**\n * Sends an activity end signal to mark the end of user input.\n */\n sendActivityEnd() {\n this.send({activityEnd: {}});\n }\n\n /**\n * Implements the async iterator protocol.\n */\n async *\n [Symbol.asyncIterator](): AsyncGenerator<LiveRequest, void, undefined> {\n while (true) {\n const request = await this.get();\n yield request;\n if (request.close) {\n break;\n }\n }\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Content, FunctionCall, GenerateContentConfig, Schema, Part } from '@google/genai';\nimport { z } from 'zod';\n\nimport { BaseCodeExecutor } from '../code_executors/base_code_executor.js';\nimport { BuiltInCodeExecutor } from '../code_executors/built_in_code_executor.js';\nimport { buildCodeExecutionResultPart, buildExecutableCodePart, CodeExecutionResult, convertCodeExecutionParts, extractCodeAndTruncateContent, File } from '../code_executors/code_execution_utils.js';\nimport { CodeExecutorContext } from '../code_executors/code_executor_context.js';\nimport { createEvent, createNewEventId, Event, getFunctionCalls, getFunctionResponses, isFinalResponse } from '../events/event.js';\nimport { EventActions, createEventActions } from '../events/event_actions.js';\nimport { BaseExampleProvider } from '../examples/base_example_provider.js';\nimport { Example } from '../examples/example.js';\nimport { BaseLlm, isBaseLlm } from '../models/base_llm.js';\nimport { appendInstructions, LlmRequest, setOutputSchema } from '../models/llm_request.js';\nimport { LlmResponse } from '../models/llm_response.js';\nimport { LLMRegistry } from '../models/registry.js';\nimport { State } from '../sessions/state.js';\nimport { BaseTool } from '../tools/base_tool.js';\nimport { BaseToolset } from '../tools/base_toolset.js';\nimport { FunctionTool } from '../tools/function_tool.js';\nimport { ToolConfirmation } from '../tools/tool_confirmation.js';\nimport { ToolContext } from '../tools/tool_context.js';\nimport { deepClone } from '../utils/deep_clone.js';\nimport { base64Decode } from '../utils/env_aware_utils.js';\nimport { logger } from '../utils/logger.js';\n\nimport { BaseAgent, BaseAgentConfig } from './base_agent.js';\nimport { BaseLlmRequestProcessor, BaseLlmResponseProcessor } from './base_llm_processor.js';\nimport { CallbackContext } from './callback_context.js';\nimport { getContents, getCurrentTurnContents } from './content_processor_utils.js';\nimport { generateAuthEvent, generateRequestConfirmationEvent, getLongRunningFunctionCalls, handleFunctionCallList, handleFunctionCallsAsync, populateClientFunctionCallId, REQUEST_CONFIRMATION_FUNCTION_CALL_NAME } from './functions.js';\nimport { injectSessionState } from './instructions.js';\nimport { InvocationContext } from './invocation_context.js';\nimport { ReadonlyContext } from './readonly_context.js';\nimport { StreamingMode } from './run_config.js';\n\n/** An object that can provide an instruction string. */\nexport type InstructionProvider = (\n context: ReadonlyContext,\n) => string | Promise<string>;\n\n/**\n * A callback that runs before a request is sent to the model.\n *\n * @param context The current callback context.\n * @param request The raw model request. Callback can mutate the request.\n * @returns The content to return to the user. When present, the model call\n * will be skipped and the provided content will be returned to user.\n */\nexport type SingleBeforeModelCallback =\n (params: { context: CallbackContext; request: LlmRequest; }) =>\n LlmResponse | undefined | Promise<LlmResponse | undefined>;\n\n/**\n * A single callback or a list of callbacks.\n *\n * When a list of callbacks is provided, the callbacks will be called in the\n * order they are listed until a callback does not return None.\n */\nexport type BeforeModelCallback =\n | SingleBeforeModelCallback | SingleBeforeModelCallback[];\n\n/**\n * A callback that runs after a response is received from the model.\n *\n * @param context The current callback context.\n * @param response The actual model response.\n * @returns The content to return to the user. When present, the actual model\n * response will be ignored and the provided content will be returned to\n * user.\n */\nexport type SingleAfterModelCallback =\n (params: { context: CallbackContext; response: LlmResponse; }) =>\n LlmResponse | undefined | Promise<LlmResponse | undefined>;\n\n/**\n * A single callback or a list of callbacks.\n *\n * When a list of callbacks is provided, the callbacks will be called in the\n order they are listed until a callback does not return None.\n */\nexport type AfterModelCallback =\n | SingleAfterModelCallback | SingleAfterModelCallback[];\n\n/** A generic dictionary type. */\nexport type Dict = {\n [key: string]: unknown\n};\n\n/**\n * A callback that runs before a tool is called.\n *\n * @param tool The tool to be called.\n * @param args The arguments to the tool.\n * @param tool_context: ToolContext,\n * @returns The tool response. When present, the returned tool response will\n * be used and the framework will skip calling the actual tool.\n */\nexport type SingleBeforeToolCallback =\n (params: { tool: BaseTool; args: Dict; context: ToolContext; }) =>\n Dict | undefined | Promise<Dict | undefined>;\n\n/**\n * A single callback or a list of callbacks.\n *\n * When a list of callbacks is provided, the callbacks will be called in the\n * order they are listed until a callback does not return None.\n */\nexport type BeforeToolCallback =\n | SingleBeforeToolCallback | SingleBeforeToolCallback[];\n\n/**\n * A callback that runs after a tool is called.\n *\n * @param tool The tool to be called.\n * @param args The arguments to the tool.\n * @param tool_context: ToolContext,\n * @param tool_response: The response from the tool.\n * @returns When present, the returned dict will be used as tool result.\n */\nexport type SingleAfterToolCallback = (params: {\n tool: BaseTool; args: Dict; context: ToolContext; response: Dict;\n}) => Dict | undefined | Promise<Dict | undefined>;\n\n/**\n * A single callback or a list of callbacks.\n *\n * When a list of callbacks is provided, the callbacks will be called in the\n * order they are listed until acallback does not return None.\n */\nexport type AfterToolCallback =\n | SingleAfterToolCallback | SingleAfterToolCallback[];\n\n/** A list of examples or an example provider. */\nexport type ExamplesUnion = Example[] | BaseExampleProvider;\n\n/** A union of tool types that can be provided to an agent. */\nexport type ToolUnion = BaseTool | BaseToolset;\n\nconst ADK_AGENT_NAME_LABEL_KEY = 'adk_agent_name';\n\nexport interface LlmAgentConfig extends BaseAgentConfig {\n /**\n * The model to use for the agent.\n */\n model?: string | BaseLlm;\n\n /** Instructions for the LLM model, guiding the agent's behavior. */\n instruction?: string | InstructionProvider;\n\n /**\n * Instructions for all the agents in the entire agent tree.\n *\n * ONLY the globalInstruction in root agent will take effect.\n *\n * For example: use globalInstruction to make all agents have a stable\n * identity or personality.\n */\n globalInstruction?: string | InstructionProvider;\n\n /** Tools available to this agent. */\n tools?: ToolUnion[];\n\n /**\n * The additional content generation configurations.\n *\n * NOTE: not all fields are usable, e.g. tools must be configured via\n * `tools`, thinking_config must be configured via `planner` in LlmAgent.\n *\n * For example: use this config to adjust model temperature, configure safety\n * settings, etc.\n */\n generateContentConfig?: GenerateContentConfig;\n\n /**\n * Disallows LLM-controlled transferring to the parent agent.\n *\n * NOTE: Setting this as True also prevents this agent to continue reply to\n * the end-user. This behavior prevents one-way transfer, in which end-user\n * may be stuck with one agent that cannot transfer to other agents in the\n * agent tree.\n */\n disallowTransferToParent?: boolean;\n\n /** Disallows LLM-controlled transferring to the peer agents. */\n disallowTransferToPeers?: boolean;\n\n // TODO - b/425992518: consider more complex contex engineering mechanims.\n /**\n * Controls content inclusion in model requests.\n *\n * Options:\n * default: Model receives relevant conversation history\n * none: Model receives no prior history, operates solely on current\n * instruction and input\n */\n includeContents?: 'default' | 'none';\n\n /** The input schema when agent is used as a tool. */\n inputSchema?: Schema;\n\n /**\n * The output schema when agent replies.\n *\n * NOTE:\n * When this is set, agent can ONLY reply and CANNOT use any tools, such as\n * function tools, RAGs, agent transfer, etc.\n */\n outputSchema?: Schema;\n\n /**\n * The key in session state to store the output of the agent.\n *\n * Typically use cases:\n * - Extracts agent reply for later use, such as in tools, callbacks, etc.\n * - Connects agents to coordinate with each other.\n */\n outputKey?: string;\n\n /**\n * Callbacks to be called before calling the LLM.\n */\n beforeModelCallback?: BeforeModelCallback;\n\n /**\n * Callbacks to be called after calling the LLM.\n */\n afterModelCallback?: AfterModelCallback;\n\n /**\n * Callbacks to be called before calling the tool.\n */\n beforeToolCallback?: BeforeToolCallback;\n\n /**\n * Callbacks to be called after calling the tool.\n */\n afterToolCallback?: AfterToolCallback;\n\n /**\n * Processors to run before the LLM request is sent.\n */\n requestProcessors?: BaseLlmRequestProcessor[];\n\n /**\n * Processors to run after the LLM response is received.\n */\n responseProcessors?: BaseLlmResponseProcessor[];\n\n /**\n * Instructs the agent to make a plan and execute it step by step.\n */\n codeExecutor?: BaseCodeExecutor;\n}\n\nasync function convertToolUnionToTools(\n toolUnion: ToolUnion,\n context?: ReadonlyContext,\n): Promise<BaseTool[]> {\n if (toolUnion instanceof BaseTool) {\n return [toolUnion];\n }\n return await toolUnion.getTools(context);\n}\n\n// --------------------------------------------------------------------------\n// #START Request Processors\n// --------------------------------------------------------------------------\nclass BasicLlmRequestProcessor extends BaseLlmRequestProcessor {\n override async *\n runAsync(\n invocationContext: InvocationContext,\n llmRequest: LlmRequest,\n ): AsyncGenerator<Event, void, void> {\n const agent = invocationContext.agent;\n if (!(agent instanceof LlmAgent)) {\n return;\n }\n\n // set model string, not model instance.\n llmRequest.model = agent.canonicalModel.model;\n\n llmRequest.config = { ...agent.generateContentConfig ?? {} };\n if (agent.outputSchema) {\n setOutputSchema(llmRequest, agent.outputSchema);\n }\n\n if (invocationContext.runConfig) {\n llmRequest.liveConnectConfig.responseModalities =\n invocationContext.runConfig.responseModalities;\n llmRequest.liveConnectConfig.speechConfig =\n invocationContext.runConfig.speechConfig;\n llmRequest.liveConnectConfig.outputAudioTranscription =\n invocationContext.runConfig.outputAudioTranscription;\n llmRequest.liveConnectConfig.inputAudioTranscription =\n invocationContext.runConfig.inputAudioTranscription;\n llmRequest.liveConnectConfig.realtimeInputConfig =\n invocationContext.runConfig.realtimeInputConfig;\n llmRequest.liveConnectConfig.enableAffectiveDialog =\n invocationContext.runConfig.enableAffectiveDialog;\n llmRequest.liveConnectConfig.proactivity =\n invocationContext.runConfig.proactivity;\n }\n }\n}\nconst BASIC_LLM_REQUEST_PROCESSOR = new BasicLlmRequestProcessor();\n\n\nclass IdentityLlmRequestProcessor extends BaseLlmRequestProcessor {\n override async *\n runAsync(\n invocationContext: InvocationContext,\n llmRequest: LlmRequest,\n ): AsyncGenerator<Event, void, undefined> {\n const agent = invocationContext.agent;\n const si = [`You are an agent. Your internal name is \"${agent.name}\".`];\n if (agent.description) {\n si.push(`The description about you is \"${agent.description}\"`);\n }\n appendInstructions(llmRequest, si);\n }\n}\nconst IDENTITY_LLM_REQUEST_PROCESSOR = new IdentityLlmRequestProcessor();\n\n\nclass InstructionsLlmRequestProcessor extends BaseLlmRequestProcessor {\n /**\n * Handles instructions and global instructions for LLM flow.\n */\n async *\n runAsync(\n invocationContext: InvocationContext,\n llmRequest: LlmRequest,\n ): AsyncGenerator<Event, void, void> {\n const agent = invocationContext.agent;\n if (!(agent instanceof LlmAgent) ||\n !(agent.rootAgent instanceof LlmAgent)) {\n return;\n }\n const rootAgent: LlmAgent = agent.rootAgent;\n\n // TODO - b/425992518: unexpected and buggy for performance.\n // Global instruction should be explicitly scoped.\n // Step 1: Appends global instructions if set by RootAgent.\n if (rootAgent instanceof LlmAgent && rootAgent.globalInstruction) {\n const { instruction, requireStateInjection } =\n await rootAgent.canonicalGlobalInstruction(\n new ReadonlyContext(invocationContext),\n );\n let instructionWithState = instruction;\n if (requireStateInjection) {\n instructionWithState = await injectSessionState(\n instruction,\n new ReadonlyContext(invocationContext),\n );\n }\n appendInstructions(llmRequest, [instructionWithState]);\n }\n\n // Step 2: Appends agent local instructions if set.\n // TODO - b/425992518: requireStateInjection means user passed a\n // instruction processor. We need to make it more explicit.\n if (agent.instruction) {\n const { instruction, requireStateInjection } =\n await agent.canonicalInstruction(\n new ReadonlyContext(invocationContext),\n );\n let instructionWithState = instruction;\n if (requireStateInjection) {\n instructionWithState = await injectSessionState(\n instruction,\n new ReadonlyContext(invocationContext),\n );\n }\n appendInstructions(llmRequest, [instructionWithState]);\n }\n }\n}\nconst INSTRUCTIONS_LLM_REQUEST_PROCESSOR =\n new InstructionsLlmRequestProcessor();\n\n\nclass ContentRequestProcessor implements BaseLlmRequestProcessor {\n async *\n runAsync(invocationContext: InvocationContext, llmRequest: LlmRequest):\n AsyncGenerator<Event, void, void> {\n const agent = invocationContext.agent;\n if (!agent || !(agent instanceof LlmAgent)) {\n return;\n }\n\n if (agent.includeContents === 'default') {\n // Include full conversation history\n llmRequest.contents = getContents(\n invocationContext.session.events,\n agent.name,\n invocationContext.branch,\n );\n } else {\n // Include current turn context only (no conversation history).\n llmRequest.contents = getCurrentTurnContents(\n invocationContext.session.events,\n agent.name,\n invocationContext.branch,\n );\n }\n\n return;\n }\n}\nconst CONTENT_REQUEST_PROCESSOR = new ContentRequestProcessor();\n\nclass AgentTransferLlmRequestProcessor extends BaseLlmRequestProcessor {\n private readonly toolName = 'transfer_to_agent' as const;\n private readonly tool = new FunctionTool({\n name: this.toolName,\n description:\n 'Transfer the question to another agent. This tool hands off control to another agent when it is more suitable to answer the user question according to the agent description.',\n parameters: z.object({\n agentName: z.string().describe('the agent name to transfer to.'),\n }),\n execute:\n function (args: { agentName: string }, toolContext?: ToolContext) {\n if (!toolContext) {\n throw new Error('toolContext is required.');\n }\n toolContext.actions.transferToAgent = args.agentName;\n return 'Transfer queued';\n },\n });\n\n override async *\n runAsync(\n invocationContext: InvocationContext,\n llmRequest: LlmRequest,\n ): AsyncGenerator<Event, void, void> {\n if (!(invocationContext.agent instanceof LlmAgent)) {\n return;\n }\n\n const transferTargets = this.getTransferTargets(invocationContext.agent);\n if (!transferTargets.length) {\n return;\n }\n\n appendInstructions(llmRequest, [\n this.buildTargetAgentsInstructions(\n invocationContext.agent,\n transferTargets,\n ),\n ]);\n\n const toolContext = new ToolContext({ invocationContext });\n await this.tool.processLlmRequest({ toolContext, llmRequest });\n }\n\n private buildTargetAgentsInfo(targetAgent: BaseAgent): string {\n return `\nAgent name: ${targetAgent.name}\nAgent description: ${targetAgent.description}\n`;\n }\n\n private buildTargetAgentsInstructions(\n agent: LlmAgent,\n targetAgents: BaseAgent[],\n ): string {\n let instructions = `\nYou have a list of other agents to transfer to:\n\n${targetAgents.map(this.buildTargetAgentsInfo).join('\\n')}\n\nIf you are the best to answer the question according to your description, you\ncan answer it.\n\nIf another agent is better for answering the question according to its\ndescription, call \\`${this.toolName}\\` function to transfer the\nquestion to that agent. When transferring, do not generate any text other than\nthe function call.\n`;\n\n if (agent.parentAgent && !agent.disallowTransferToParent) {\n instructions += `\nYour parent agent is ${agent.parentAgent.name}. If neither the other agents nor\nyou are best for answering the question according to the descriptions, transfer\nto your parent agent.\n`;\n }\n return instructions;\n }\n\n private getTransferTargets(agent: LlmAgent): BaseAgent[] {\n const targets: BaseAgent[] = [];\n targets.push(...agent.subAgents);\n\n if (!agent.parentAgent || !(agent.parentAgent instanceof LlmAgent)) {\n return targets;\n }\n\n if (!agent.disallowTransferToParent) {\n targets.push(agent.parentAgent);\n }\n\n if (!agent.disallowTransferToPeers) {\n targets.push(\n ...agent.parentAgent.subAgents.filter(\n (peerAgent) => peerAgent.name !== agent.name,\n ),\n );\n }\n\n return targets;\n }\n}\nconst AGENT_TRANSFER_LLM_REQUEST_PROCESSOR =\n new AgentTransferLlmRequestProcessor();\n\n\nclass RequestConfirmationLlmRequestProcessor extends BaseLlmRequestProcessor {\n /** Handles tool confirmation information to build the LLM request. */\n override async *\n runAsync(\n invocationContext: InvocationContext,\n llmRequest: LlmRequest,\n ): AsyncGenerator<Event, void, void> {\n const agent = invocationContext.agent;\n if (!(agent instanceof LlmAgent)) {\n return;\n }\n const events = invocationContext.session.events;\n if (!events || events.length === 0) {\n return;\n }\n\n const requestConfirmationFunctionResponses:\n { [key: string]: ToolConfirmation } = {};\n\n let confirmationEventIndex = -1;\n // Step 1: Find the FIRST confirmation event authored by user.\n for (let i = events.length - 1; i >= 0; i--) {\n const event = events[i];\n if (event.author !== 'user') {\n continue;\n }\n const responses = getFunctionResponses(event);\n if (!responses) {\n continue;\n }\n\n let foundConfirmation = false;\n for (const functionResponse of responses) {\n if (functionResponse.name !== REQUEST_CONFIRMATION_FUNCTION_CALL_NAME) {\n continue;\n }\n foundConfirmation = true;\n\n let toolConfirmation = null;\n\n if (functionResponse.response &&\n Object.keys(functionResponse.response).length === 1 &&\n 'response' in functionResponse.response) {\n toolConfirmation =\n JSON.parse(functionResponse.response['response'] as string) as\n ToolConfirmation;\n } else if (functionResponse.response) {\n toolConfirmation = new ToolConfirmation({\n hint: functionResponse.response['hint'] as string,\n payload: functionResponse.response['payload'],\n confirmed: functionResponse.response['confirmed'] as boolean,\n });\n }\n\n if (functionResponse.id && toolConfirmation) {\n requestConfirmationFunctionResponses[functionResponse.id] =\n toolConfirmation;\n }\n }\n if (foundConfirmation) {\n confirmationEventIndex = i;\n break;\n }\n }\n\n if (Object.keys(requestConfirmationFunctionResponses).length === 0) {\n return;\n }\n\n // Step 2: Find the system generated FunctionCall event requesting the tool\n // confirmation\n for (let i = confirmationEventIndex - 1; i >= 0; i--) {\n const event = events[i];\n const functionCalls = getFunctionCalls(event);\n if (!functionCalls) {\n continue;\n }\n\n const toolsToResumeWithConfirmation:\n { [key: string]: ToolConfirmation } = {};\n const toolsToResumeWithArgs: { [key: string]: FunctionCall } = {};\n\n for (const functionCall of functionCalls) {\n if (!functionCall.id ||\n !(functionCall.id in requestConfirmationFunctionResponses)) {\n continue;\n }\n\n const args = functionCall.args;\n if (!args || !('originalFunctionCall' in args)) {\n continue;\n }\n const originalFunctionCall =\n args['originalFunctionCall'] as FunctionCall;\n\n if (originalFunctionCall.id) {\n toolsToResumeWithConfirmation[originalFunctionCall.id] =\n requestConfirmationFunctionResponses[functionCall.id];\n toolsToResumeWithArgs[originalFunctionCall.id] = originalFunctionCall;\n }\n }\n if (Object.keys(toolsToResumeWithConfirmation).length === 0) {\n continue;\n }\n\n // Step 3: Remove the tools that have already been confirmed AND resumed.\n for (let j = events.length - 1; j > confirmationEventIndex; j--) {\n const eventToCheck = events[j];\n const functionResponses = getFunctionResponses(eventToCheck);\n if (!functionResponses) {\n continue;\n }\n\n for (const fr of functionResponses) {\n if (fr.id && fr.id in toolsToResumeWithConfirmation) {\n delete toolsToResumeWithConfirmation[fr.id];\n delete toolsToResumeWithArgs[fr.id];\n }\n }\n if (Object.keys(toolsToResumeWithConfirmation).length === 0) {\n break;\n }\n }\n\n if (Object.keys(toolsToResumeWithConfirmation).length === 0) {\n continue;\n }\n\n const toolsList =\n await agent.canonicalTools(new ReadonlyContext(invocationContext));\n const toolsDict =\n Object.fromEntries(toolsList.map((tool) => [tool.name, tool]));\n\n const functionResponseEvent = await handleFunctionCallList({\n invocationContext: invocationContext,\n functionCalls: Object.values(toolsToResumeWithArgs),\n toolsDict: toolsDict,\n beforeToolCallbacks: agent.canonicalBeforeToolCallbacks,\n afterToolCallbacks: agent.canonicalAfterToolCallbacks,\n filters: new Set(Object.keys(toolsToResumeWithConfirmation)),\n toolConfirmationDict: toolsToResumeWithConfirmation,\n });\n\n if (functionResponseEvent) {\n yield functionResponseEvent;\n }\n return;\n }\n }\n}\n\nexport const REQUEST_CONFIRMATION_LLM_REQUEST_PROCESSOR =\n new RequestConfirmationLlmRequestProcessor();\n\n\n/**\n * Processes code execution requests.\n */\nclass CodeExecutionRequestProcessor extends BaseLlmRequestProcessor {\n override async *\n runAsync(\n invocationContext: InvocationContext,\n llmRequest: LlmRequest,\n ): AsyncGenerator<Event, void, void> {\n if (!(invocationContext.agent instanceof LlmAgent)) {\n return;\n }\n\n if (!invocationContext.agent.codeExecutor) {\n return;\n }\n\n for await (const event of runPreProcessor(invocationContext, llmRequest)) {\n yield event;\n }\n\n if (!(invocationContext.agent.codeExecutor instanceof BaseCodeExecutor)) {\n return;\n }\n\n for (const content of llmRequest.contents) {\n const delimeters: [string, string] =\n invocationContext.agent.codeExecutor.codeBlockDelimiters.length ?\n invocationContext.agent.codeExecutor.codeBlockDelimiters[0] :\n ['', ''];\n\n const codeExecutionParts = convertCodeExecutionParts(\n content,\n delimeters,\n invocationContext.agent.codeExecutor.executionResultDelimiters,\n );\n }\n }\n}\n\n/**\n * Map of MIME types to data file utilities\n */\nconst DATA_FILE_UTIL_MAP: Record<string, {\n extension: string;\n loaderCodeTemplate: string;\n}\n> = {\n 'text/csv': {\n extension: '.csv',\n loaderCodeTemplate: 'pd.read_csv(\\'{filename}\\')',\n },\n};\n\n/**\n * Helper library for data file exploration\n */\nconst DATA_FILE_HELPER_LIB = `\nimport pandas as pd\n\ndef explore_df(df: pd.DataFrame) -> None:\n \"\"\"Prints some information about a pandas DataFrame.\"\"\"\n\n with pd.option_context(\n 'display.max_columns', None, 'display.expand_frame_repr', False\n ):\n # Print the column names to never encounter KeyError when selecting one.\n df_dtypes = df.dtypes\n\n # Obtain information about data types and missing values.\n df_nulls = (len(df) - df.isnull().sum()).apply(\n lambda x: f'{x} / {df.shape[0]} non-null'\n )\n\n # Explore unique total values in columns using \\`.unique()\\`.\n df_unique_count = df.apply(lambda x: len(x.unique()))\n\n # Explore unique values in columns using \\`.unique()\\`.\n df_unique = df.apply(lambda x: crop(str(list(x.unique()))))\n\n df_info = pd.concat(\n (\n df_dtypes.rename('Dtype'),\n df_nulls.rename('Non-Null Count'),\n df_unique_count.rename('Unique Values Count'),\n df_unique.rename('Unique Values'),\n ),\n axis=1,\n )\n df_info.index.name = 'Columns'\n print(f\"\"\"Total rows: {df.shape[0]}\nTotal columns: {df.shape[1]}\n\n{df_info}\"\"\")\n`;\n\n/**\n * Processor for code execution responses.\n */\nclass CodeExecutionResponseProcessor implements BaseLlmResponseProcessor {\n /**\n * Processes the LLM response asynchronously.\n *\n * @param invocationContext The invocation context\n * @param llmResponse The LLM response to process\n * @returns An async generator yielding events\n */\n async *\n runAsync(invocationContext: InvocationContext, llmResponse: LlmResponse):\n AsyncGenerator<Event, void, unknown> {\n // Skip if the response is partial (streaming)\n if (llmResponse.partial) {\n return;\n }\n\n // Run the post-processor with standard generator approach\n for await (\n const event of runPostProcessor(invocationContext, llmResponse)) {\n yield event;\n }\n }\n}\n\n/**\n * The exported response processor instance.\n */\nexport const responseProcessor = new CodeExecutionResponseProcessor();\n\n/**\n * Pre-processes the user message by adding the user message to the execution\n * environment.\n *\n * @param invocationContext The invocation context\n * @param llmRequest The LLM request to process\n * @returns An async generator yielding events\n */\nasync function*\n runPreProcessor(\n invocationContext: InvocationContext,\n llmRequest: LlmRequest,\n ): AsyncGenerator<Event, void, unknown> {\n const agent = invocationContext.agent;\n\n if (!(agent instanceof LlmAgent)) {\n return;\n }\n\n const codeExecutor = agent.codeExecutor;\n\n if (!codeExecutor || !(codeExecutor instanceof BaseCodeExecutor)) {\n return;\n }\n\n if (codeExecutor instanceof BuiltInCodeExecutor) {\n codeExecutor.processLlmRequest(llmRequest);\n return;\n }\n\n if (!codeExecutor.optimizeDataFile) {\n return;\n }\n\n const codeExecutorContext =\n new CodeExecutorContext(new State(invocationContext.session.state));\n\n // Skip if the error count exceeds the max retry attempts\n if (codeExecutorContext.getErrorCount(invocationContext.invocationId) >=\n codeExecutor.errorRetryAttempts) {\n return;\n }\n\n // [Step 1] Extract data files from the session_history and store them in\n // memory Meanwhile, mutate the inline data file to text part in session\n // history from all turns\n const allInputFiles =\n extractAndReplaceInlineFiles(codeExecutorContext, llmRequest);\n\n // [Step 2] Run explore_df code on the data files from the current turn\n // We only need to explore the new data files because the previous data files\n // should already be explored and cached in the code execution runtime\n const processedFileNames =\n new Set(codeExecutorContext.getProcessedFileNames());\n const filesToProcess =\n allInputFiles.filter(f => !processedFileNames.has(f.name));\n\n for (const file of filesToProcess) {\n const codeStr = getDataFilePreprocessingCode(file);\n\n // Skip for unsupported file or executor types\n if (!codeStr) {\n return;\n }\n\n // Emit the code to execute, and add it to the LLM request\n const codeContent: Content = {\n role: 'model',\n parts: [\n { text: `Processing input file: \\`${file.name}\\`` },\n buildExecutableCodePart(codeStr)\n ]\n };\n\n llmRequest.contents.push(deepClone(codeContent)!);\n\n yield createEvent({\n invocationId: invocationContext.invocationId,\n author: agent.name,\n branch: invocationContext.branch,\n content: codeContent\n });\n\n const executionId =\n getOrSetExecutionId(invocationContext, codeExecutorContext);\n const codeExecutionResult = await codeExecutor.executeCode({\n invocationContext,\n codeExecutionInput: {\n code: codeStr,\n inputFiles: [file],\n executionId,\n }\n });\n\n // Update the processing results to code executor context\n codeExecutorContext.updateCodeExecutionResult({\n invocationId: invocationContext.invocationId,\n code: codeStr,\n resultStdout: codeExecutionResult.stdout,\n resultStderr: codeExecutionResult.stderr,\n });\n\n codeExecutorContext.addProcessedFileNames([file.name]);\n\n // Emit the execution result, and add it to the LLM request\n const executionResultEvent = await postProcessCodeExecutionResult(\n invocationContext,\n codeExecutorContext,\n codeExecutionResult,\n );\n\n yield executionResultEvent;\n llmRequest.contents.push(deepClone(executionResultEvent.content)!);\n }\n}\n\n/**\n * Post-processes the model response by extracting and executing the first code\n * block.\n *\n * @param invocationContext The invocation context\n * @param llmResponse The LLM response to process\n * @returns An async generator yielding events\n */\nasync function*\n runPostProcessor(\n invocationContext: InvocationContext,\n llmResponse: LlmResponse,\n ): AsyncGenerator<Event, void, unknown> {\n const agent = invocationContext.agent;\n\n if (!(agent instanceof LlmAgent)) {\n return;\n }\n\n const codeExecutor = agent.codeExecutor;\n\n if (!codeExecutor || !(codeExecutor instanceof BaseCodeExecutor)) {\n return;\n }\n\n if (!llmResponse || !llmResponse.content) {\n return;\n }\n\n if (codeExecutor instanceof BuiltInCodeExecutor) {\n return;\n }\n\n const codeExecutorContext =\n new CodeExecutorContext(new State(invocationContext.session.state));\n\n // Skip if the error count exceeds the max retry attempts\n if (codeExecutorContext.getErrorCount(invocationContext.invocationId) >=\n codeExecutor.errorRetryAttempts) {\n return;\n }\n\n // [Step 1] Extract code from the model predict response and truncate the\n // content to the part with the first code block\n const responseContent = llmResponse.content;\n const codeStr = extractCodeAndTruncateContent(\n responseContent, codeExecutor.codeBlockDelimiters);\n\n // Terminal state: no code to execute\n if (!codeStr) {\n return;\n }\n\n // [Step 2] Executes the code and emit 2 Events for code and execution result\n yield createEvent({\n invocationId: invocationContext.invocationId,\n author: agent.name,\n branch: invocationContext.branch,\n content: responseContent,\n });\n\n const executionId =\n getOrSetExecutionId(invocationContext, codeExecutorContext);\n const codeExecutionResult = await codeExecutor.executeCode({\n invocationContext,\n codeExecutionInput: {\n code: codeStr,\n inputFiles: codeExecutorContext.getInputFiles(),\n executionId,\n }\n });\n\n codeExecutorContext.updateCodeExecutionResult({\n invocationId: invocationContext.invocationId,\n code: codeStr,\n resultStdout: codeExecutionResult.stdout,\n resultStderr: codeExecutionResult.stderr,\n });\n\n yield await postProcessCodeExecutionResult(\n invocationContext,\n codeExecutorContext,\n codeExecutionResult,\n );\n\n // [Step 3] Skip processing the original model response\n // to continue code generation loop\n llmResponse.content = null as any;\n}\n\n/**\n * Extracts and replaces inline files with file names in the LLM request.\n *\n * @param codeExecutorContext The code executor context\n * @param llmRequest The LLM request to process\n * @returns A list of input files\n */\nfunction extractAndReplaceInlineFiles(\n codeExecutorContext: CodeExecutorContext, llmRequest: LlmRequest): File[] {\n const allInputFiles = codeExecutorContext.getInputFiles();\n const savedFileNames = new Set(allInputFiles.map(f => f.name));\n\n // [Step 1] Process input files from LlmRequest and cache them in CodeExecutor\n for (let i = 0; i < llmRequest.contents.length; i++) {\n const content = llmRequest.contents[i];\n\n // Only process the user message\n if (content.role !== 'user' || !content.parts) {\n continue;\n }\n\n for (let j = 0; j < content.parts.length; j++) {\n const part = content.parts[j] as Part;\n const mimeType = part.inlineData?.mimeType;\n\n // Skip if the inline data is not supported\n if (!mimeType || !part.inlineData || !DATA_FILE_UTIL_MAP[mimeType]) {\n continue;\n }\n\n // Replace the inline data file with a file name placeholder\n const fileName =\n `data_${i + 1}_${j + 1}${DATA_FILE_UTIL_MAP[mimeType].extension}`;\n\n part.text = `\\nAvailable file: \\`${fileName}\\`\\n`;\n\n // Add the inline data as input file to the code executor context\n const file: File = {\n name: fileName,\n content: base64Decode(part.inlineData.data!),\n mimeType\n };\n\n if (!savedFileNames.has(fileName)) {\n codeExecutorContext.addInputFiles([file]);\n allInputFiles.push(file);\n }\n }\n }\n\n return allInputFiles;\n}\n\n/**\n * Gets or sets the execution ID for stateful code execution.\n *\n * @param invocationContext The invocation context\n * @param codeExecutorContext The code executor context\n * @returns The execution ID or undefined if not stateful\n */\nfunction getOrSetExecutionId(\n invocationContext: InvocationContext,\n codeExecutorContext: CodeExecutorContext): string | undefined {\n const agent = invocationContext.agent;\n\n if (!(agent instanceof LlmAgent) || !agent.codeExecutor?.stateful) {\n return undefined;\n }\n\n let executionId = codeExecutorContext.getExecutionId();\n\n if (!executionId) {\n executionId = invocationContext.session.id;\n codeExecutorContext.setExecutionId(executionId);\n }\n\n return executionId;\n}\n\n/**\n * Post-processes the code execution result and emits an Event.\n *\n * @param invocationContext The invocation context\n * @param codeExecutorContext The code executor context\n * @param codeExecutionResult The code execution result\n * @returns The event with the code execution result\n */\nasync function postProcessCodeExecutionResult(\n invocationContext: InvocationContext,\n codeExecutorContext: CodeExecutorContext,\n codeExecutionResult: CodeExecutionResult): Promise<Event> {\n if (!invocationContext.artifactService) {\n throw new Error('Artifact service is not initialized.');\n }\n\n const resultContent: Content = {\n role: 'model',\n parts: [buildCodeExecutionResultPart(codeExecutionResult)]\n };\n\n const eventActions =\n createEventActions({ stateDelta: codeExecutorContext.getStateDelta() });\n\n // Handle code execution error retry\n if (codeExecutionResult.stderr) {\n codeExecutorContext.incrementErrorCount(invocationContext.invocationId);\n } else {\n codeExecutorContext.resetErrorCount(invocationContext.invocationId);\n }\n\n // Handle output files\n for (const outputFile of codeExecutionResult.outputFiles) {\n const version = await invocationContext.artifactService.saveArtifact({\n appName: invocationContext.appName || '',\n userId: invocationContext.userId || '',\n sessionId: invocationContext.session.id,\n filename: outputFile.name,\n artifact: {\n inlineData: { data: outputFile.content, mimeType: outputFile.mimeType }\n },\n });\n\n eventActions.artifactDelta[outputFile.name] = version;\n }\n\n return createEvent({\n invocationId: invocationContext.invocationId,\n author: invocationContext.agent.name,\n branch: invocationContext.branch,\n content: resultContent,\n actions: eventActions\n });\n}\n\n/**\n * Returns the code to explore the data file.\n *\n * @param file The file to explore\n * @returns The code to explore the data file or undefined if not supported\n */\nfunction getDataFilePreprocessingCode(file: File): string | undefined {\n /**\n * Gets a normalized file name.\n *\n * @param fileName The file name to normalize\n * @returns The normalized file name\n */\n function getNormalizedFileName(fileName: string): string {\n const [varName] = fileName.split('.');\n\n // Replace non-alphanumeric characters with underscores\n let normalizedName = varName.replace(/[^a-zA-Z0-9_]/g, '_');\n\n // If the filename starts with a digit, prepend an underscore\n if (/^\\d/.test(normalizedName)) {\n normalizedName = '_' + normalizedName;\n }\n\n return normalizedName;\n }\n\n if (!DATA_FILE_UTIL_MAP[file.mimeType]) {\n return undefined;\n }\n\n const varName = getNormalizedFileName(file.name);\n const loaderCode =\n DATA_FILE_UTIL_MAP[file.mimeType].loaderCodeTemplate.replace(\n '{filename}', file.name);\n\n return `\n${DATA_FILE_HELPER_LIB}\n\n# Load the dataframe.\n${varName} = ${loaderCode}\n\n# Use \\`explore_df\\` to guide my analysis.\nexplore_df(${varName})\n`;\n}\n\nconst CODE_EXECUTION_REQUEST_PROCESSOR = new CodeExecutionRequestProcessor();\n\n// --------------------------------------------------------------------------\n// #END RequesBaseCodeExecutort Processors\n// --------------------------------------------------------------------------\n\n/**\n * An agent that uses a large language model to generate responses.\n */\nexport class LlmAgent extends BaseAgent {\n model?: string | BaseLlm;\n instruction: string | InstructionProvider;\n globalInstruction: string | InstructionProvider;\n tools: ToolUnion[];\n generateContentConfig?: GenerateContentConfig;\n disallowTransferToParent: boolean;\n disallowTransferToPeers: boolean;\n includeContents: 'default' | 'none';\n inputSchema?: Schema;\n outputSchema?: Schema;\n outputKey?: string;\n beforeModelCallback?: BeforeModelCallback;\n afterModelCallback?: AfterModelCallback;\n beforeToolCallback?: BeforeToolCallback;\n afterToolCallback?: AfterToolCallback;\n requestProcessors: BaseLlmRequestProcessor[];\n responseProcessors: BaseLlmResponseProcessor[];\n codeExecutor?: BaseCodeExecutor;\n\n constructor(config: LlmAgentConfig) {\n super(config);\n this.model = config.model;\n this.instruction = config.instruction ?? '';\n this.globalInstruction = config.globalInstruction ?? '';\n this.tools = config.tools ?? [];\n this.generateContentConfig = config.generateContentConfig;\n this.disallowTransferToParent = config.disallowTransferToParent ?? false;\n this.disallowTransferToPeers = config.disallowTransferToPeers ?? false;\n this.includeContents = config.includeContents ?? 'default';\n this.inputSchema = config.inputSchema;\n this.outputSchema = config.outputSchema;\n this.outputKey = config.outputKey;\n this.beforeModelCallback = config.beforeModelCallback;\n this.afterModelCallback = config.afterModelCallback;\n this.beforeToolCallback = config.beforeToolCallback;\n this.afterToolCallback = config.afterToolCallback;\n this.codeExecutor = config.codeExecutor;\n\n // TODO - b/425992518: Define these processor arrays.\n // Orders matter, don't change. Append new processors to the end\n this.requestProcessors = config.requestProcessors ?? [\n BASIC_LLM_REQUEST_PROCESSOR,\n IDENTITY_LLM_REQUEST_PROCESSOR,\n INSTRUCTIONS_LLM_REQUEST_PROCESSOR,\n REQUEST_CONFIRMATION_LLM_REQUEST_PROCESSOR,\n CONTENT_REQUEST_PROCESSOR,\n CODE_EXECUTION_REQUEST_PROCESSOR,\n ];\n this.responseProcessors = config.responseProcessors ?? [];\n\n // Preserve the agent transfer behavior.\n const agentTransferDisabled = this.disallowTransferToParent &&\n this.disallowTransferToPeers && !this.subAgents?.length;\n if (!agentTransferDisabled) {\n this.requestProcessors.push(AGENT_TRANSFER_LLM_REQUEST_PROCESSOR);\n }\n\n // Validate generateContentConfig.\n if (config.generateContentConfig) {\n if (config.generateContentConfig.tools) {\n throw new Error('All tools must be set via LlmAgent.tools.');\n }\n if (config.generateContentConfig.systemInstruction) {\n throw new Error(\n 'System instruction must be set via LlmAgent.instruction.',\n );\n }\n if (config.generateContentConfig.responseSchema) {\n throw new Error(\n 'Response schema must be set via LlmAgent.output_schema.');\n }\n } else {\n this.generateContentConfig = {}\n }\n\n // Validate output schema related configurations.\n if (this.outputSchema) {\n if (!this.disallowTransferToParent || !this.disallowTransferToPeers) {\n logger.warn(\n `Invalid config for agent ${this.name}: outputSchema cannot co-exist with agent transfer configurations. Setting disallowTransferToParent=true, disallowTransferToPeers=true`,\n );\n this.disallowTransferToParent = true;\n this.disallowTransferToPeers = true;\n }\n\n if (this.subAgents && this.subAgents.length > 0) {\n throw new Error(\n `Invalid config for agent ${this.name}: if outputSchema is set, subAgents must be empty to disable agent transfer.`,\n );\n }\n\n if (this.tools && this.tools.length > 0) {\n throw new Error(\n `Invalid config for agent ${this.name}: if outputSchema is set, tools must be empty`,\n );\n }\n }\n }\n\n /**\n * The resolved BaseLlm instance.\n *\n * When not set, the agent will inherit the model from its ancestor.\n */\n get canonicalModel(): BaseLlm {\n if (isBaseLlm(this.model)) {\n return this.model;\n }\n\n if (typeof this.model === 'string' && this.model) {\n return LLMRegistry.newLlm(this.model);\n }\n\n let ancestorAgent = this.parentAgent;\n while (ancestorAgent) {\n if (ancestorAgent instanceof LlmAgent) {\n return ancestorAgent.canonicalModel;\n }\n ancestorAgent = ancestorAgent.parentAgent;\n }\n throw new Error(`No model found for ${this.name}.`);\n }\n\n /**\n * The resolved self.instruction field to construct instruction for this\n * agent.\n *\n * This method is only for use by Agent Development Kit.\n * @param context The context to retrieve the session state.\n * @returns The resolved self.instruction field.\n */\n async canonicalInstruction(context: ReadonlyContext):\n Promise<{ instruction: string, requireStateInjection: boolean }> {\n if (typeof this.instruction === 'string') {\n return { instruction: this.instruction, requireStateInjection: true };\n }\n return {\n instruction: await this.instruction(context),\n requireStateInjection: false\n };\n }\n\n /**\n * The resolved self.instruction field to construct global instruction.\n *\n * This method is only for use by Agent Development Kit.\n * @param context The context to retrieve the session state.\n * @returns The resolved self.global_instruction field.\n */\n async canonicalGlobalInstruction(context: ReadonlyContext):\n Promise<{ instruction: string, requireStateInjection: boolean }> {\n if (typeof this.globalInstruction === 'string') {\n return { instruction: this.globalInstruction, requireStateInjection: true };\n }\n return {\n instruction: await this.globalInstruction(context),\n requireStateInjection: false\n };\n }\n\n /**\n * The resolved self.tools field as a list of BaseTool based on the context.\n *\n * This method is only for use by Agent Development Kit.\n */\n async canonicalTools(context?: ReadonlyContext): Promise<BaseTool[]> {\n const resolvedTools: BaseTool[] = [];\n for (const toolUnion of this.tools) {\n const tools = await convertToolUnionToTools(toolUnion, context);\n resolvedTools.push(...tools);\n }\n return resolvedTools;\n }\n\n /**\n * Normalizes a callback or an array of callbacks into an array of callbacks.\n *\n * @param callback The callback or an array of callbacks.\n * @returns An array of callbacks.\n */\n private static normalizeCallbackArray<T>(callback?: T | T[]): T[] {\n if (!callback) {\n return [];\n }\n if (Array.isArray(callback)) {\n return callback;\n }\n return [callback];\n }\n\n /**\n * The resolved self.before_model_callback field as a list of\n * SingleBeforeModelCallback.\n *\n * This method is only for use by Agent Development Kit.\n */\n get canonicalBeforeModelCallbacks(): SingleBeforeModelCallback[] {\n return LlmAgent.normalizeCallbackArray(this.beforeModelCallback);\n }\n\n /**\n * The resolved self.after_model_callback field as a list of\n * SingleAfterModelCallback.\n *\n * This method is only for use by Agent Development Kit.\n */\n get canonicalAfterModelCallbacks(): SingleAfterModelCallback[] {\n return LlmAgent.normalizeCallbackArray(this.afterModelCallback);\n }\n\n /**\n * The resolved self.before_tool_callback field as a list of\n * BeforeToolCallback.\n *\n * This method is only for use by Agent Development Kit.\n */\n get canonicalBeforeToolCallbacks(): SingleBeforeToolCallback[] {\n return LlmAgent.normalizeCallbackArray(this.beforeToolCallback);\n }\n\n /**\n * The resolved self.after_tool_callback field as a list of AfterToolCallback.\n *\n * This method is only for use by Agent Development Kit.\n */\n get canonicalAfterToolCallbacks(): SingleAfterToolCallback[] {\n return LlmAgent.normalizeCallbackArray(this.afterToolCallback);\n }\n\n /**\n * Saves the agent's final response to the session state if configured.\n *\n * It extracts the text content from the final response event, optionally\n * parses it as JSON based on the output schema, and stores the result in the\n * session state using the specified output key.\n *\n * @param event The event to process.\n */\n private maybeSaveOutputToState(event: Event) {\n if (event.author !== this.name) {\n logger.debug(\n `Skipping output save for agent ${this.name}: event authored by ${event.author}`,\n );\n return;\n }\n if (!this.outputKey) {\n logger.debug(\n `Skipping output save for agent ${this.name}: outputKey is not set`,\n );\n return;\n }\n if (!isFinalResponse(event)) {\n logger.debug(\n `Skipping output save for agent ${this.name}: event is not a final response`,\n );\n return;\n }\n if (!event.content?.parts?.length) {\n logger.debug(\n `Skipping output save for agent ${this.name}: event content is empty`,\n );\n return;\n }\n\n const resultStr: string =\n event.content.parts.map((part) => (part.text ? part.text : ''))\n .join('');\n let result: unknown = resultStr;\n if (this.outputSchema) {\n // If the result from the final chunk is just whitespace or empty,\n // it means this is an empty final chunk of a stream.\n // Do not attempt to parse it as JSON.\n if (!resultStr.trim()) {\n return;\n }\n // TODO - b/425992518: Use a proper Schema validation utility.\n // Should use output schema to validate the JSON.\n try {\n result = JSON.parse(resultStr);\n } catch (e) {\n logger.error(`Error parsing output for agent ${this.name}`, e);\n }\n }\n event.actions.stateDelta[this.outputKey] = result;\n }\n\n protected async *\n runAsyncImpl(\n context: InvocationContext,\n ): AsyncGenerator<Event, void, void> {\n while (true) {\n let lastEvent: Event | undefined = undefined;\n for await (const event of this.runOneStepAsync(context)) {\n lastEvent = event;\n this.maybeSaveOutputToState(event);\n yield event;\n }\n\n if (!lastEvent || isFinalResponse(lastEvent)) {\n break;\n }\n if (lastEvent.partial) {\n logger.warn('The last event is partial, which is not expected.');\n break;\n }\n }\n }\n\n protected async *\n runLiveImpl(\n context: InvocationContext,\n ): AsyncGenerator<Event, void, void> {\n for await (const event of this.runLiveFlow(context)) {\n this.maybeSaveOutputToState(event);\n yield event;\n }\n if (context.endInvocation) {\n return;\n }\n }\n\n // --------------------------------------------------------------------------\n // #START LlmFlow Logic\n // --------------------------------------------------------------------------\n private async *\n runLiveFlow(\n invocationContext: InvocationContext,\n ): AsyncGenerator<Event, void, void> {\n // TODO - b/425992518: remove dummy logic, implement this.\n await Promise.resolve();\n throw new Error('LlmAgent.runLiveFlow not implemented');\n }\n\n private async *\n runOneStepAsync(\n invocationContext: InvocationContext,\n ): AsyncGenerator<Event, void, void> {\n const llmRequest: LlmRequest = {\n contents: [],\n toolsDict: {},\n liveConnectConfig: {},\n };\n\n // =========================================================================\n // Preprocess before calling the LLM\n // =========================================================================\n // Runs request processors.\n for (const processor of this.requestProcessors) {\n for await (\n const event of processor.runAsync(invocationContext, llmRequest)) {\n yield event;\n }\n }\n // TODO - b/425992518: check if tool preprocessors can be simplified.\n // Run pre-processors for tools.\n for (const toolUnion of this.tools) {\n const toolContext = new ToolContext({ invocationContext });\n\n // process all tools from this tool union\n const tools = await convertToolUnionToTools(\n toolUnion, new ReadonlyContext(invocationContext));\n for (const tool of tools) {\n await tool.processLlmRequest({ toolContext, llmRequest });\n }\n }\n // =========================================================================\n // Global runtime interruption\n // =========================================================================\n // TODO - b/425992518: global runtime interruption, hacky, fix.\n if (invocationContext.endInvocation) {\n return;\n }\n\n // =========================================================================\n // Calls the LLM\n // =========================================================================\n // TODO - b/425992518: misleading, this is passing metadata.\n const modelResponseEvent = createEvent({\n invocationId: invocationContext.invocationId,\n author: this.name,\n branch: invocationContext.branch,\n });\n for await (const llmResponse of this.callLlmAsync(\n invocationContext, llmRequest, modelResponseEvent)) {\n // ======================================================================\n // Postprocess after calling the LLM\n // ======================================================================\n for await (const event of this.postprocess(\n invocationContext, llmRequest, llmResponse, modelResponseEvent)) {\n // Update the mutable event id to avoid conflict\n modelResponseEvent.id = createNewEventId();\n modelResponseEvent.timestamp = new Date().getTime();\n yield event;\n }\n }\n }\n\n private async *\n postprocess(\n invocationContext: InvocationContext,\n llmRequest: LlmRequest,\n llmResponse: LlmResponse,\n modelResponseEvent: Event,\n ): AsyncGenerator<Event, void, void> {\n // =========================================================================\n // Runs response processors\n // =========================================================================\n for (const processor of this.responseProcessors) {\n for await (\n const event of processor.runAsync(invocationContext, llmResponse)) {\n yield event;\n }\n }\n\n // =========================================================================\n // Builds the merged model response event\n // =========================================================================\n // If no model response, skip.\n if (!llmResponse.content && !llmResponse.errorCode &&\n !llmResponse.interrupted) {\n return;\n }\n\n // Merge llm response with model response event.\n const mergedEvent = createEvent({\n ...modelResponseEvent,\n ...llmResponse,\n });\n\n if (mergedEvent.content) {\n const functionCalls = getFunctionCalls(mergedEvent);\n if (functionCalls?.length) {\n // TODO - b/425992518: rename topopulate if missing.\n populateClientFunctionCallId(mergedEvent);\n // TODO - b/425992518: hacky, transaction log, simplify.\n // Long running is a property of tool in registry.\n mergedEvent.longRunningToolIds = Array.from(\n getLongRunningFunctionCalls(functionCalls, llmRequest.toolsDict));\n }\n }\n yield mergedEvent;\n\n // =========================================================================\n // Process function calls if any, which inlcudes agent transfer.\n // =========================================================================\n if (!getFunctionCalls(mergedEvent)?.length) {\n return;\n }\n\n // Call functions\n // TODO - b/425992518: bloated funciton input, fix.\n // Tool callback passed to get rid of cyclic dependency.\n const functionResponseEvent = await handleFunctionCallsAsync({\n invocationContext: invocationContext,\n functionCallEvent: mergedEvent,\n toolsDict: llmRequest.toolsDict,\n beforeToolCallbacks: this.canonicalBeforeToolCallbacks,\n afterToolCallbacks: this.canonicalAfterToolCallbacks,\n });\n\n if (!functionResponseEvent) {\n return;\n }\n\n // Yiels an authentication event if any.\n // TODO - b/425992518: transaction log session, simplify.\n const authEvent =\n generateAuthEvent(invocationContext, functionResponseEvent);\n if (authEvent) {\n yield authEvent;\n }\n\n // Yields a tool confirmation event if any.\n const toolConfirmationEvent = generateRequestConfirmationEvent({\n invocationContext: invocationContext,\n functionCallEvent: mergedEvent,\n functionResponseEvent: functionResponseEvent,\n });\n if (toolConfirmationEvent) {\n yield toolConfirmationEvent;\n }\n\n // Yields the function response event.\n yield functionResponseEvent;\n\n // If model instruct to transfer to an agent, run the transferred agent.\n const nextAgentName = functionResponseEvent.actions.transferToAgent;\n if (nextAgentName) {\n const nextAgent = this.getAgentByName(invocationContext, nextAgentName);\n for await (const event of nextAgent.runAsync(invocationContext)) {\n yield event;\n }\n }\n }\n\n /**\n * Retrieves an agent from the agent tree by its name.\n *\n * Performing a depth-first search to locate the agent with the given name.\n * - Starts searching from the root agent of the current invocation context.\n * - Traverses down the agent tree to find the specified agent.\n *\n * @param invocationContext The current invocation context.\n * @param agentName The name of the agent to retrieve.\n * @returns The agent with the given name.\n * @throws Error if the agent is not found.\n */\n private getAgentByName(\n invocationContext: InvocationContext,\n agentName: string,\n ): BaseAgent {\n const rootAgent = invocationContext.agent.rootAgent;\n const agentToRun = rootAgent.findAgent(agentName);\n if (!agentToRun) {\n throw new Error(`Agent ${agentName} not found in the agent tree.`);\n }\n return agentToRun;\n }\n\n private async *\n callLlmAsync(\n invocationContext: InvocationContext,\n llmRequest: LlmRequest,\n modelResponseEvent: Event,\n ): AsyncGenerator<LlmResponse, void, void> {\n // Runs before_model_callback if it exists.\n const beforeModelResponse = await this.handleBeforeModelCallback(\n invocationContext, llmRequest, modelResponseEvent);\n if (beforeModelResponse) {\n yield beforeModelResponse;\n return;\n }\n\n llmRequest.config ??= {};\n llmRequest.config.labels ??= {};\n\n // Add agent name as a label to the llm_request. This will help with slicing\n // the billing reports on a per-agent basis.\n if (!llmRequest.config.labels[ADK_AGENT_NAME_LABEL_KEY]) {\n llmRequest.config.labels[ADK_AGENT_NAME_LABEL_KEY] = this.name;\n }\n\n // Calls the LLM.\n const llm = this.canonicalModel;\n // TODO - b/436079721: Add tracer.start_as_current_span('call_llm')\n if (invocationContext.runConfig?.supportCfc) {\n // TODO - b/425992518: Implement CFC call path\n // This is a hack, underneath it calls runLive. Which makes\n // runLive/run mixed.\n throw new Error('CFC is not yet supported in callLlmAsync');\n } else {\n invocationContext.incrementLlmCallCount();\n const responsesGenerator = llm.generateContentAsync(\n llmRequest,\n /* stream= */ invocationContext.runConfig?.streamingMode ===\n StreamingMode.SSE,\n );\n\n for await (const llmResponse of this.runAndHandleError(\n responsesGenerator, invocationContext, llmRequest,\n modelResponseEvent)) {\n // TODO - b/436079721: Add trace_call_llm\n\n // Runs after_model_callback if it exists.\n const alteredLlmResponse = await this.handleAfterModelCallback(\n invocationContext, llmResponse, modelResponseEvent);\n yield alteredLlmResponse ?? llmResponse;\n }\n }\n }\n\n private async handleBeforeModelCallback(\n invocationContext: InvocationContext,\n llmRequest: LlmRequest,\n modelResponseEvent: Event,\n ): Promise<LlmResponse | undefined> {\n // TODO - b/425992518: Clean up eventActions from CallbackContext here as\n // modelResponseEvent.actions is always empty.\n const callbackContext = new CallbackContext(\n { invocationContext, eventActions: modelResponseEvent.actions });\n\n // Plugin callbacks before canonical callbacks\n const beforeModelCallbackResponse =\n await invocationContext.pluginManager.runBeforeModelCallback(\n { callbackContext, llmRequest });\n if (beforeModelCallbackResponse) {\n return beforeModelCallbackResponse;\n }\n\n // If no override was returned from the plugins, run the canonical callbacks\n for (const callback of this.canonicalBeforeModelCallbacks) {\n const callbackResponse =\n await callback({ context: callbackContext, request: llmRequest });\n if (callbackResponse) {\n return callbackResponse;\n }\n }\n return undefined;\n }\n\n private async handleAfterModelCallback(\n invocationContext: InvocationContext,\n llmResponse: LlmResponse,\n modelResponseEvent: Event,\n ): Promise<LlmResponse | undefined> {\n const callbackContext = new CallbackContext(\n { invocationContext, eventActions: modelResponseEvent.actions });\n\n // Plugin callbacks before canonical callbacks\n const afterModelCallbackResponse =\n await invocationContext.pluginManager.runAfterModelCallback(\n { callbackContext, llmResponse });\n if (afterModelCallbackResponse) {\n return afterModelCallbackResponse;\n }\n\n // If no override was returned from the plugins, run the canonical callbacks\n for (const callback of this.canonicalAfterModelCallbacks) {\n const callbackResponse =\n await callback({ context: callbackContext, response: llmResponse });\n if (callbackResponse) {\n return callbackResponse;\n }\n }\n return undefined;\n }\n\n private async *\n runAndHandleError(\n responseGenerator: AsyncGenerator<LlmResponse, void, void>,\n invocationContext: InvocationContext,\n llmRequest: LlmRequest,\n modelResponseEvent: Event,\n ): AsyncGenerator<LlmResponse, void, void> {\n try {\n for await (const response of responseGenerator) {\n yield response;\n }\n } catch (modelError: unknown) {\n // Return an LlmResponse with error details.\n // Note: this will cause agent to work better if there's a loop.\n const callbackContext = new CallbackContext(\n { invocationContext, eventActions: modelResponseEvent.actions });\n\n // Wrapped LLM should throw Error-typed errors\n if (modelError instanceof Error) {\n // Try plugins to recover from the error\n const onModelErrorCallbackResponse =\n await invocationContext.pluginManager.runOnModelErrorCallback({\n callbackContext: callbackContext,\n llmRequest: llmRequest,\n error: modelError as Error\n });\n\n if (onModelErrorCallbackResponse) {\n yield onModelErrorCallbackResponse;\n } else {\n // If no plugins, just return the message.\n const errorResponse = JSON.parse(modelError.message) as\n { error: { code: number; message: string; } };\n\n yield {\n errorCode: String(errorResponse.error.code),\n errorMessage: errorResponse.error.message,\n };\n }\n } else {\n logger.error('Unknown error during response generation', modelError);\n throw modelError;\n }\n }\n }\n\n // --------------------------------------------------------------------------\n // #END LlmFlow Logic\n // --------------------------------------------------------------------------\n\n // TODO - b/425992518: omitted Py LlmAgent features.\n // - code_executor\n // - configurable agents by yaml config\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {InvocationContext} from '../agents/invocation_context.js';\n\nimport {CodeExecutionInput, CodeExecutionResult} from './code_execution_utils.js';\n\n/**\n * The parameters for executing code.\n * */\nexport interface ExecuteCodeParams {\n /** The invocation context of the code execution. */\n invocationContext: InvocationContext;\n /** The input of the code execution. */\n codeExecutionInput: CodeExecutionInput;\n}\n\n/**\n * The code executor allows the agent to execute code blocks from model\n * responses and incorporate the execution results into the final response.\n */\nexport abstract class BaseCodeExecutor {\n /**\n * If true, extract and process data files from the model request\n * and attach them to the code executor.\n *\n * Supported data file MimeTypes are [text/csv].\n * Default to false.\n */\n optimizeDataFile = false;\n\n /**\n * Whether the code executor is stateful. Default to false.\n */\n stateful = false;\n\n /**\n * The number of attempts to retry on consecutive code execution errors.\n * Default to 2.\n */\n errorRetryAttempts = 2;\n\n /**\n * The list of the enclosing delimiters to identify the code blocks.\n * For example, the delimiter('```python\\\\n', '\\\\n```') can be used to\n * identify code blocks with the following format::\n *\n * ```python\n * print(\"hello\")\n * ```\n */\n codeBlockDelimiters: Array<[string, string]> = [\n ['```tool_code\\n', '\\n```'],\n ['```python\\n', '\\n```'],\n ];\n\n /**\n * The delimiters to format the code execution result.\n */\n executionResultDelimiters: [string, string] = ['```tool_output\\n', '\\n```'];\n\n /**\n * Executes code and return the code execution result.\n *\n * @param params The parameters for executing code.\n * @return The result of the code execution.\n */\n abstract executeCode(params: ExecuteCodeParams): Promise<CodeExecutionResult>;\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nconst MODEL_NAME_PATTERN =\n '^projects/[^/]+/locations/[^/]+/publishers/[^/]+/models/(.+)$';\n\n/**\n * Extract the actual model name from either simple or path-based format.\n *\n * @param modelString Either a simple model name like \"gemini-2.5-pro\" or\n * a path-based model name like \"projects/.../models/gemini-2.0-flash-001\"\n * @return The extracted model name (e.g., \"gemini-2.5-pro\")\n */\nexport function extractModelName(modelString: string): string {\n const match = modelString.match(MODEL_NAME_PATTERN);\n if (match) {\n return match[1];\n }\n\n // If it's not a path-based model, return as-is (simple model name)\n return modelString;\n}\n\n/**\n * Check if the model is a Gemini model using regex patterns.\n *\n * @param modelString Either a simple model name or path - based model name\n * @return true if it's a Gemini model, false otherwise.\n */\nexport function isGeminiModel(modelString: string): boolean {\n const modelName = extractModelName(modelString);\n\n return modelName.startsWith('gemini-');\n}\n\n/**\n * Check if the model is a Gemini 1.x model using regex patterns.\n *\n * @param modelString Either a simple model name or path - based model name\n * @return true if it's a Gemini 1.x model, false otherwise.\n */\nexport function isGemini1Model(modelString: string): boolean {\n const modelName = extractModelName(modelString);\n\n return modelName.startsWith('gemini-1');\n}\n\n/**\n * Check if the model is a Gemini 2.x model using regex patterns.\n *\n * @param modelString Either a simple model name or path - based model name\n * @return true if it's a Gemini 2.x model, false otherwise.\n */\nexport function isGemini2Model(modelString: string): boolean {\n const modelName = extractModelName(modelString);\n\n return modelName.startsWith('gemini-2');\n}\n\n/**\n * Check if the model is a Gemini 3.x model using regex patterns.\n *\n * @param modelString Either a simple model name or path - based model name\n * @return true if it's a Gemini 3.x model, false otherwise.\n */\nexport function isGemini3Model(modelString: string): boolean {\n const modelName = extractModelName(modelString);\n\n return modelName.startsWith('gemini-3');\n}\n\n/**\n * Check if the model is a Gemini 3.x preview model.\n * Preview models require special endpoint handling (aiplatform.googleapis.com).\n *\n * @param modelString Either a simple model name or path - based model name\n * @return true if it's a Gemini 3.x preview model, false otherwise.\n */\nexport function isGemini3PreviewModel(modelString: string): boolean {\n const modelName = extractModelName(modelString);\n\n return modelName.startsWith('gemini-3') && modelName.includes('preview');\n}", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {GenerateContentConfig} from '@google/genai'\n\nimport {InvocationContext} from '../agents/invocation_context.js';\nimport {LlmRequest} from '../models/llm_request.js';\nimport {isGemini2Model} from '../utils/model_name.js';\n\nimport {BaseCodeExecutor, ExecuteCodeParams} from './base_code_executor.js';\nimport {CodeExecutionInput, CodeExecutionResult} from './code_execution_utils.js';\n\n/**\n * A code executor that uses the Model's built-in code executor.\n *\n * Currently only supports Gemini 2.0+ models, but will be expanded to\n * other models.\n */\nexport class BuiltInCodeExecutor extends BaseCodeExecutor {\n executeCode(params: ExecuteCodeParams): Promise<CodeExecutionResult> {\n return Promise.resolve({\n stdout: '',\n stderr: '',\n outputFiles: [],\n });\n }\n\n processLlmRequest(llmRequest: LlmRequest) {\n if (llmRequest.model && isGemini2Model(llmRequest.model)) {\n llmRequest.config = llmRequest.config || {};\n llmRequest.config.tools = llmRequest.config.tools || [];\n llmRequest.config.tools.push({codeExecution: {}});\n\n return;\n }\n\n throw new Error(`Gemini code execution tool is not supported for model ${\n llmRequest.model}`);\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {Content, Language, Outcome, Part} from '@google/genai';\n\nimport {deepClone} from '../utils/deep_clone.js';\nimport {base64Encode, isBase64Encoded} from '../utils/env_aware_utils.js';\n\n/**\n * A structure that contains a file name and its content\n */\nexport interface File {\n /**\n * The name of the file with file extension(e.g., ' file.csv')\n * */\n name: string;\n\n /**\n * The base64 - encoded bytes of the file content.\n * */\n content: string;\n\n /**\n * The mime type of the file (e.g., ' image / png')\n * */\n mimeType: string;\n}\n\n/**\n * A structure that contains the input of code execution.\n * */\nexport interface CodeExecutionInput {\n /**\n * The code to execute.\n * */\n code: string;\n\n /**\n * The input files available to the code.\n * */\n inputFiles: File[];\n\n /**\n * The execution ID for the stateful code execution.\n * */\n executionId?: string;\n}\n\n/**\n * A structure that contains the result of code execution.\n * */\nexport interface CodeExecutionResult {\n /**\n * The standard output of the code execution.\n * */\n stdout: string;\n\n /**\n * The standard error of the code execution.\n * */\n stderr: string;\n\n /**\n * The output files from the code execution.\n * */\n outputFiles: File[];\n}\n\n/**\n * Gets the file content as a base64-encoded bytes.\n *\n * @param data The file content bytes.\n * @return The file content as a base64-encoded bytes.\n */\nexport function getEncodedFileContent(data: string): string {\n return isBase64Encoded(data) ? data : base64Encode(data);\n}\n\n// Type to be used for regex matching of code blocks.\ninterface CodeGroupMatch {\n groups?: {prefix?: string; codeStr?: string;};\n index?: number;\n length?: number;\n}\n\n/**\n * Extracts the first code block from the content and truncate everything after\n * it.\n *\n * @param content The mutable content to extract the code from.\n * @param codeBlockDelimiters The list of the enclosing delimiters to identify\n * the code blocks.\n * @return The first code block if found, otherwise None.\n */\nexport function extractCodeAndTruncateContent(\n content: Content,\n codeBlockDelimiters: Array<[string, string]>,\n ): string {\n if (!content.parts?.length) {\n return '';\n }\n\n // Extract the code from the executable code parts if there're no associated\n // code execution result parts.\n for (let i = 0; i < content.parts.length; i++) {\n const part = content.parts[i];\n if (part.executableCode &&\n (i === content.parts.length - 1 ||\n !content.parts[i + 1].codeExecutionResult)) {\n content.parts = content.parts.slice(0, i + 1);\n return part.executableCode.code!;\n }\n }\n\n // Extract the code from the text parts.\n const textParts = content.parts.filter((part) => part.text);\n if (!textParts.length) {\n return '';\n }\n\n const firstTextPart = deepClone(textParts[0])!;\n const responseText = textParts.map((part) => part.text!).join('\\n');\n\n // Find the first code block.\n const leadingDelimiterPattern =\n codeBlockDelimiters.map((d) => d[0]).join('|');\n const trailingDelimiterPattern =\n codeBlockDelimiters.map((d) => d[1]).join('|');\n const match =\n new RegExp(\n `?<prefix>.*?)(${leadingDelimiterPattern})(?<codeStr>.*?)(${\n trailingDelimiterPattern})(?<suffix>.*?)$`,\n 's').exec(responseText) as unknown as CodeGroupMatch |\n null;\n\n const {prefix, codeStr} = match?.groups || {};\n\n if (!codeStr) {\n return '';\n }\n\n content.parts = [];\n\n if (prefix) {\n firstTextPart.text = prefix;\n content.parts.push(firstTextPart);\n }\n content.parts.push(buildExecutableCodePart(codeStr));\n\n return codeStr;\n}\n\n/**\n * Builds an executable code part with code string.\n *\n * @param code The code string.\n * @return The constructed executable code part.\n */\nexport function buildExecutableCodePart(code: string): Part {\n return {\n text: code,\n executableCode: {\n code,\n language: Language.PYTHON,\n },\n };\n}\n\n/**\n * Builds the code execution result part from the code execution result.\n *\n * @param codeExecutionResult The code execution result.\n * @return The code execution result part.\n */\nexport function buildCodeExecutionResultPart(\n codeExecutionResult: CodeExecutionResult,\n ): Part {\n if (codeExecutionResult.stderr) {\n return {\n text: codeExecutionResult.stderr,\n codeExecutionResult: {\n outcome: Outcome.OUTCOME_FAILED,\n },\n };\n }\n\n const finalResult = [];\n if (codeExecutionResult.stdout || !codeExecutionResult.outputFiles) {\n finalResult.push(`Code execution result:\\n${codeExecutionResult.stdout}\\n`);\n }\n if (codeExecutionResult.outputFiles) {\n finalResult.push(\n `Saved artifacts:\\n` +\n codeExecutionResult.outputFiles.map(f => f.name).join(', '));\n }\n\n return {\n text: finalResult.join('\\n\\n'),\n codeExecutionResult: {\n outcome: Outcome.OUTCOME_OK,\n },\n };\n}\n\n/**\n * Converts the code execution parts to text parts in a Content.\n *\n * @param content The mutable content to convert the code execution parts to\n * text parts.\n * @param codeBlockDelimiter The delimiter to format the code block.\n * @param executionResultDelimiters The delimiter to format the code execution\n * result.\n * @return The converted content.\n */\nexport function convertCodeExecutionParts(\n content: Content,\n codeBlockDelimiter: [string, string],\n executionResultDelimiters: [string, string],\n) {\n if (!content.parts?.length) {\n return;\n }\n\n const lastPart = content.parts[content.parts.length - 1];\n\n if (lastPart.executableCode) {\n content.parts[content.parts.length - 1] = {\n text: codeBlockDelimiter[0] + lastPart.executableCode.code +\n codeBlockDelimiter[1],\n };\n } else if (content.parts.length == 1 && lastPart.codeExecutionResult) {\n content.parts[content.parts.length - 1] = {\n text: executionResultDelimiters[0] + lastPart.codeExecutionResult.output +\n executionResultDelimiters[1],\n };\n content.role = 'user'\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {Event} from '../events/event.js';\n\n// TODO - b/425992518: replace with lodash deep clone.\nexport function deepClone<T>(obj: T): T {\n if (obj === undefined) {\n return undefined as T;\n }\n\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {State} from '../sessions/state.js';\nimport {deepClone} from '../utils/deep_clone.js';\n\nimport {File} from './code_execution_utils.js';\n\nconst CONTEXT_KEY = '_code_execution_context';\nconst SESSION_ID_KEY = 'execution_session_id';\nconst PROCESSED_FILE_NAMES_KEY = 'processed_input_files';\nconst INPUT_FILE_KEY = '_code_executor_input_files';\nconst ERROR_COUNT_KEY = '_code_executor_error_counts';\nconst CODE_EXECUTION_RESULTS_KEY = '_code_execution_results';\n\ninterface CodeExecutionResult {\n code: string;\n resultStdout: string;\n resultStderr: string;\n timestamp: number;\n}\n\n/**\n * The parameters for updating the code execution result.\n * */\nexport interface UpdateCodeExecutionResultParams {\n invocationId: string;\n code: string;\n resultStdout: string;\n resultStderr: string;\n}\n\n/**\n * The persistent context used to configure the code executor.\n */\nexport class CodeExecutorContext {\n private readonly context:\n {[SESSION_ID_KEY]?: string;[PROCESSED_FILE_NAMES_KEY]?: string[];};\n\n constructor(private readonly sessionState: State) {\n this.context = sessionState.get(CONTEXT_KEY) ?? {};\n this.sessionState = sessionState;\n }\n\n /**\n * Gets the state delta to update in the persistent session state.\n * @return The state delta to update in the persistent session state.\n */\n getStateDelta(): Record<string, unknown> {\n return {\n [CONTEXT_KEY]: deepClone(this.context),\n };\n }\n\n /**\n * Gets the execution ID for the code executor.\n * @return The execution ID for the code executor.\n */\n getExecutionId(): string|undefined {\n if (!(SESSION_ID_KEY in this.context)) {\n return undefined;\n }\n\n return this.context[SESSION_ID_KEY];\n }\n\n /**\n * Sets the execution ID for the code executor.\n * @param executionId The execution ID to set.\n */\n setExecutionId(executionId: string) {\n this.context[SESSION_ID_KEY] = executionId;\n }\n\n /**\n * Gets the processed file names from the session state.\n * @return A list of processed file names in the code executor context.\n */\n getProcessedFileNames(): string[] {\n if (!(PROCESSED_FILE_NAMES_KEY in this.context)) {\n return [];\n }\n\n return this.context[PROCESSED_FILE_NAMES_KEY]!;\n }\n\n /**\n * Adds the processed file names to the session state.\n * @param fileNames The file names to add to the session state.\n */\n addProcessedFileNames(fileNames: string[]) {\n if (!(PROCESSED_FILE_NAMES_KEY in this.context)) {\n this.context[PROCESSED_FILE_NAMES_KEY] = [];\n }\n\n this.context[PROCESSED_FILE_NAMES_KEY]!.push(...fileNames);\n }\n\n /**\n * Gets the input files from the session state.\n * @return A list of input files in the code executor context.\n */\n getInputFiles(): File[] {\n if (!(INPUT_FILE_KEY in this.sessionState)) {\n return [];\n }\n\n return this.sessionState.get(INPUT_FILE_KEY) as File[];\n }\n\n /**\n * Adds the input files to the session state.\n * @param inputFiles The input files to add to the session state.\n */\n addInputFiles(inputFiles: File[]) {\n if (!(INPUT_FILE_KEY in this.sessionState)) {\n this.sessionState.set(INPUT_FILE_KEY, []);\n }\n\n (this.sessionState.get(INPUT_FILE_KEY) as File[]).push(...inputFiles);\n }\n\n clearInputFiles() {\n if (INPUT_FILE_KEY in this.sessionState) {\n this.sessionState.set(INPUT_FILE_KEY, []);\n }\n\n if (PROCESSED_FILE_NAMES_KEY in this.context) {\n this.context[PROCESSED_FILE_NAMES_KEY] = [];\n }\n }\n\n /**\n * Gets the error count from the session state.\n * @param invocationId The invocation ID to get the error count for.\n * @return The error count for the given invocation ID.\n */\n getErrorCount(invocationId: string): number {\n if (!(ERROR_COUNT_KEY in this.sessionState)) {\n return 0;\n }\n\n return (this.sessionState.get(ERROR_COUNT_KEY) as\n Record<string, number>)[invocationId] as number ||\n 0;\n }\n\n /**\n * Increments the error count from the session state.\n * @param invocationId The invocation ID to increment the error count for.\n */\n incrementErrorCount(invocationId: string) {\n if (!(ERROR_COUNT_KEY in this.sessionState)) {\n this.sessionState.set(ERROR_COUNT_KEY, {});\n }\n\n (this.sessionState.get(ERROR_COUNT_KEY) as\n Record<string, number>)[invocationId] =\n (this.getErrorCount(invocationId) + 1);\n }\n\n /**\n * Resets the error count from the session state.\n * @param invocationId The invocation ID to reset the error count for.\n */\n resetErrorCount(invocationId: string) {\n if (!(ERROR_COUNT_KEY in this.sessionState)) {\n return;\n }\n\n const errorCounts =\n this.sessionState.get(ERROR_COUNT_KEY) as Record<string, number>;\n\n if (invocationId in errorCounts) {\n delete errorCounts[invocationId];\n }\n }\n\n /**\n * Updates the code execution result.\n * @param invocationId The invocation ID to update the code execution result\n * for.\n * @param code The code to execute.\n * @param resultStdout The standard output of the code execution.\n * @param resultStderr The standard error of the code execution.\n */\n updateCodeExecutionResult({\n invocationId,\n code,\n resultStdout,\n resultStderr,\n }: UpdateCodeExecutionResultParams) {\n if (!(CODE_EXECUTION_RESULTS_KEY in this.sessionState)) {\n this.sessionState.set(CODE_EXECUTION_RESULTS_KEY, {});\n }\n\n const codeExecutionResults =\n this.sessionState.get(CODE_EXECUTION_RESULTS_KEY) as\n Record<string, CodeExecutionResult[]>;\n\n if (!(invocationId in codeExecutionResults)) {\n codeExecutionResults[invocationId] = [];\n }\n\n codeExecutionResults[invocationId].push({\n code,\n resultStdout,\n resultStderr,\n timestamp: Date.now(),\n });\n }\n\n /**\n * Gets the code executor context from the session state.\n * @param invocationId The session state to get the code executor context\n * from.\n * @return The code execution context for the given invocation ID.\n */\n getCodeExecutionContext(invocationId: string): Record<string, unknown> {\n return this.sessionState.get(CONTEXT_KEY) || {};\n }\n}", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n// version: major.minor.patch\nexport const version = '0.2.4';\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {version} from '../version.js';\n\nimport {isBrowser} from './env_aware_utils.js';\n\nconst ADK_LABEL = 'google-adk';\nconst LANGUAGE_LABEL = 'gl-typescript';\nconst AGENT_ENGINE_TELEMETRY_TAG = 'remote_reasoning_engine';\nconst AGENT_ENGINE_TELEMETRY_ENV_VARIABLE_NAME = 'GOOGLE_CLOUD_AGENT_ENGINE_ID';\n\n// TODO: b/468053794 - Configurable client labels in AsyncLocalStorage and/or\n// browser equivalent\n\nfunction _getDefaultLabels(): string[] {\n let frameworkLabel = `${ADK_LABEL}/${version}`;\n\n if (!isBrowser() && process.env[AGENT_ENGINE_TELEMETRY_ENV_VARIABLE_NAME]) {\n frameworkLabel = `${frameworkLabel}+${AGENT_ENGINE_TELEMETRY_TAG}`;\n }\n\n // TODO: b/468051563 - Consider extracting browser name and version from\n // userAgent string\n const languageLabel = `${LANGUAGE_LABEL}/${\n isBrowser() ? window.navigator.userAgent : process.version}`;\n return [frameworkLabel, languageLabel];\n}\n\n/**\n * Returns the current list of client labels that can be added to HTTP Headers.\n */\nexport function getClientLabels(): string[] {\n const labels = _getDefaultLabels();\n // TODO: b/468053794 - Configurable client labels in AsyncLocalStorage and/or\n // browser equivalent\n return labels;\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {getClientLabels} from '../utils/client_labels.js';\n\nimport {BaseLlmConnection} from './base_llm_connection.js';\nimport {LlmRequest} from './llm_request.js';\nimport {LlmResponse} from './llm_response.js';\n\nconst BASE_MODEL_SYMBOL = Symbol('baseModel');\n\nexport function isBaseLlm(obj: unknown): obj is BaseLlm {\n return typeof obj === 'object' && obj !== null && BASE_MODEL_SYMBOL in obj &&\n obj[BASE_MODEL_SYMBOL] === true;\n}\n\n/**\n * The BaseLLM class.\n */\nexport abstract class BaseLlm {\n readonly[BASE_MODEL_SYMBOL] = true;\n\n readonly model: string;\n\n /**\n * Creates an instance of BaseLLM.\n * @param params The parameters for creating a BaseLlm instance.\n * @param params.model The name of the LLM, e.g. gemini-1.5-flash or\n * gemini-1.5-flash-001.\n */\n constructor({model}: {model: string}) {\n this.model = model;\n }\n\n /**\n * List of supported models in regex for LlmRegistry.\n */\n static readonly supportedModels: Array<string|RegExp> = [];\n\n /**\n * Generates one content from the given contents and tools.\n *\n * @param llmRequest LlmRequest, the request to send to the LLM.\n * @param stream whether to do streaming call.\n * For non-streaming call, it will only yield one Content.\n * @return A generator of LlmResponse.\n */\n abstract generateContentAsync(llmRequest: LlmRequest, stream?: boolean):\n AsyncGenerator<LlmResponse, void>;\n\n /**\n * Creates a live connection to the LLM.\n *\n * @param llmRequest LlmRequest, the request to send to the LLM.\n * @return A live connection to the LLM.\n */\n abstract connect(llmRequest: LlmRequest): Promise<BaseLlmConnection>;\n\n protected get trackingHeaders(): Record<string, string> {\n const labels = getClientLabels();\n const headerValue = labels.join(' ');\n return {\n 'x-goog-api-client': headerValue,\n 'user-agent': headerValue,\n };\n }\n\n /**\n * Appends a user content, so that model can continue to output.\n *\n * @param llmRequest LlmRequest, the request to send to the LLM.\n */\n maybeAppendUserContent(llmRequest: LlmRequest): void {\n if (llmRequest.contents.length === 0) {\n llmRequest.contents.push({\n role: 'user',\n parts: [\n {text: 'Handle the requests as specified in the System Instruction.'}\n ],\n });\n }\n\n if (llmRequest.contents[llmRequest.contents.length - 1]?.role !== 'user') {\n llmRequest.contents.push({\n role: 'user',\n parts: [{\n text:\n 'Continue processing previous requests as instructed. Exit or provide a summary if no more outputs are needed.'\n }],\n });\n }\n }\n}", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Content, FunctionDeclaration, GenerateContentConfig, LiveConnectConfig, SchemaUnion} from '@google/genai';\n\nimport {BaseTool} from '../tools/base_tool.js';\n\n/**\n * LLM request class that allows passing in tools, output schema and system\n * instructions to the model.\n */\nexport interface LlmRequest {\n /**\n * The model name.\n */\n model?: string;\n\n /**\n * The contents to send to the model.\n */\n contents: Content[];\n\n /**\n * Additional config for the generate content request.\n * Tools in generateContentConfig should not be set directly; use appendTools.\n */\n config?: GenerateContentConfig;\n\n liveConnectConfig: LiveConnectConfig;\n\n /**\n * The tools dictionary. Excluded from JSON serialization.\n */\n toolsDict: {[key: string]: BaseTool};\n}\n\n/**\n * Appends instructions to the system instruction.\n * @param instructions The instructions to append.\n */\nexport function appendInstructions(\n llmRequest: LlmRequest,\n instructions: string[],\n ): void {\n if (!llmRequest.config) {\n llmRequest.config = {};\n }\n const newInstructions = instructions.join('\\n\\n');\n if (llmRequest.config.systemInstruction) {\n llmRequest.config.systemInstruction += '\\n\\n' + newInstructions;\n } else {\n llmRequest.config.systemInstruction = newInstructions;\n }\n}\n\n /**\n * Appends tools to the request.\n * @param tools The tools to append.\n */\nexport function appendTools(\n llmRequest: LlmRequest,\n tools: BaseTool[],\n ): void {\n if (!tools?.length) {\n return;\n }\n\n const functionDeclarations: FunctionDeclaration[] = [];\n for (const tool of tools) {\n const declaration = tool._getDeclaration();\n if (declaration) {\n functionDeclarations.push(declaration);\n llmRequest.toolsDict[tool.name] = tool;\n }\n }\n\n if (functionDeclarations.length) {\n if (!llmRequest.config) {\n llmRequest.config = {};\n }\n if (!llmRequest.config.tools) {\n llmRequest.config.tools = [];\n }\n llmRequest.config.tools.push({functionDeclarations});\n }\n}\n\n /**\n * Sets the output schema for the request.\n *\n * @param schema The JSON Schema object to set as the output schema.\n */\nexport function setOutputSchema(\n llmRequest: LlmRequest,\n schema: SchemaUnion,\n ): void {\n if (!llmRequest.config) {\n llmRequest.config = {};\n }\n llmRequest.config.responseSchema = schema;\n llmRequest.config.responseMimeType = 'application/json';\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n Blob,\n createPartFromText,\n FileData,\n FinishReason,\n GenerateContentResponse,\n GoogleGenAI,\n Part,\n} from '@google/genai';\n\nimport {logger} from '../utils/logger.js';\nimport {isGemini3PreviewModel} from '../utils/model_name.js';\nimport {GoogleLLMVariant} from '../utils/variant_utils.js';\n\nimport {BaseLlm} from './base_llm.js';\nimport {BaseLlmConnection} from './base_llm_connection.js';\nimport {GeminiLlmConnection} from './gemini_llm_connection.js';\nimport {LlmRequest} from './llm_request.js';\nimport {createLlmResponse, LlmResponse} from './llm_response.js';\n\nconst AGENT_ENGINE_TELEMETRY_TAG = 'remote_reasoning_engine';\nconst AGENT_ENGINE_TELEMETRY_ENV_VARIABLE_NAME = 'GOOGLE_CLOUD_AGENT_ENGINE_ID';\n\n/**\n * Default API endpoint for Gemini 3 preview models.\n * Gemini 3 preview models require the aiplatform.googleapis.com endpoint with\n * the publishers/google path prefix.\n *\n * The SDK constructs URLs like: ${baseUrl}/models/${model}:generateContent\n * But Gemini 3 preview needs: https://aiplatform.googleapis.com/v1/publishers/google/models/${model}:generateContent\n *\n * So we set the baseUrl to include the path prefix up to (but not including) /models/\n */\nconst GEMINI3_PREVIEW_API_ENDPOINT =\n 'https://aiplatform.googleapis.com/v1/publishers/google';\n\n/**\n * The parameters for creating a Gemini instance.\n */\nexport interface GeminiParams {\n /**\n * The name of the model to use. Defaults to 'gemini-2.5-flash'.\n */\n model?: string;\n /**\n * The API key to use for the Gemini API. If not provided, it will look for\n * the GOOGLE_GENAI_API_KEY or GEMINI_API_KEY environment variable.\n */\n apiKey?: string;\n /**\n * Whether to use Vertex AI. If true, `project`, `location`\n * should be provided.\n */\n vertexai?: boolean;\n /**\n * The Vertex AI project ID. Required if `vertexai` is true.\n */\n project?: string;\n /**\n * The Vertex AI location. Required if `vertexai` is true.\n */\n location?: string;\n /**\n * Headers to merge with internally crafted headers.\n */\n headers?: Record<string, string>;\n /**\n * Custom API endpoint URL. If not provided, uses the default endpoint\n * based on the model type:\n * - Gemini 3 preview models: aiplatform.googleapis.com\n * - Other models: uses SDK default (generativelanguage.googleapis.com)\n *\n * Can also be set via GEMINI_API_ENDPOINT environment variable.\n */\n apiEndpoint?: string;\n}\n\n/**\n * Integration for Gemini models.\n */\nexport class Gemini extends BaseLlm {\n private readonly apiKey?: string;\n private readonly vertexai: boolean;\n private readonly project?: string;\n private readonly location?: string;\n private readonly headers?: Record<string, string>;\n private readonly apiEndpoint?: string;\n private readonly isGemini3Preview: boolean;\n\n /**\n * @param params The parameters for creating a Gemini instance.\n */\n constructor({\n model,\n apiKey,\n vertexai,\n project,\n location,\n headers,\n apiEndpoint,\n }: GeminiParams) {\n if (!model) {\n model = 'gemini-2.5-flash';\n }\n\n super({model});\n\n this.project = project;\n this.location = location;\n this.apiKey = apiKey;\n this.headers = headers;\n this.isGemini3Preview = isGemini3PreviewModel(model);\n\n const canReadEnv = typeof process === 'object';\n\n // Handle API endpoint configuration\n this.apiEndpoint = apiEndpoint;\n if (!this.apiEndpoint && canReadEnv) {\n this.apiEndpoint = process.env['GEMINI_API_ENDPOINT'];\n }\n // For Gemini 3 preview models, use the aiplatform.googleapis.com endpoint by default\n if (!this.apiEndpoint && this.isGemini3Preview) {\n this.apiEndpoint = GEMINI3_PREVIEW_API_ENDPOINT;\n logger.info(`Using Gemini 3 preview endpoint: ${this.apiEndpoint}`);\n }\n\n // Determine vertexai mode from constructor or environment\n let useVertexAI = !!vertexai;\n if (!useVertexAI && canReadEnv) {\n const vertexAIfromEnv = process.env['GOOGLE_GENAI_USE_VERTEXAI'];\n if (vertexAIfromEnv) {\n useVertexAI =\n vertexAIfromEnv.toLowerCase() === 'true' || vertexAIfromEnv === '1';\n }\n }\n\n // For Gemini 3 preview models, force API key mode instead of Vertex AI.\n // This is because Gemini 3 preview requires a special endpoint path\n // (publishers/google/models/) that is not compatible with standard Vertex AI\n // SDK configuration. The custom apiEndpoint is only applied in non-Vertex AI mode.\n if (this.isGemini3Preview && useVertexAI) {\n // Check if API key is available before switching modes\n const availableApiKey =\n apiKey ||\n (canReadEnv\n ? process.env['GOOGLE_GENAI_API_KEY'] || process.env['GEMINI_API_KEY']\n : undefined);\n if (availableApiKey) {\n logger.info(\n 'Gemini 3 preview detected with Vertex AI mode. Switching to API key mode for correct endpoint handling.',\n );\n useVertexAI = false;\n this.apiKey = availableApiKey;\n } else {\n logger.warn(\n 'Gemini 3 preview requires API key authentication for correct endpoint handling. ' +\n 'Set GEMINI_API_KEY or GOOGLE_GENAI_API_KEY environment variable for best compatibility.',\n );\n }\n }\n\n this.vertexai = useVertexAI;\n\n if (this.vertexai) {\n if (canReadEnv && !this.project) {\n this.project = process.env['GOOGLE_CLOUD_PROJECT'];\n }\n if (canReadEnv && !this.location) {\n this.location = process.env['GOOGLE_CLOUD_LOCATION'];\n }\n if (!this.project) {\n throw new Error(\n 'VertexAI project must be provided via constructor or GOOGLE_CLOUD_PROJECT environment variable.',\n );\n }\n if (!this.location) {\n throw new Error(\n 'VertexAI location must be provided via constructor or GOOGLE_CLOUD_LOCATION environment variable.',\n );\n }\n } else {\n if (!this.apiKey && canReadEnv) {\n this.apiKey =\n process.env['GOOGLE_GENAI_API_KEY'] || process.env['GEMINI_API_KEY'];\n }\n if (!this.apiKey) {\n throw new Error(\n 'API key must be provided via constructor or GOOGLE_GENAI_API_KEY or GEMINI_API_KEY environment variable.',\n );\n }\n }\n }\n\n /**\n * A list of model name patterns that are supported by this LLM.\n *\n * @returns A list of supported models.\n */\n static override readonly supportedModels: Array<string | RegExp> = [\n /gemini-.*/,\n // fine-tuned vertex endpoint pattern\n /projects\\/.+\\/locations\\/.+\\/endpoints\\/.+/,\n // vertex gemini long name\n /projects\\/.+\\/locations\\/.+\\/publishers\\/google\\/models\\/gemini.+/,\n ];\n\n private _apiClient?: GoogleGenAI;\n private _apiBackend?: GoogleLLMVariant;\n private _trackingHeaders?: Record<string, string>;\n private _liveApiVersion?: string;\n private _liveApiClient?: GoogleGenAI;\n\n /**\n * Sends a request to the Gemini model.\n *\n * @param llmRequest LlmRequest, the request to send to the Gemini model.\n * @param stream bool = false, whether to do streaming call.\n * @yields LlmResponse: The model response.\n */\n override async *generateContentAsync(\n llmRequest: LlmRequest,\n stream = false,\n ): AsyncGenerator<LlmResponse, void> {\n this.preprocessRequest(llmRequest);\n this.maybeAppendUserContent(llmRequest);\n logger.info(\n `Sending out request, model: ${llmRequest.model}, backend: ${\n this.apiBackend\n }, stream: ${stream}`,\n );\n\n if (llmRequest.config?.httpOptions) {\n llmRequest.config.httpOptions.headers = {\n ...llmRequest.config.httpOptions.headers,\n ...this.trackingHeaders,\n };\n }\n\n if (stream) {\n const streamResult = await this.apiClient.models.generateContentStream({\n model: llmRequest.model ?? this.model,\n contents: llmRequest.contents,\n config: llmRequest.config,\n });\n let thoughtText = '';\n let thoughtSignature: string | undefined;\n let text = '';\n let usageMetadata;\n let lastResponse: GenerateContentResponse | undefined;\n\n // TODO - b/425992518: verify the type of streaming response is correct.\n for await (const response of streamResult) {\n lastResponse = response;\n const llmResponse = createLlmResponse(response);\n usageMetadata = llmResponse.usageMetadata;\n const firstPart = llmResponse.content?.parts?.[0];\n // Accumulates the text and thought text from the first part.\n if (firstPart?.text) {\n if ('thought' in firstPart && firstPart.thought) {\n thoughtText += firstPart.text;\n // Preserve thoughtSignature from the thought parts for Gemini 3 thinking mode\n if ('thoughtSignature' in firstPart && firstPart.thoughtSignature) {\n thoughtSignature = firstPart.thoughtSignature as string;\n }\n } else {\n text += firstPart.text;\n }\n llmResponse.partial = true;\n } else if (\n (thoughtText || text) &&\n (!firstPart || !firstPart.inlineData)\n ) {\n // Flushes the data if there's no more text.\n const parts: Part[] = [];\n if (thoughtText) {\n // Include thoughtSignature when flushing accumulated thought text\n // This is required for Gemini 3 thinking mode to maintain signature chain\n const thoughtPart: Part = {text: thoughtText, thought: true};\n if (thoughtSignature) {\n thoughtPart.thoughtSignature = thoughtSignature;\n }\n parts.push(thoughtPart);\n }\n if (text) {\n parts.push(createPartFromText(text));\n }\n yield {\n content: {\n role: 'model',\n parts,\n },\n usageMetadata: llmResponse.usageMetadata,\n };\n thoughtText = '';\n // Keep thoughtSignature for function calls - Gemini 3 requires it on function call parts\n text = '';\n }\n\n // For Gemini 3 thinking mode: ensure function call parts have thoughtSignature\n // The API may return function calls without thoughtSignature, but when sending\n // the history back to the model, each function call part needs a thoughtSignature\n // to maintain the reasoning chain.\n if (\n this.isGemini3Preview &&\n thoughtSignature &&\n llmResponse.content?.parts\n ) {\n for (const part of llmResponse.content.parts) {\n if (part.functionCall && !part.thoughtSignature) {\n part.thoughtSignature = thoughtSignature;\n }\n }\n }\n\n yield llmResponse;\n\n // Clear thoughtSignature after yielding function call response\n // The signature has been applied to the function call parts\n if (llmResponse.content?.parts?.some(part => part.functionCall)) {\n thoughtSignature = undefined;\n }\n }\n if (\n (text || thoughtText) &&\n lastResponse?.candidates?.[0]?.finishReason === FinishReason.STOP\n ) {\n const parts: Part[] = [];\n if (thoughtText) {\n // Include thoughtSignature in final flush as well\n const thoughtPart: Part = {text: thoughtText, thought: true};\n if (thoughtSignature) {\n thoughtPart.thoughtSignature = thoughtSignature;\n }\n parts.push(thoughtPart);\n }\n if (text) {\n parts.push({text: text});\n }\n yield {\n content: {\n role: 'model',\n parts,\n },\n usageMetadata,\n };\n }\n } else {\n const response = await this.apiClient.models.generateContent({\n model: llmRequest.model ?? this.model,\n contents: llmRequest.contents,\n config: llmRequest.config,\n });\n const llmResponse = createLlmResponse(response);\n\n // For Gemini 3 thinking mode in non-streaming: propagate thoughtSignature\n // from thought parts to function call parts if they don't have one.\n // This ensures the reasoning chain is maintained in multi-turn conversations.\n if (this.isGemini3Preview && llmResponse.content?.parts) {\n // Find the thoughtSignature from thought parts\n let thoughtSig: string | undefined;\n for (const part of llmResponse.content.parts) {\n if (part.thought && part.thoughtSignature) {\n thoughtSig = part.thoughtSignature;\n break;\n }\n }\n // Apply to function call parts that don't have a signature\n if (thoughtSig) {\n for (const part of llmResponse.content.parts) {\n if (part.functionCall && !part.thoughtSignature) {\n part.thoughtSignature = thoughtSig;\n }\n }\n }\n }\n\n yield llmResponse;\n }\n }\n\n get apiClient(): GoogleGenAI {\n if (this._apiClient) {\n return this._apiClient;\n }\n\n const combinedHeaders = {\n ...this.trackingHeaders,\n ...this.headers,\n };\n\n if (this.vertexai) {\n this._apiClient = new GoogleGenAI({\n vertexai: this.vertexai,\n project: this.project,\n location: this.location,\n httpOptions: {headers: combinedHeaders},\n });\n } else {\n // Build httpOptions with optional baseUrl for Gemini 3 preview models\n const httpOptions: Record<string, unknown> = {headers: combinedHeaders};\n if (this.apiEndpoint) {\n httpOptions.baseUrl = this.apiEndpoint;\n logger.debug(`Using custom API endpoint: ${this.apiEndpoint}`);\n\n // For Gemini 3 preview models on aiplatform.googleapis.com, we need to:\n // 1. Use the baseUrl that includes /v1/publishers/google path\n // 2. Prevent the SDK from adding its own API version prefix\n // The baseUrl already contains the version, so we don't need apiVersion\n if (this.isGemini3Preview) {\n // Set empty apiVersion to prevent SDK from adding version prefix\n // since the version is already included in the baseUrl\n httpOptions.apiVersion = '';\n logger.info(\n `Gemini 3 preview mode: using direct API path without version prefix`,\n );\n }\n }\n\n // Explicitly set vertexai: false to prevent SDK from auto-detecting\n // Vertex AI mode based on environment (e.g., GCP credentials on Cloud Run).\n // This ensures the API key authentication and custom baseUrl are used.\n this._apiClient = new GoogleGenAI({\n apiKey: this.apiKey,\n vertexai: false,\n httpOptions,\n });\n }\n return this._apiClient;\n }\n\n get apiBackend(): GoogleLLMVariant {\n if (!this._apiBackend) {\n this._apiBackend = this.apiClient.vertexai\n ? GoogleLLMVariant.VERTEX_AI\n : GoogleLLMVariant.GEMINI_API;\n }\n return this._apiBackend;\n }\n\n get liveApiVersion(): string {\n if (!this._liveApiVersion) {\n this._liveApiVersion =\n this.apiBackend === GoogleLLMVariant.VERTEX_AI ? 'v1beta1' : 'v1alpha';\n }\n return this._liveApiVersion;\n }\n\n get liveApiClient(): GoogleGenAI {\n if (!this._liveApiClient) {\n const httpOptions: Record<string, unknown> = {\n headers: this.trackingHeaders,\n apiVersion: this.liveApiVersion,\n };\n if (this.apiEndpoint) {\n httpOptions.baseUrl = this.apiEndpoint;\n\n // For Gemini 3 preview models, the baseUrl already contains the version\n // so we don't need the SDK to add another version prefix\n if (this.isGemini3Preview) {\n httpOptions.apiVersion = '';\n }\n }\n\n this._liveApiClient = new GoogleGenAI({\n apiKey: this.apiKey,\n httpOptions,\n });\n }\n return this._liveApiClient;\n }\n\n /**\n * Connects to the Gemini model and returns an llm connection.\n *\n * @param llmRequest LlmRequest, the request to send to the Gemini model.\n * @returns BaseLlmConnection, the connection to the Gemini model.\n */\n override async connect(llmRequest: LlmRequest): Promise<BaseLlmConnection> {\n // add tracking headers to custom headers and set api_version given\n // the customized http options will override the one set in the api client\n // constructor\n if (llmRequest.liveConnectConfig?.httpOptions) {\n if (!llmRequest.liveConnectConfig.httpOptions.headers) {\n llmRequest.liveConnectConfig.httpOptions.headers = {};\n }\n Object.assign(\n llmRequest.liveConnectConfig.httpOptions.headers,\n this.trackingHeaders,\n );\n // For Gemini 3 preview, the baseUrl already contains the version\n // so we use empty apiVersion to prevent double version prefix\n llmRequest.liveConnectConfig.httpOptions.apiVersion = this\n .isGemini3Preview\n ? ''\n : this.liveApiVersion;\n }\n\n if (llmRequest.config?.systemInstruction) {\n llmRequest.liveConnectConfig.systemInstruction = {\n role: 'system',\n // TODO - b/425992518: validate type casting works well.\n parts: [\n createPartFromText(llmRequest.config.systemInstruction as string),\n ],\n };\n }\n\n llmRequest.liveConnectConfig.tools = llmRequest.config?.tools;\n\n const liveSession = await this.liveApiClient.live.connect({\n model: llmRequest.model ?? this.model,\n config: llmRequest.liveConnectConfig,\n callbacks: {\n // TODO - b/425992518: GenAI SDK inconsistent API, missing methods.\n onmessage: () => {},\n },\n });\n return new GeminiLlmConnection(liveSession);\n }\n\n private preprocessRequest(llmRequest: LlmRequest): void {\n if (this.apiBackend === GoogleLLMVariant.GEMINI_API) {\n if (llmRequest.config) {\n // Using API key from Google AI Studio to call model doesn't support\n // labels.\n (llmRequest.config as any).labels = undefined;\n }\n if (llmRequest.contents) {\n for (const content of llmRequest.contents) {\n if (!content.parts) continue;\n for (const part of content.parts) {\n removeDisplayNameIfPresent(part.inlineData);\n removeDisplayNameIfPresent(part.fileData);\n }\n }\n }\n }\n }\n}\n\nfunction removeDisplayNameIfPresent(\n dataObj: Blob | FileData | undefined,\n): void {\n // display_name is not supported for Gemini API (non-vertex)\n if (dataObj && (dataObj as FileData).displayName) {\n (dataObj as FileData).displayName = undefined;\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * The Google LLM variant to use.\n * see\n * https://google.github.io/adk-docs/get-started/quickstart/#set-up-the-model\n */\nexport enum GoogleLLMVariant {\n /**\n * For using credentials from Google Vertex AI\n */\n VERTEX_AI = 'VERTEX_AI',\n\n /**\n * For using API Key from Google AI Studio\n */\n GEMINI_API = 'GEMINI_API',\n}\n\n/**\n * Gets the Google LLM variant to use.\n */\nexport function getGoogleLlmVariant() {\n return getBooleanEnvVar('GOOGLE_GENAI_USE_VERTEXAI') ?\n GoogleLLMVariant.VERTEX_AI :\n GoogleLLMVariant.GEMINI_API;\n}\n\n/**\n * Gets the boolean value of the given environment variable.\n *\n * @param envVar The environment variable to get the value of.\n * @return The boolean value of the environment variable.\n */\nfunction getBooleanEnvVar(envVar: string): boolean {\n if (!process.env) {\n return false;\n }\n\n const envVarValue = (process.env[envVar] || '').toLowerCase();\n\n return ['true', '1'].includes(envVar.toLowerCase());\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Blob, Content, FunctionResponse, Session,} from '@google/genai';\n\nimport {logger} from '../utils/logger.js';\n\nimport {BaseLlmConnection} from './base_llm_connection.js';\nimport {LlmResponse} from './llm_response.js';\n\n/** The Gemini model connection. */\nexport class GeminiLlmConnection implements BaseLlmConnection {\n constructor(\n private readonly geminiSession: Session,\n ) {}\n\n /**\n * Sends the conversation history to the gemini model.\n *\n * You call this method right after setting up the model connection.\n * The model will respond if the last content is from user, otherwise it will\n * wait for new user input before responding.\n *\n * @param history The conversation history to send to the model.\n */\n async sendHistory(history: Content[]): Promise<void> {\n // We ignore any audio from user during the agent transfer phase.\n const contents = history.filter(\n (content) => content.parts && content.parts[0]?.text,\n );\n\n if (contents.length > 0) {\n this.geminiSession.sendClientContent({\n turns: contents,\n turnComplete: contents[contents.length - 1].role === 'user',\n });\n } else {\n logger.info('no content is sent');\n }\n }\n\n /**\n * Sends a user content to the gemini model.\n *\n * The model will respond immediately upon receiving the content.\n * If you send function responses, all parts in the content should be function\n * responses.\n *\n * @param content The content to send to the model.\n */\n async sendContent(content: Content): Promise<void> {\n if (!content.parts) {\n throw new Error('Content must have parts.');\n }\n if (content.parts[0].functionResponse) {\n // All parts have to be function responses.\n const functionResponses =\n content.parts.map((part) => part.functionResponse)\n .filter((fr): fr is FunctionResponse => !!fr);\n logger.debug('Sending LLM function response:', functionResponses);\n this.geminiSession.sendToolResponse({\n functionResponses,\n });\n } else {\n logger.debug('Sending LLM new content', content);\n this.geminiSession.sendClientContent({\n turns: [content],\n turnComplete: true,\n });\n }\n }\n\n /**\n * Sends a chunk of audio or a frame of video to the model in realtime.\n *\n * @param blob The blob to send to the model.\n */\n async sendRealtime(blob: Blob): Promise<void> {\n logger.debug('Sending LLM Blob:', blob);\n this.geminiSession.sendRealtimeInput({media: blob});\n }\n\n /**\n * Builds a full text response.\n *\n * The text should not be partial and the returned LlmResponse is not be\n * partial.\n *\n * @param text The text to be included in the response.\n * @returns An LlmResponse containing the full text.\n */\n private buildFullTextResponse(text: string): LlmResponse {\n return {\n content: {\n role: 'model',\n parts: [{text}],\n },\n };\n }\n\n // TODO(b/425992518): GenAI SDK inconsistent API, missing methods.\n async * receive(): AsyncGenerator<LlmResponse, void, void> {\n throw new Error('Not Implemented.');\n }\n\n /**\n * Closes the llm server connection.\n */\n async close(): Promise<void> {\n this.geminiSession.close();\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Content, FinishReason, GenerateContentResponse, GenerateContentResponseUsageMetadata, GroundingMetadata, LiveServerSessionResumptionUpdate, Transcription,} from '@google/genai';\n\n/**\n * LLM response class that provides the first candidate response from the\n * model if available. Otherwise, returns error code and message.\n */\nexport interface LlmResponse {\n /**\n * The content of the response.\n */\n content?: Content;\n\n /**\n * The grounding metadata of the response.\n */\n groundingMetadata?: GroundingMetadata;\n\n /**\n * Indicates whether the text content is part of a unfinished text stream.\n * Only used for streaming mode and when the content is plain text.\n */\n partial?: boolean;\n\n /**\n * Indicates whether the response from the model is complete.\n * Only used for streaming mode.\n */\n turnComplete?: boolean;\n\n /**\n * Error code if the response is an error. Code varies by model.\n */\n errorCode?: string;\n\n /**\n * Error message if the response is an error.\n */\n errorMessage?: string;\n\n /**\n * Flag indicating that LLM was interrupted when generating the content.\n * Usually it's due to user interruption during a bidi streaming.\n */\n interrupted?: boolean;\n\n /**\n * The custom metadata of the LlmResponse.\n * An optional key-value pair to label an LlmResponse.\n * NOTE: the entire object must be JSON serializable.\n */\n customMetadata?: {[key: string]: any};\n\n /**\n * The usage metadata of the LlmResponse.\n */\n usageMetadata?: GenerateContentResponseUsageMetadata;\n\n /**\n * The finish reason of the response.\n */\n finishReason?: FinishReason;\n\n /**\n * The session resumption update of the LlmResponse\n */\n liveSessionResumptionUpdate?: LiveServerSessionResumptionUpdate;\n\n /**\n * Audio transcription of user input.\n */\n inputTranscription?: Transcription;\n\n /**\n * Audio transcription of model output.\n */\n outputTranscription?: Transcription;\n}\n\n/**\n * Creates an LlmResponse from a GenerateContentResponse.\n *\n * @param response The GenerateContentResponse to create the\n * LlmResponse from.\n * @returns The LlmResponse.\n */\nexport function createLlmResponse(\n response: GenerateContentResponse,\n ): LlmResponse {\n const usageMetadata = response.usageMetadata;\n\n if (response.candidates && response.candidates.length > 0) {\n const candidate = response.candidates[0];\n if (candidate.content?.parts && candidate.content.parts.length > 0) {\n return {\n content: candidate.content,\n groundingMetadata: candidate.groundingMetadata,\n usageMetadata: usageMetadata,\n finishReason: candidate.finishReason,\n };\n }\n\n return {\n errorCode: candidate.finishReason,\n errorMessage: candidate.finishMessage,\n usageMetadata: usageMetadata,\n finishReason: candidate.finishReason,\n };\n }\n\n if (response.promptFeedback) {\n return {\n errorCode: response.promptFeedback.blockReason,\n errorMessage: response.promptFeedback.blockReasonMessage,\n usageMetadata: usageMetadata,\n };\n }\n\n // The ultimate fallback for an unknown error state\n return {\n errorCode: 'UNKNOWN_ERROR',\n errorMessage: 'Unknown error.',\n usageMetadata: usageMetadata,\n };\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {logger} from '../utils/logger.js';\n\nimport {BaseLlm} from './base_llm.js';\nimport {Gemini} from './google_llm.js';\n\n/**\n * type[BaseLlm] equivalent in TypeScript, represents a class that can be new-ed\n * to create a BaseLlm instance.\n */\nexport type BaseLlmType = (new (params: {model: string}) => BaseLlm)&{\n readonly supportedModels: Array<string|RegExp>;\n};\n\n/**\n * A simple LRU cache.\n */\n// TODO - b/425992518: consider remove this. model resolution is not frequent.\nclass LRUCache<K, V> {\n private readonly maxSize: number;\n private cache: Map<K, V>;\n\n constructor(maxSize: number) {\n this.maxSize = maxSize;\n this.cache = new Map<K, V>();\n }\n\n get(key: K): V|undefined {\n const item = this.cache.get(key);\n if (item) {\n // Map maintians insertion order.\n this.cache.delete(key);\n this.cache.set(key, item);\n }\n return item;\n }\n\n set(key: K, value: V): void {\n if (this.cache.size >= this.maxSize && !this.cache.has(key)) {\n const lruKey = this.cache.keys().next().value;\n if (lruKey !== undefined) {\n this.cache.delete(lruKey);\n }\n }\n this.cache.set(key, value);\n }\n}\n\n/**\n * Registry for LLMs.\n */\nexport class LLMRegistry {\n /**\n * Key is the regex that matches the model name.\n * Value is the class that implements the model.\n */\n private static llmRegistryDict: Map<string|RegExp, BaseLlmType> = new Map();\n private static resolveCache = new LRUCache<string, BaseLlmType>(32);\n\n /**\n * Creates a new LLM instance.\n * @param model The model name.\n * @returns The LLM instance.\n */\n static newLlm(model: string): BaseLlm {\n return new (LLMRegistry.resolve(model))({model});\n }\n\n private static _register(modelNameRegex: string|RegExp, llmCls: BaseLlmType) {\n if (LLMRegistry.llmRegistryDict.has(modelNameRegex)) {\n logger.info(\n `Updating LLM class for ${modelNameRegex} from ${\n LLMRegistry.llmRegistryDict.get(modelNameRegex)} to ${llmCls}`,\n );\n }\n LLMRegistry.llmRegistryDict.set(modelNameRegex, llmCls);\n }\n\n /**\n * Registers a new LLM class.\n * @param llmCls The class that implements the model.\n */\n static register<T extends BaseLlm>(\n llmCls: (new(params: {model: string}) => T)&{\n readonly supportedModels: Array<string|RegExp>;\n }) {\n for (const regex of llmCls.supportedModels) {\n LLMRegistry._register(regex, llmCls);\n }\n }\n\n /**\n * Resolves the model to a BaseLlm subclass.\n * @param model The model name.\n * @returns The BaseLlm subclass.\n * @throws If the model is not found.\n */\n static resolve(model: string): BaseLlmType {\n const cachedLlm = LLMRegistry.resolveCache.get(model);\n if (cachedLlm) {\n return cachedLlm;\n }\n\n for (const [regex, llmClass] of LLMRegistry.llmRegistryDict.entries()) {\n // Replicates Python's `re.fullmatch` by anchoring the regex\n // to the start (^) and end ($) of the string.\n // TODO - b/425992518: validate it works well.\n const pattern = new RegExp(\n `^${regex instanceof RegExp ? regex.source : regex}$`,\n regex instanceof RegExp ? regex.flags : undefined,\n );\n if (pattern.test(model)) {\n LLMRegistry.resolveCache.set(model, llmClass);\n return llmClass;\n }\n }\n\n throw new Error(`Model ${model} not found.`);\n }\n}\n\n/** Registers default LLM factories, e.g. for Gemini models. */\nLLMRegistry.register(Gemini);\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {FunctionDeclaration, Tool} from '@google/genai';\n\nimport {LlmRequest} from '../models/llm_request.js';\nimport {getGoogleLlmVariant} from '../utils/variant_utils.js';\n\nimport {ToolContext} from './tool_context.js';\n\n/**\n * The parameters for `runAsync`.\n */\nexport interface RunAsyncToolRequest {\n args: Record<string, unknown>;\n toolContext: ToolContext;\n}\n\n/**\n * The parameters for `processLlmRequest`.\n */\nexport interface ToolProcessLlmRequest {\n toolContext: ToolContext;\n llmRequest: LlmRequest;\n}\n\n/**\n * Parameters for the BaseTool constructor.\n */\nexport interface BaseToolParams {\n name: string;\n description: string;\n isLongRunning?: boolean;\n}\n\n/**\n * The base class for all tools.\n */\nexport abstract class BaseTool {\n readonly name: string;\n readonly description: string;\n readonly isLongRunning: boolean;\n\n /**\n * Base constructor for a tool.\n *\n * @param params The parameters for `BaseTool`.\n */\n constructor(params: BaseToolParams) {\n this.name = params.name;\n this.description = params.description;\n this.isLongRunning = params.isLongRunning ?? false;\n }\n\n /**\n * Gets the OpenAPI specification of this tool in the form of a\n * FunctionDeclaration.\n *\n * NOTE\n * - Required if subclass uses the default implementation of\n * `processLlmRequest` to add function declaration to LLM request.\n * - Otherwise, can be skipped, e.g. for a built-in GoogleSearch tool for\n * Gemini.\n *\n * @return The FunctionDeclaration of this tool, or undefined if it doesn't\n * need to be added to LlmRequest.config.\n */\n _getDeclaration(): FunctionDeclaration|undefined {\n return undefined;\n }\n\n /**\n * Runs the tool with the given arguments and context.\n *\n * NOTE\n * - Required if this tool needs to run at the client side.\n * - Otherwise, can be skipped, e.g. for a built-in GoogleSearch tool for\n * Gemini.\n *\n * @param request The request to run the tool.\n * @return A promise that resolves to the tool response.\n */\n abstract runAsync(request: RunAsyncToolRequest): Promise<unknown>;\n\n /**\n * Processes the outgoing LLM request for this tool.\n *\n * Use cases:\n * - Most common use case is adding this tool to the LLM request.\n * - Some tools may just preprocess the LLM request before it's sent out.\n *\n * @param request The request to process the LLM request.\n */\n async processLlmRequest({toolContext, llmRequest}: ToolProcessLlmRequest):\n Promise<void> {\n const functionDeclaration = this._getDeclaration();\n if (!functionDeclaration) {\n return;\n }\n\n llmRequest.toolsDict[this.name] = this;\n\n const tool = findToolWithFunctionDeclarations(llmRequest);\n if (tool) {\n if (!tool.functionDeclarations) {\n tool.functionDeclarations = [];\n }\n\n tool.functionDeclarations.push(functionDeclaration);\n } else {\n llmRequest.config = llmRequest.config || {};\n llmRequest.config.tools = llmRequest.config.tools || [];\n llmRequest.config.tools.push({\n functionDeclarations: [functionDeclaration],\n });\n }\n }\n\n /**\n * The Google API LLM variant to use.\n */\n get apiVariant() {\n return getGoogleLlmVariant();\n }\n}\n\nfunction findToolWithFunctionDeclarations(llmRequest: LlmRequest): Tool|\n undefined {\n return (llmRequest.config?.tools ||\n []).find(tool => 'functionDeclarations' in tool) as Tool |\n undefined;\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {FunctionDeclaration, Schema, Type} from '@google/genai';\nimport {type infer as zInfer, ZodObject} from 'zod';\n\nimport {isZodObject, zodObjectToSchema} from '../utils/simple_zod_to_json.js';\n\nimport {BaseTool, RunAsyncToolRequest} from './base_tool.js';\nimport {ToolContext} from './tool_context.js';\n\n/**\n * Input parameters of the function tool.\n */\nexport type ToolInputParameters =|undefined|ZodObject<any>|Schema;\n\n/*\n * The arguments of the function tool.\n */\nexport type ToolExecuteArgument<TParameters extends ToolInputParameters> =\n TParameters extends ZodObject<any>?\n zInfer<TParameters>:\n TParameters extends Schema ? unknown : string;\n\n/*\n * The function to execute by the tool.\n */\ntype ToolExecuteFunction<\n TParameters extends ToolInputParameters,\n> = (\n input: ToolExecuteArgument<TParameters>,\n tool_context?: ToolContext,\n) => Promise<unknown> | unknown;\n\n/**\n * The configuration options for creating a function-based tool.\n * The `name`, `description` and `parameters` fields are used to generate the\n * tool definition that is passed to the LLM prompt.\n *\n * Note: Unlike Python's ADK, JSDoc on the `execute` function is ignored\n * for tool definition generation.\n */\nexport type ToolOptions<\n TParameters extends ToolInputParameters,\n> = {\n name?: string;\n description: string;\n parameters?: TParameters;\n execute: ToolExecuteFunction<TParameters>;\n isLongRunning?: boolean;\n};\n\nfunction toSchema<TParameters extends ToolInputParameters>(\n parameters: TParameters): Schema {\n if (parameters === undefined) {\n return {type: Type.OBJECT, properties: {}};\n }\n\n if (isZodObject(parameters)) {\n return zodObjectToSchema(parameters);\n }\n\n return parameters;\n}\n\nexport class FunctionTool<\n TParameters extends ToolInputParameters = undefined,\n> extends BaseTool {\n // User defined function.\n private readonly execute: ToolExecuteFunction<TParameters>;\n // Typed input parameters.\n private readonly parameters?: TParameters;\n\n /**\n * The constructor acts as the user-friendly factory.\n * @param options The configuration for the tool.\n */\n constructor(options: ToolOptions<TParameters>) {\n const name = options.name ?? (options.execute as any).name;\n if (!name) {\n throw new Error(\n 'Tool name cannot be empty. Either name the `execute` function or provide a `name`.',\n );\n }\n super({\n name,\n description: options.description,\n isLongRunning: options.isLongRunning\n });\n this.execute = options.execute;\n this.parameters = options.parameters;\n }\n\n /**\n * Provide a schema for the function.\n */\n override _getDeclaration(): FunctionDeclaration {\n return {\n name: this.name,\n description: this.description,\n parameters: toSchema(this.parameters),\n };\n }\n\n /**\n * Logic for running the tool.\n */\n override async runAsync(req: RunAsyncToolRequest): Promise<unknown> {\n try {\n let validatedArgs: unknown = req.args;\n if (this.parameters instanceof ZodObject) {\n validatedArgs = this.parameters.parse(req.args);\n }\n return await this.execute(\n validatedArgs as ToolExecuteArgument<TParameters>, req.toolContext);\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n throw new Error(`Error in tool '${this.name}': ${errorMessage}`);\n }\n }\n}", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Schema, Type} from '@google/genai';\nimport {z, ZodObject, ZodTypeAny} from 'zod';\n\n/**\n * Returns true if the given object is a V3 ZodObject.\n */\nexport function isZodObject(obj: unknown): obj is ZodObject<any> {\n return (\n obj !== null && typeof obj === 'object' &&\n (obj as any)._def?.typeName === 'ZodObject');\n}\n\n// TODO(b/425992518): consider conversion to FunctionDeclaration directly.\n\nfunction parseZodType(zodType: ZodTypeAny): Schema|undefined {\n const def = zodType._def;\n if (!def) {\n return {};\n }\n const description = def.description;\n const result: Schema = {};\n if (description) result.description = description;\n\n const returnResult = (result: Schema) => {\n if (result.description === undefined) {\n delete result.description;\n }\n return result;\n };\n\n switch (def.typeName) {\n case z.ZodFirstPartyTypeKind.ZodString:\n result.type = Type.STRING;\n for (const check of def.checks || []) {\n if (check.kind === 'min')\n result.minLength = check.value.toString();\n else if (check.kind === 'max')\n result.maxLength = check.value.toString();\n else if (check.kind === 'email')\n result.format = 'email';\n else if (check.kind === 'uuid')\n result.format = 'uuid';\n else if (check.kind === 'url')\n result.format = 'uri';\n else if (check.kind === 'regex')\n result.pattern = check.regex.source;\n }\n return returnResult(result);\n\n case z.ZodFirstPartyTypeKind.ZodNumber:\n result.type = Type.NUMBER;\n for (const check of def.checks || []) {\n if (check.kind === 'min')\n result.minimum = check.value;\n else if (check.kind === 'max')\n result.maximum = check.value;\n else if (check.kind === 'int')\n result.type = Type.INTEGER;\n }\n return returnResult(result);\n\n case z.ZodFirstPartyTypeKind.ZodBoolean:\n result.type = Type.BOOLEAN;\n return returnResult(result);\n\n case z.ZodFirstPartyTypeKind.ZodArray:\n result.type = Type.ARRAY;\n result.items = parseZodType(def.type);\n if (def.minLength) result.minItems = def.minLength.value.toString();\n if (def.maxLength) result.maxItems = def.maxLength.value.toString();\n return returnResult(result);\n\n case z.ZodFirstPartyTypeKind.ZodObject: {\n const nestedSchema = zodObjectToSchema(zodType as ZodObject<any>);\n return nestedSchema as Schema;\n }\n\n case z.ZodFirstPartyTypeKind.ZodLiteral:\n const literalType = typeof def.value;\n result.enum = [def.value.toString()];\n\n if (literalType === 'string') {\n result.type = Type.STRING;\n } else if (literalType === 'number') {\n result.type = Type.NUMBER;\n } else if (literalType === 'boolean') {\n result.type = Type.BOOLEAN;\n } else if (def.value === null) {\n result.type = Type.NULL;\n } else {\n throw new Error(`Unsupported ZodLiteral value type: ${literalType}`);\n }\n\n return returnResult(result);\n\n case z.ZodFirstPartyTypeKind.ZodEnum:\n result.type = Type.STRING;\n result.enum = def.values;\n return returnResult(result);\n\n case z.ZodFirstPartyTypeKind.ZodNativeEnum:\n result.type = Type.STRING;\n result.enum = Object.values(def.values);\n return returnResult(result);\n\n case z.ZodFirstPartyTypeKind.ZodUnion:\n result.anyOf = def.options.map(parseZodType);\n return returnResult(result);\n\n case z.ZodFirstPartyTypeKind.ZodOptional:\n return parseZodType(def.innerType);\n case z.ZodFirstPartyTypeKind.ZodNullable:\n const nullableInner = parseZodType(def.innerType);\n return nullableInner ?\n returnResult({\n anyOf: [nullableInner, {type: Type.NULL}],\n ...(description && {description})\n }) :\n returnResult({type: Type.NULL, ...(description && {description})});\n case z.ZodFirstPartyTypeKind.ZodDefault:\n const defaultInner = parseZodType(def.innerType);\n if (defaultInner) defaultInner.default = def.defaultValue();\n return defaultInner;\n case z.ZodFirstPartyTypeKind.ZodBranded:\n return parseZodType(def.type);\n case z.ZodFirstPartyTypeKind.ZodReadonly:\n return parseZodType(def.innerType);\n case z.ZodFirstPartyTypeKind.ZodNull:\n result.type = Type.NULL;\n return returnResult(result);\n case z.ZodFirstPartyTypeKind.ZodAny:\n case z.ZodFirstPartyTypeKind.ZodUnknown:\n return returnResult({...(description && {description})});\n default:\n throw new Error(`Unsupported Zod type: ${def.typeName}`);\n }\n}\n\nexport function zodObjectToSchema(schema: ZodObject<any>): Schema {\n if (schema._def.typeName !== z.ZodFirstPartyTypeKind.ZodObject) {\n throw new Error('Expected a ZodObject');\n }\n\n const shape = schema.shape;\n const properties: Record<string, Schema> = {};\n const required: string[] = [];\n\n for (const key in shape) {\n const fieldSchema = shape[key];\n const parsedField = parseZodType(fieldSchema);\n if (parsedField) {\n properties[key] = parsedField;\n }\n\n let currentSchema = fieldSchema;\n let isOptional = false;\n while (currentSchema._def.typeName ===\n z.ZodFirstPartyTypeKind.ZodOptional ||\n currentSchema._def.typeName === z.ZodFirstPartyTypeKind.ZodDefault) {\n isOptional = true;\n currentSchema = currentSchema._def.innerType;\n }\n if (!isOptional) {\n required.push(key);\n }\n }\n\n const catchall = schema._def.catchall;\n let additionalProperties: boolean|Schema = false;\n if (catchall && catchall._def.typeName !== z.ZodFirstPartyTypeKind.ZodNever) {\n additionalProperties = parseZodType(catchall) || true;\n } else {\n additionalProperties = schema._def.unknownKeys === 'passthrough';\n }\n return {\n type: Type.OBJECT,\n properties,\n required: required.length > 0 ? required : [],\n ...(schema._def.description ? {description: schema._def.description} : {}),\n };\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {InvocationContext} from '../agents/invocation_context.js';\nimport {Event} from '../events/event.js';\nimport {LlmRequest} from '../models/llm_request.js';\nimport {LlmResponse} from '../models/llm_response.js';\n\n/**\n * Base class for LLM request processor.\n */\nexport abstract class BaseLlmRequestProcessor {\n /**\n * Runs the processor.\n */\n abstract runAsync(\n invocationContext: InvocationContext,\n llmRequest: LlmRequest): AsyncGenerator<Event, void, void>;\n}\n\n/**\n * Base class for LLM response processor.\n */\nexport abstract class BaseLlmResponseProcessor {\n /**\n * Processes the LLM response.\n */\n abstract runAsync(\n invocationContext: InvocationContext,\n llmResponse: LlmResponse): AsyncGenerator<Event, void, void>;\n}", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {Content} from '@google/genai';\n\nimport {createEvent, Event, getFunctionCalls, getFunctionResponses} from '../events/event.js';\nimport {deepClone} from '../utils/deep_clone.js';\n\nimport {removeClientFunctionCallId, REQUEST_CONFIRMATION_FUNCTION_CALL_NAME, REQUEST_EUC_FUNCTION_CALL_NAME} from './functions.js';\n\n/**\n * Get the contents for the LLM request.\n *\n * @param events: A list of all session events.\n * @param agentName: The name of the agent.\n * @param currentBranch: The current branch of the agent.\n *\n * @returns A list of processed contents.\n */\nexport function getContents(\n events: Event[], agentName: string, currentBranch?: string): Content[] {\n const filteredEvents: Event[] = [];\n\n for (const event of events) {\n // Skip events without content, or generated neither by user nor by model.\n // E.g. events purely for mutating session states.\n // Also skip events with empty parts array (can happen during streaming with parallel tool calls)\n if (!event.content?.role || !event.content.parts?.length) {\n continue;\n }\n\n // Skip events not in the current branch.\n // TODO - b/425992518: inefficient, a tire search is better.\n if (currentBranch && event.branch &&\n !currentBranch.startsWith(event.branch)) {\n continue;\n }\n\n if (isAuthEvent(event)) {\n continue;\n }\n\n if (isToolConfirmationEvent(event)) {\n continue;\n }\n\n filteredEvents.push(\n isEventFromAnotherAgent(agentName, event) ? convertForeignEvent(event) :\n event);\n }\n\n let resultEvents = rearrangeEventsForLatestFunctionResponse(filteredEvents);\n resultEvents =\n rearrangeEventsForAsyncFunctionResponsesInHistory(resultEvents);\n const contents = [];\n for (const event of resultEvents) {\n const content = deepClone(event.content) as Content;\n removeClientFunctionCallId(content);\n contents.push(content);\n }\n return contents;\n}\n\n/**\n * Get contents for the current turn only (no conversation history).\n *\n * When include_contents='none', we want to include:\n * - The current user input\n * - Tool calls and responses from the current turn\n * But exclude conversation history from previous turns.\n *\n * In multi-agent scenarios, the \"current turn\" for an agent starts from an\n * actual user or from another agent.\n *\n * @param events: A list of all session events.\n * @param agentName: The name of the agent.\n * @param currentBranch: The current branch of the agent.\n *\n * @returns A list of contents for the current turn only, preserving context\n * needed for proper tool execution while excluding conversation history.\n */\nexport function getCurrentTurnContents(\n events: Event[],\n agentName: string,\n currentBranch?: string,\n ): Content[] {\n // Find the latest event that starts the current turn and process from there.\n for (let i = events.length - 1; i >= 0; i--) {\n const event = events[i];\n if (event.author === 'user' || isEventFromAnotherAgent(agentName, event)) {\n return getContents(events.slice(i), agentName, currentBranch);\n }\n }\n\n return [];\n}\n\n/**\n * Whether the event is an auth event.\n *\n * An auth event is an event that contains a function call or response\n * related to requesting end-user credentials (EUC). These events are\n * skipped when constructing the content for the LLM request.\n */\nfunction isAuthEvent(event: Event): boolean {\n if (!event.content?.parts) {\n return false;\n }\n for (const part of event.content.parts) {\n if (part.functionCall?.name === REQUEST_EUC_FUNCTION_CALL_NAME ||\n part.functionResponse?.name === REQUEST_EUC_FUNCTION_CALL_NAME) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Whether the event is a tool confirmation event.\n *\n * A tool confirmation event is an event that contains a function call or\n * response related to requesting confirmation for a tool call. These events\n * are skipped when constructing the content for the LLM request.\n */\nfunction isToolConfirmationEvent(event: Event): boolean {\n if (!event.content?.parts) {\n return false;\n }\n for (const part of event.content.parts) {\n if (part.functionCall?.name === REQUEST_CONFIRMATION_FUNCTION_CALL_NAME ||\n part.functionResponse?.name ===\n REQUEST_CONFIRMATION_FUNCTION_CALL_NAME) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Whether the event is from another agent.\n */\nfunction isEventFromAnotherAgent(agentName: string, event: Event): boolean {\n return !!agentName && event.author !== agentName && event.author !== 'user';\n}\n\n/**\n * Formats an event authored by another agent to a user-content event.\n *\n * This is to provide another agent's output as context to the current agent,\n * so that current agent can continue to respond, such as summarizing previous\n * agent's reply, etc.\n *\n * @param event The event to convert.\n *\n * @returns The converted event.\n */\nfunction convertForeignEvent(event: Event): Event {\n if (!event.content?.parts?.length) {\n return event;\n }\n\n const content: Content = {\n role: 'user',\n parts: [{\n text: 'For context:',\n }],\n };\n\n for (const part of event.content.parts) {\n // Exclude thoughts from the context.\n // TODO - b/425992518: filtring should be configurable.\n if (part.text && !part.thought) {\n content.parts?.push({\n text: `[${event.author}] said: ${part.text}`,\n });\n } else if (part.functionCall) {\n const argsText = safeStringify(part.functionCall.args);\n content.parts?.push({\n text: `[${event.author}] called tool \\`${\n part.functionCall.name}\\` with parameters: ${argsText}`,\n });\n } else if (part.functionResponse) {\n const responseText = safeStringify(part.functionResponse.response);\n content.parts?.push({\n text: `[${event.author}] tool \\`${\n part.functionResponse.name}\\` returned result: ${responseText}`,\n });\n } else {\n content.parts?.push(part);\n }\n }\n\n return createEvent({\n invocationId: event.invocationId,\n author: 'user',\n content,\n branch: event.branch,\n timestamp: event.timestamp,\n });\n}\n\n/**\n * Merges a list of function_response events into one event.\n *\n * The key goal is to ensure:\n * 1. function_call and function_response are always of the same number.\n * 2. The function_call and function_response are consecutively in the content.\n *\n * @param events: A list of function_response events.\n *\n * NOTE:\n * function_response_events must fulfill these requirements:\n * 1. The list is in increasing order of timestamp;\n * 2. the first event is the initial function_response event;\n * 3. all later events should contain at least one function_response part that\n * related to the function_call event. Caveat: This implementation doesn't\n * support when a parallel function_call event contains async function_call of\n * the same name.\n *\n * @returns\n * A merged event, that is\n * 1. All later function_response will replace function_response part in\n * the initial function_response event.\n * 2. All non-function_response parts will be appended to the part list of\n * the initial function_response event.\n */\nfunction mergeFunctionResponseEvents(events: Event[]): Event {\n if (events.length === 0) {\n throw new Error('Cannot merge an empty list of events.');\n }\n\n const mergedEvent = createEvent(events[0]);\n const partsInMergedEvent = mergedEvent.content?.parts || [];\n\n if (partsInMergedEvent.length === 0) {\n throw new Error('There should be at least one function_response part.');\n }\n\n const partIndicesInMergedEvent: Record<string, number> = {};\n for (let i = 0; i < partsInMergedEvent.length; i++) {\n const part = partsInMergedEvent[i];\n if (part.functionResponse && part.functionResponse.id) {\n partIndicesInMergedEvent[part.functionResponse.id] = i;\n }\n }\n\n for (const event of events.slice(1)) {\n if (!event.content || !event.content.parts) {\n throw new Error('There should be at least one function_response part.');\n }\n for (const part of event.content.parts) {\n if (part.functionResponse && part.functionResponse.id) {\n const functionCallId = part.functionResponse.id;\n if (functionCallId in partIndicesInMergedEvent) {\n partsInMergedEvent[partIndicesInMergedEvent[functionCallId]] = part;\n } else {\n partsInMergedEvent.push(part);\n partIndicesInMergedEvent[functionCallId] =\n partsInMergedEvent.length - 1;\n }\n } else {\n partsInMergedEvent.push(part);\n }\n }\n }\n\n return mergedEvent;\n}\n\n/**\n * Rearrange the async functionResponse events in the history.\n */\nfunction rearrangeEventsForLatestFunctionResponse(\n events: Event[],\n ): Event[] {\n if (events.length === 0) {\n return events;\n }\n\n const latestEvent = events[events.length - 1];\n const functionResponses = getFunctionResponses(latestEvent);\n\n // No need to process, since the latest event is not functionResponse.\n if (!functionResponses?.length) {\n return events;\n }\n\n let functionResponsesIds = new Set<string>(\n functionResponses\n .filter((response): response is {id: string} => !!response.id)\n .map((response) => response.id),\n );\n\n // No need to rearrange if the second latest event already contains the\n // corresponding function calls for the latest function responses.\n const secondLatestEvent = events.at(-2);\n if (secondLatestEvent) {\n const functionCallsFromSecondLatest = getFunctionCalls(secondLatestEvent);\n if (functionCallsFromSecondLatest) {\n for (const functionCall of functionCallsFromSecondLatest) {\n if (functionCall.id && functionResponsesIds.has(functionCall.id)) {\n return events;\n }\n }\n }\n }\n\n // Look for corresponding function call event reversely.\n let functionCallEventIdx = -1;\n for (let idx = events.length - 2; idx >= 0; idx--) {\n const event = events[idx];\n const functionCalls = getFunctionCalls(event);\n if (!functionCalls?.length) {\n continue;\n }\n\n for (const functionCall of functionCalls) {\n if (functionCall.id && functionResponsesIds.has(functionCall.id)) {\n functionCallEventIdx = idx;\n const functionCallIds = new Set<string>(\n functionCalls.map(fc => fc.id).filter((id): id is string => !!id),\n );\n\n // Check if functionResponsesIds is a subset of functionCallIds\n const isSubset = Array.from(functionResponsesIds)\n .every(id => functionCallIds.has(id));\n\n if (!isSubset) {\n throw new Error(\n 'Last response event should only contain the responses for the' +\n ' function calls in the same function call event. Function' +\n ` call ids found : ${\n Array.from(functionCallIds)\n .join(', ')}, function response` +\n ` ids provided: ${\n Array.from(functionResponsesIds).join(', ')}`,\n );\n }\n // Expand the function call events to collect all function responses\n // from the function call event to the last response event.\n // TODO - b/425992518: bad practice, state can mutated multiple times.\n functionResponsesIds = functionCallIds;\n break;\n }\n }\n }\n\n if (functionCallEventIdx === -1) {\n throw new Error(\n `No function call event found for function responses ids: ${\n Array\n .from(\n functionResponsesIds,\n )\n .join(', ')}`,\n );\n }\n\n // Collect all function response events between the function call event\n // and the last function response event\n const functionResponseEvents: Event[] = [];\n for (let idx = functionCallEventIdx + 1; idx < events.length - 1; idx++) {\n const event = events[idx];\n const responses = getFunctionResponses(event);\n if (responses &&\n responses.some(\n (response) =>\n response.id && functionResponsesIds.has(response.id))) {\n functionResponseEvents.push(event);\n }\n }\n functionResponseEvents.push(events[events.length - 1]);\n\n const resultEvents = events.slice(0, functionCallEventIdx + 1);\n resultEvents.push(mergeFunctionResponseEvents(functionResponseEvents));\n\n return resultEvents;\n}\n\n/**\n * Rearrange the events for the latest function_response.\n *\n * If the latest function_response is for an async function_call, all events\n * between the initial function_call and the latest function_response will be\n * removed.\n *\n * @param event: A list of events.\n *\n * @returns A list of events with the latest function_response rearranged.\n */\nfunction rearrangeEventsForAsyncFunctionResponsesInHistory(\n events: Event[],\n ): Event[] {\n const functionCallIdToResponseEventIndex: Map<string, number> = new Map();\n\n // First pass: Map function_call_id to the index of their\n // corresponding response events.\n for (let i = 0; i < events.length; i++) {\n const event = events[i];\n const functionResponses = getFunctionResponses(event);\n if (functionResponses?.length) {\n for (const functionResponse of functionResponses) {\n if (!functionResponse.id) {\n continue;\n }\n\n functionCallIdToResponseEventIndex.set(functionResponse.id, i);\n }\n }\n }\n\n const resultEvents: Event[] = [];\n\n // Second pass: Build the new ordered list of events.\n for (const event of events) {\n // If the event contains function responses, it will be handled when\n // its corresponding function_call is encountered, so skip it for now.\n if (getFunctionResponses(event).length > 0) {\n continue;\n }\n\n const functionCalls = getFunctionCalls(event);\n if (functionCalls?.length) {\n const functionResponseEventsIndices: Set<number> = new Set();\n for (const functionCall of functionCalls) {\n const functionCallId = functionCall.id;\n if (functionCallId &&\n functionCallIdToResponseEventIndex.has(functionCallId)) {\n functionResponseEventsIndices.add(\n functionCallIdToResponseEventIndex.get(functionCallId)!,\n );\n }\n }\n\n resultEvents.push(event);\n\n if (functionResponseEventsIndices.size === 0) {\n continue;\n }\n\n if (functionResponseEventsIndices.size === 1) {\n const [responseIndex] = [...functionResponseEventsIndices];\n resultEvents.push(events[responseIndex]);\n } else {\n const indicesArray =\n Array.from(functionResponseEventsIndices).sort((a, b) => a - b);\n const eventsToMerge = indicesArray.map((index) => events[index]);\n resultEvents.push(mergeFunctionResponseEvents(eventsToMerge));\n }\n } else {\n resultEvents.push(event);\n }\n }\n\n return resultEvents;\n}\n\n/**\n * Safely stringifies an object, handling circular references.\n */\nfunction safeStringify(obj: unknown): string {\n if (typeof obj === 'string') {\n return obj;\n }\n try {\n return JSON.stringify(obj);\n } catch (e) {\n return String(obj);\n }\n}\n\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {State} from '../sessions/state.js';\nimport {ReadonlyContext} from './readonly_context.js';\n\n/**\n * Populates values in the instruction template, e.g. state, artifact, etc.\n *\n * ```\n * async function buildInstruction(\n * readonlyContext: ReadonlyContext,\n * ): Promise<string> {\n * return await injectSessionState(\n * 'You can inject a state variable like {var_name} or an artifact ' +\n * '{artifact.file_name} into the instruction template.',\n * readonlyContext,\n * );\n * }\n *\n * const agent = new LlmAgent({\n * model: 'gemini-1.5-flash',\n * name: 'agent',\n * instruction: buildInstruction,\n * });\n * ```\n *\n * @param template The instruction template.\n * @param readonlyContext The read-only context\n * @returns The instruction template with values populated.\n */\nexport async function injectSessionState(\n template: string,\n readonlyContext: ReadonlyContext,\n ): Promise<string> {\n const invocationContext = readonlyContext.invocationContext;\n\n /**\n * Replaces a matched string in the template with the corresponding value from\n * the context.\n *\n * @param match The matched string in the template.\n * @returns The replaced string.\n */\n async function replaceMatchedKeyWithItsValue(match: RegExpMatchArray):\n Promise<string> {\n // Step 1: extract the key from the match\n let key = match[0].replace(/^\\{+/, '').replace(/\\}+$/, '').trim();\n const isOptional = key.endsWith('?');\n if (isOptional) {\n key = key.slice(0, -1);\n }\n\n // Step 2: handle artifact injection\n if (key.startsWith('artifact.')) {\n const fileName = key.substring('artifact.'.length);\n if (invocationContext.artifactService === undefined) {\n throw new Error('Artifact service is not initialized.');\n }\n const artifact = await invocationContext.artifactService.loadArtifact({\n appName: invocationContext.session.appName,\n userId: invocationContext.session.userId,\n sessionId: invocationContext.session.id,\n filename: fileName,\n });\n if (!artifact) {\n throw new Error(`Artifact ${fileName} not found.`);\n }\n return String(artifact);\n }\n\n // Step 3: Handle state variable injection.\n if (!isValidStateName(key)) {\n return match[0];\n }\n\n if (key in invocationContext.session.state) {\n return String(invocationContext.session.state[key]);\n }\n\n if (isOptional) {\n return '';\n }\n\n throw new Error(`Context variable not found: \\`${key}\\`.`);\n }\n // TODO - b/425992518: enable concurrent repalcement with key deduplication.\n const pattern = /\\{+[^{}]*}+/g;\n const result: string[] = [];\n let lastEnd = 0;\n const matches = template.matchAll(pattern);\n\n for (const match of matches) {\n result.push(template.slice(lastEnd, match.index));\n const replacement = await replaceMatchedKeyWithItsValue(match);\n result.push(replacement);\n lastEnd = match.index! + match[0].length;\n }\n result.push(template.slice(lastEnd));\n return result.join('');\n}\n\n\n/**\n * An IIFE that checks if the JavaScript runtime supports Unicode property\n * escapes (`\\p{...}`) in regular expressions and returns a RegExp object that\n * is used for all subsequent calls to isIdentifier().\n */\nconst isIdentifierPattern = (() => {\n return /^[a-zA-Z_][a-zA-Z0-9_]*$/;\n})();\n\n/**\n * Checks if a string is a valid identifier.\n */\nfunction isIdentifier(s: string): boolean {\n if (s === '' || s === undefined) {\n return false;\n }\n\n return isIdentifierPattern.test(s);\n}\n\nconst VALID_PREFIXES = [State.APP_PREFIX, State.USER_PREFIX, State.TEMP_PREFIX];\n/**\n * Checks if a variable name is a valid state name.\n * A valid state name is either:\n * - <identifier>\n * - <prefix>:<identifier>\n *\n * @param variableName The variable name to check.\n * @returns True if the variable name is valid, False otherwise.\n */\nfunction isValidStateName(variableName: string): boolean {\n const parts = variableName.split(':');\n if (parts.length === 0 || parts.length > 2) {\n return false;\n }\n if (parts.length === 1) {\n return isIdentifier(variableName);\n }\n if (VALID_PREFIXES.includes(parts[0] + ':')) {\n return isIdentifier(parts[1]);\n }\n return false;\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {AudioTranscriptionConfig, Modality, ProactivityConfig, RealtimeInputConfig, SpeechConfig} from '@google/genai';\n\nimport {logger} from '../utils/logger.js';\n\n/**\n * The streaming mode for the run config.\n */\nexport enum StreamingMode {\n NONE = 'none',\n SSE = 'sse',\n BIDI = 'bidi',\n}\n\n/**\n * Configs for runtime behavior of agents.\n */\nexport interface RunConfig {\n /**\n * Speech configuration for the live agent.\n */\n speechConfig?: SpeechConfig;\n\n /**\n * The output modalities. If not set, it's default to AUDIO.\n */\n responseModalities?: Modality[];\n\n /**\n * Whether or not to save the input blobs as artifacts.\n */\n saveInputBlobsAsArtifacts?: boolean;\n\n /**\n * Whether to support CFC (Compositional Function Calling). Only applicable\n * for StreamingMode.SSE. If it's true. the LIVE API will be invoked. Since\n * only LIVE API supports CFC\n *\n * WARNING: This feature is **experimental** and its API or behavior may\n * change in future releases.\n */\n supportCfc?: boolean;\n\n /**\n * Streaming mode, None or StreamingMode.SSE or StreamingMode.BIDI.\n */\n streamingMode?: StreamingMode;\n\n /**\n * Output audio transcription config.\n */\n outputAudioTranscription?: AudioTranscriptionConfig;\n\n /**\n * Input transcription for live agents with audio input from user.\n */\n inputAudioTranscription?: AudioTranscriptionConfig;\n\n /**\n * If enabled, the model will detect emotions and adapt its responses\n * accordingly.\n */\n enableAffectiveDialog?: boolean;\n\n /**\n * Configures the proactivity of the model. This allows the model to respond\n * proactively to the input and to ignore irrelevant input.\n */\n proactivity?: ProactivityConfig;\n\n /**\n * Realtime input config for live agents with audio input from user.\n */\n realtimeInputConfig?: RealtimeInputConfig;\n\n /**\n * A limit on the total number of llm calls for a given run.\n *\n * Valid Values:\n * - More than 0 and less than sys.maxsize: The bound on the number of llm\n * calls is enforced, if the value is set in this range.\n * - Less than or equal to 0: This allows for unbounded number of llm calls.\n */\n maxLlmCalls?: number;\n}\n\nexport function createRunConfig(params: Partial<RunConfig> = {}) {\n return {\n saveInputBlobsAsArtifacts: false,\n supportCfc: false,\n enableAffectiveDialog: false,\n streamingMode: StreamingMode.NONE,\n maxLlmCalls: validateMaxLlmCalls(params.maxLlmCalls || 500),\n ...params,\n };\n}\n\nfunction validateMaxLlmCalls(value: number): number {\n if (value > Number.MAX_SAFE_INTEGER) {\n throw new Error(\n `maxLlmCalls should be less than ${Number.MAX_SAFE_INTEGER}.`,\n );\n }\n\n if (value <= 0) {\n logger.warn(\n 'maxLlmCalls is less than or equal to 0. This will result in no enforcement on total number of llm calls that will be made for a run. This may not be ideal, as this could result in a never ending communication between the model and the agent in certain cases.');\n }\n return value;\n}", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Event} from '../events/event.js';\n\nimport {BaseAgent, BaseAgentConfig} from './base_agent.js';\nimport {InvocationContext} from './invocation_context.js';\n\n/**\n * The configuration options for creating a loop agent.\n */\nexport interface LoopAgentConfig extends BaseAgentConfig {\n /**\n * The maximum number of iterations the loop agent will run.\n *\n * If not provided, the loop agent will run indefinitely.\n */\n maxIterations?: number;\n}\n\n/**\n * A shell agent that run its sub-agents in a loop.\n *\n * When sub-agent generates an event with escalate or max_iterations are\n * reached, the loop agent will stop.\n */\nexport class LoopAgent extends BaseAgent {\n private readonly maxIterations: number;\n\n constructor(config: LoopAgentConfig) {\n super(config);\n this.maxIterations = config.maxIterations ?? Number.MAX_SAFE_INTEGER;\n }\n\n protected async *\n runAsyncImpl(\n context: InvocationContext,\n ): AsyncGenerator<Event, void, void> {\n let iteration = 0;\n\n while (iteration < this.maxIterations) {\n for (const subAgent of this.subAgents) {\n let shouldExit = false;\n for await (const event of subAgent.runAsync(context)) {\n yield event;\n\n if (event.actions.escalate) {\n shouldExit = true;\n }\n }\n\n if (shouldExit) {\n return;\n }\n }\n\n iteration++;\n }\n\n return;\n }\n\n protected async *\n runLiveImpl(\n context: InvocationContext,\n ): AsyncGenerator<Event, void, void> {\n throw new Error('This is not supported yet for LoopAgent.');\n }\n}", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Event} from '../events/event.js';\n\nimport {BaseAgent} from './base_agent.js';\nimport {InvocationContext} from './invocation_context.js';\n\n/**\n * A shell agent that run its sub-agents in parallel in isolated manner.\n *\n * This approach is beneficial for scenarios requiring multiple perspectives or\n * attempts on a single task, such as:\n *\n * - Running different algorithms simultaneously.\n * - Generating multiple responses for review by a subsequent evaluation agent.\n */\nexport class ParallelAgent extends BaseAgent {\n protected async *\n runAsyncImpl(\n context: InvocationContext,\n ): AsyncGenerator<Event, void, void> {\n const agentRuns = this.subAgents.map(\n subAgent => subAgent.runAsync(\n createBranchCtxForSubAgent(this, subAgent, context)));\n\n for await (const event of mergeAgentRuns(agentRuns)) {\n yield event;\n }\n }\n\n protected async *\n runLiveImpl(\n context: InvocationContext,\n ): AsyncGenerator<Event, void, void> {\n throw new Error('This is not supported yet for ParallelAgent.');\n }\n}\n\n/**\n * Create isolated branch for every sub-agent.\n */\nfunction createBranchCtxForSubAgent(\n agent: BaseAgent,\n subAgent: BaseAgent,\n originalContext: InvocationContext,\n ): InvocationContext {\n const invocationContext = new InvocationContext(originalContext);\n const branchSuffix = `${agent.name}.${subAgent.name}`;\n invocationContext.branch = invocationContext.branch ?\n `${invocationContext.branch}.${branchSuffix}` :\n branchSuffix;\n\n return invocationContext;\n}\n\n/**\n * Merges the agent run event generator.\n *\n * This implementation guarantees for each agent, it won't move on until the\n * generated event is processed by upstream runner.\n *\n * @param agentRuns A list of async generators that yield events from each\n * agent.\n *\n * @returns A list of async generators that yield events from each agent.\n *\n * @yield The next event from the merged generator.\n */\nasync function*\n mergeAgentRuns(agentRuns: AsyncGenerator<Event, void, void>[]):\n AsyncGenerator<Event, void, void> {\n const pendingPromises = new Map<\n number, Promise<{result: IteratorResult<Event>; index: number}>>();\n\n for (const [index, generator] of agentRuns.entries()) {\n const promise = generator.next().then(result => ({result, index}));\n pendingPromises.set(index, promise);\n }\n\n while (pendingPromises.size > 0) {\n const {result, index} = await Promise.race(pendingPromises.values());\n\n if (result.done) {\n pendingPromises.delete(index);\n continue;\n }\n\n yield result.value;\n\n const nextPromise =\n agentRuns[index].next().then(result => ({result, index}));\n pendingPromises.set(index, nextPromise);\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {Event} from '../events/event.js';\nimport {FunctionTool} from '../tools/function_tool.js';\n\nimport {BaseAgent} from './base_agent.js';\nimport {InvocationContext} from './invocation_context.js';\nimport {LlmAgent} from './llm_agent.js';\nimport {ReadonlyContext} from './readonly_context.js';\n\nconst TASK_COMPLETED_TOOL_NAME = 'task_completed';\n\n/**\n * A shell agent that runs its sub-agents in a sequential order.\n */\nexport class SequentialAgent extends BaseAgent {\n protected async *\n runAsyncImpl(\n context: InvocationContext,\n ): AsyncGenerator<Event, void, void> {\n for (const subAgent of this.subAgents) {\n for await (const event of subAgent.runAsync(context)) {\n yield event;\n }\n }\n }\n\n /**\n * Implementation for live SequentialAgent.\n *\n * Compared to the non-live case, live agents process a continuous stream of\n * audio or video, so there is no way to tell if it's finished and should pass\n * to the next agent or not. So we introduce a task_completed() function so\n * the model can call this function to signal that it's finished the task and\n * we can move on to the next agent.\n *\n * @param context: The invocation context of the agent.\n */\n protected async *\n runLiveImpl(\n context: InvocationContext,\n ): AsyncGenerator<Event, void, void> {\n for (const subAgent of this.subAgents) {\n if (subAgent instanceof LlmAgent) {\n const agentTools =\n await subAgent.canonicalTools(new ReadonlyContext(context));\n const taskCompletedToolAlreadyAdded =\n agentTools.some(tool => tool.name === TASK_COMPLETED_TOOL_NAME);\n\n if (!taskCompletedToolAlreadyAdded) {\n subAgent.tools.push(new FunctionTool({\n name: TASK_COMPLETED_TOOL_NAME,\n description: `Signals that the model has successfully completed the user's question or task.`,\n execute: () => 'Task completion signaled.'\n }));\n subAgent.instruction +=\n `If you finished the user's request according to its description, call the ${\n TASK_COMPLETED_TOOL_NAME} function to exit so the next agents can take over. When calling this function, do not generate any text other than the function call.`;\n }\n }\n }\n\n for (const subAgent of this.subAgents) {\n for await (const event of subAgent.runLive(context)) {\n yield event;\n }\n }\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Part} from '@google/genai';\n\nimport {BaseArtifactService, DeleteArtifactRequest, ListArtifactKeysRequest, ListVersionsRequest, LoadArtifactRequest, SaveArtifactRequest,} from './base_artifact_service.js';\n\n/**\n * An in-memory implementation of the ArtifactService.\n */\nexport class InMemoryArtifactService implements BaseArtifactService {\n private readonly artifacts: Record<string, Part[]> = {};\n\n saveArtifact({\n appName,\n userId,\n sessionId,\n filename,\n artifact,\n }: SaveArtifactRequest): Promise<number> {\n const path = artifactPath(appName, userId, sessionId, filename);\n\n if (!this.artifacts[path]) {\n this.artifacts[path] = [];\n }\n\n const version = this.artifacts[path].length;\n this.artifacts[path].push(artifact);\n\n return Promise.resolve(version);\n }\n\n loadArtifact({\n appName,\n userId,\n sessionId,\n filename,\n version,\n }: LoadArtifactRequest): Promise<Part|undefined> {\n const path = artifactPath(appName, userId, sessionId, filename);\n const versions = this.artifacts[path];\n\n if (!versions) {\n return Promise.resolve(undefined);\n }\n\n if (version === undefined) {\n version = versions.length - 1;\n }\n\n return Promise.resolve(versions[version]);\n }\n\n listArtifactKeys({appName, userId, sessionId}: ListArtifactKeysRequest):\n Promise<string[]> {\n const sessionPrefix = `${appName}/${userId}/${sessionId}/`;\n const usernamespacePrefix = `${appName}/${userId}/user/`;\n const filenames: string[] = [];\n\n for (const path in this.artifacts) {\n if (path.startsWith(sessionPrefix)) {\n const filename = path.replace(sessionPrefix, '');\n filenames.push(filename);\n } else if (path.startsWith(usernamespacePrefix)) {\n const filename = path.replace(usernamespacePrefix, '');\n filenames.push(filename);\n }\n }\n\n return Promise.resolve(filenames.sort());\n }\n\n deleteArtifact({appName, userId, sessionId, filename}: DeleteArtifactRequest):\n Promise<void> {\n const path = artifactPath(appName, userId, sessionId, filename);\n if (!this.artifacts[path]) {\n return Promise.resolve();\n }\n delete this.artifacts[path];\n\n return Promise.resolve();\n }\n\n listVersions({appName, userId, sessionId, filename}: ListVersionsRequest):\n Promise<number[]> {\n const path = artifactPath(appName, userId, sessionId, filename);\n const artifacts = this.artifacts[path];\n\n if (!artifacts) {\n return Promise.resolve([]);\n }\n\n let versions: number[] = [];\n for (let i = 0; i < artifacts.length; i++) {\n versions.push(i);\n }\n\n return Promise.resolve(versions);\n }\n}\n\n/**\n * Constructs the path to the artifact.\n *\n * @param appName The app name.\n * @param userId The user ID.\n * @param sessionId The session ID.\n * @param filename The filename.\n * @return The path to the artifact.\n */\nfunction artifactPath(\n appName: string,\n userId: string,\n sessionId: string,\n filename: string,\n ): string {\n if (fileHasUserNamespace(filename)) {\n return `${appName}/${userId}/user/${filename}`;\n }\n\n return `${appName}/${userId}/${sessionId}/${filename}`;\n}\n\n/**\n * Checks if the filename has a user namespace prefix.\n *\n * @param filename The filename to check.\n * @return true if the filename has a user namespace (starts with \"user:\") false\n * otherwise.\n */\nfunction fileHasUserNamespace(filename: string): boolean {\n return filename.startsWith('user:');\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Event} from '../events/event.js';\nimport {Session} from '../sessions/session.js';\n\nimport {BaseMemoryService, SearchMemoryRequest, SearchMemoryResponse} from './base_memory_service.js';\nimport {MemoryEntry} from './memory_entry.js';\n\n/**\n * An in-memory memory service for prototyping purpose only.\n *\n * Uses keyword matching instead of semantic search.\n */\nexport class InMemoryMemoryService implements BaseMemoryService {\n private readonly memories: MemoryEntry[] = [];\n private readonly sessionEvents:\n {[userKey: string]: {[sessionId: string]: Event[]}} = {};\n\n async addSessionToMemory(session: Session): Promise<void> {\n const userKey = getUserKey(session.appName, session.userId);\n if (!this.sessionEvents[userKey]) {\n this.sessionEvents[userKey] = {};\n }\n this.sessionEvents[userKey][session.id] = session.events.filter(\n (event) => (event.content?.parts?.length ?? 0) > 0);\n }\n\n async searchMemory(req: SearchMemoryRequest): Promise<SearchMemoryResponse> {\n const userKey = getUserKey(req.appName, req.userId);\n if (!this.sessionEvents[userKey]) {\n return Promise.resolve({memories: []});\n }\n\n const wordsInQuery = req.query.toLowerCase().split(/\\s+/);\n const response: SearchMemoryResponse = {memories: []};\n\n for (const sessionEvents of Object.values(this.sessionEvents[userKey])) {\n for (const event of sessionEvents) {\n if (!event.content?.parts?.length) {\n continue;\n }\n\n const joinedText = event.content.parts.map((part) => part.text)\n .filter(text => !!text)\n .join(' ');\n const wordsInEvent = extractWordsLower(joinedText);\n if (!wordsInEvent.size) {\n continue;\n }\n\n const matchQuery =\n wordsInQuery.some(queryWord => wordsInEvent.has(queryWord));\n if (matchQuery) {\n response.memories.push({\n content: event.content,\n author: event.author,\n timestamp: formatTimestamp(event.timestamp),\n });\n }\n }\n }\n\n return response;\n }\n}\n\n/**\n * Constructs the user key from the app name and user ID.\n *\n * @param appName The app name.\n * @param userId The user ID.\n * @return The user key.\n */\nfunction getUserKey(appName: string, userId: string): string {\n return `${appName}/${userId}`;\n}\n\n/**\n * Extracts the words from the text.\n *\n * @param text The text to extract the words from.\n * @return A set of words.\n */\nfunction extractWordsLower(text: string): Set<string> {\n return new Set(\n [...text.matchAll(/[A-Za-z]+/)].map(match => match[0].toLowerCase()));\n}\n\n/**\n * Formats the timestamp to a string in ISO format.\n *\n * @param timestamp The timestamp to format.\n * @return A string representing the timestamp in ISO format.\n */\nfunction formatTimestamp(timestamp: number): string {\n return new Date(timestamp).toISOString();\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Content} from '@google/genai';\n\nimport {BaseAgent} from '../agents/base_agent.js';\nimport {CallbackContext} from '../agents/callback_context.js';\nimport {InvocationContext} from '../agents/invocation_context.js';\nimport {Event} from '../events/event.js';\nimport {LlmRequest} from '../models/llm_request.js';\nimport {LlmResponse} from '../models/llm_response.js';\nimport {BaseTool} from '../tools/base_tool.js';\nimport {ToolContext} from '../tools/tool_context.js';\n\n/**\n * Base class for creating plugins.\n *\n * Plugins provide a structured way to intercept and modify agent, tool, and\n * LLM behaviors at critical execution points in a callback manner. While agent\n * callbacks apply to a particular agent, plugins applies globally to all\n * agents added in the runner. Plugins are best used for adding custom behaviors\n * like logging, monitoring, caching, or modifying requests and responses at key\n * stages.\n *\n * A plugin can implement one or more methods of callbacks, but should not\n * implement the same method of callback for multiple times.\n *\n * Relation with [Agent\n * callbacks](https://google.github.io/adk-docs/callbacks/):\n *\n * **Execution Order**\n * Similar to Agent callbacks, Plugins are executed in the order they are\n * registered. However, Plugin and Agent Callbacks are executed sequentially,\n * with Plugins takes precedence over agent callbacks. When the callback in a\n * plugin returns a value, it will short circuit all remaining plugins and\n * agent callbacks, causing all remaining plugins and agent callbacks\n * to be skipped.\n *\n * **Change Propagation**\n * Plugins and agent callbacks can both modify the value of the input\n * parameters, including agent input, tool input, and LLM request/response, etc.\n * They work in the exactly same way. The modifications will be visible and\n * passed to the next callback in the chain. For example, if a plugin modifies\n * the tool input with before_tool_callback, the modified tool input will be\n * passed to the before_tool_callback of the next plugin, and further passed to\n * the agent callbacks if not short circuited.\n *\n * To use a plugin, implement the desired callback methods and pass an instance\n * of your custom plugin class to the ADK Runner.\n *\n * Example:\n * A simple plugin that logs every tool call.\n * ```typescript\n * class ToolLoggerPlugin extends BasePlugin {\n * constructor() {\n * super('tool_logger');\n * }\n *\n * override async beforeToolCallback(\n * {tool, toolArgs, toolContext}: {\n * tool: BaseTool,\n * toolArgs: Record<string, unknown>,\n * toolContext: ToolContext,\n * },\n * ): Promise<Record<string, unknown> | undefined> {\n * this.logger.info(\n * `[${this.name}] Calling tool '${tool.name}' with args:\n * ${JSON.stringify( toolArgs,\n * )}`,\n * );\n * return;\n * }\n *\n * override async afterToolCallback(\n * {tool, toolArgs, toolContext, result}: {\n * tool: BaseTool,\n * toolArgs: Record<string, unknown>,\n * toolContext: ToolContext,\n * result: Record<string, unknown>,\n * },\n * ): Promise<Record<string, unknown> | undefined> {\n * this.logger.info(\n * `[${this.name}] Tool '${tool.name}' finished with result:\n * ${JSON.stringify( result,\n * )}`,\n * );\n * return;\n * }\n * }\n *\n * // Add the plugin to ADK Runner\n * // runner = new Runner({\n * // ...\n * // plugins: [new ToolLoggerPlugin(), new AgentPolicyPlugin()],\n * // });\n * ```\n */\nexport abstract class BasePlugin {\n readonly name: string;\n\n /**\n * Initializes the plugin.\n *\n * @param name A unique identifier for this plugin instance.\n */\n constructor(name: string) {\n this.name = name;\n }\n\n /**\n * Callback executed when a user message is received before an invocation\n * starts.\n *\n * This callback helps logging and modifying the user message before the\n * runner starts the invocation.\n *\n * @param invocationContext The context for the entire invocation.\n * @param userMessage The message content input by user.\n * @returns An optional `Content` to be returned to the ADK. Returning a\n * value to replace the user message. Returning `undefined` to proceed\n * normally.\n */\n async onUserMessageCallback({invocationContext, userMessage}: {\n invocationContext: InvocationContext; userMessage: Content;\n }): Promise<Content|undefined> {\n return;\n }\n\n /**\n * Callback executed before the ADK runner runs.\n *\n * This is the first callback to be called in the lifecycle, ideal for global\n * setup or initialization tasks.\n *\n * @param invocationContext The context for the entire invocation, containing\n * session information, the root agent, etc.\n * @returns An optional `Event` to be returned to the ADK. Returning a value\n * to halt execution of the runner and ends the runner with that event.\n * Return `undefined` to proceed normally.\n */\n async beforeRunCallback({invocationContext}: {\n invocationContext: InvocationContext;\n }): Promise<Content|undefined> {\n return;\n }\n\n /**\n * Callback executed after an event is yielded from runner.\n *\n * This is the ideal place to make modification to the event before the event\n * is handled by the underlying agent app.\n *\n * @param invocationContext The context for the entire invocation.\n * @param event The event raised by the runner.\n * @returns An optional value. A non-`undefined` return may be used by the\n * framework to modify or replace the response. Returning `undefined`\n * allows the original response to be used.\n */\n async onEventCallback({invocationContext, event}: {\n invocationContext: InvocationContext; event: Event;\n }): Promise<Event|undefined> {\n return;\n }\n\n /**\n * Callback executed after an ADK runner run has completed.\n *\n * This is the final callback in the ADK lifecycle, suitable for cleanup,\n * final logging, or reporting tasks.\n *\n * @param invocationContext The context for the entire invocation.\n * @returns undefined\n */\n async afterRunCallback({invocationContext}: {\n invocationContext: InvocationContext;\n }): Promise<void> {\n return;\n }\n\n /**\n * Callback executed before an agent's primary logic is invoked.\n *\n * This callback can be used for logging, setup, or to short-circuit the\n * agent's execution by returning a value.\n *\n * @param agent The agent that is about to run.\n * @param callbackContext The context for the agent invocation.\n * @returns An optional `Content` object. If a value is returned, it will\n * bypass the agent's callbacks and its execution, and return this value\n * directly. Returning `undefined` allows the agent to proceed normally.\n */\n async beforeAgentCallback({agent, callbackContext}: {\n agent: BaseAgent; callbackContext: CallbackContext;\n }): Promise<Content|undefined> {\n return;\n }\n\n /**\n * Callback executed after an agent's primary logic has completed.\n *\n * This callback can be used to inspect, log, or modify the agent's final\n * result before it is returned.\n *\n * @param agent The agent that has just run.\n * @param callbackContext The context for the agent invocation.\n * @returns An optional `Content` object. If a value is returned, it will\n * replace the agent's original result. Returning `undefined` uses the\n * original, unmodified result.\n */\n async afterAgentCallback({agent, callbackContext}: {\n agent: BaseAgent; callbackContext: CallbackContext;\n }): Promise<Content|undefined> {\n return;\n }\n\n /**\n * Callback executed before a request is sent to the model.\n *\n * This provides an opportunity to inspect, log, or modify the `LlmRequest`\n * object. It can also be used to implement caching by returning a cached\n * `LlmResponse`, which would skip the actual model call.\n *\n * @param callbackContext The context for the current agent call.\n * @param llmRequest The prepared request object to be sent to the model.\n * @returns An optional value. The interpretation of a non-`undefined`\n * trigger an early exit and returns the response immediately. Returning\n * `undefined` allows the LLM request to proceed normally.\n */\n async beforeModelCallback({callbackContext, llmRequest}: {\n callbackContext: CallbackContext; llmRequest: LlmRequest;\n }): Promise<LlmResponse|undefined> {\n return;\n }\n\n /**\n * Callback executed after a response is received from the model.\n *\n * This is the ideal place to log model responses, collect metrics on token\n * usage, or perform post-processing on the raw `LlmResponse`.\n *\n * @param callbackContext The context for the current agent call.\n * @param llmResponse The response object received from the model.\n * @returns An optional value. A non-`undefined` return may be used by the\n * framework to modify or replace the response. Returning `undefined`\n * allows the original response to be used.\n */\n async afterModelCallback({callbackContext, llmResponse}: {\n callbackContext: CallbackContext; llmResponse: LlmResponse;\n }): Promise<LlmResponse|undefined> {\n return;\n }\n\n /**\n * Callback executed when a model call encounters an error.\n *\n * This callback provides an opportunity to handle model errors gracefully,\n * potentially providing alternative responses or recovery mechanisms.\n *\n * @param callbackContext The context for the current agent call.\n * @param llmRequest The request that was sent to the model when the error\n * occurred.\n * @param error The exception that was raised during model execution.\n * @returns An optional LlmResponse. If an LlmResponse is returned, it will be\n * used instead of propagating the error. Returning `undefined` allows\n * the original error to be raised.\n */\n async onModelErrorCallback({callbackContext, llmRequest, error}: {\n callbackContext: CallbackContext; llmRequest: LlmRequest; error: Error;\n }): Promise<LlmResponse|undefined> {\n return;\n }\n\n /**\n * Callback executed before a tool is called.\n *\n * This callback is useful for logging tool usage, input validation, or\n * modifying the arguments before they are passed to the tool.\n *\n * @param tool The tool instance that is about to be executed.\n * @param toolArgs The dictionary of arguments to be used for invoking the\n * tool.\n * @param toolContext The context specific to the tool execution.\n * @returns An optional dictionary. If a dictionary is returned, it will stop\n * the tool execution and return this response immediately. Returning\n * `undefined` uses the original, unmodified arguments.\n */\n async beforeToolCallback({tool, toolArgs, toolContext}: {\n tool: BaseTool; toolArgs: Record<string, unknown>; toolContext: ToolContext;\n }): Promise<Record<string, unknown>|undefined> {\n return;\n }\n\n /**\n * Callback executed after a tool has been called.\n *\n * This callback allows for inspecting, logging, or modifying the result\n * returned by a tool.\n *\n * @param tool The tool instance that has just been executed.\n * @param toolArgs The original arguments that were passed to the tool.\n * @param toolContext The context specific to the tool execution.\n * @param result The dictionary returned by the tool invocation.\n * @returns An optional dictionary. If a dictionary is returned, it will\n * **replace** the original result from the tool. This allows for\n * post-processing or altering tool outputs. Returning `undefined` uses\n * the original, unmodified result.\n */\n async afterToolCallback({tool, toolArgs, toolContext, result}: {\n tool: BaseTool; toolArgs: Record<string, unknown>; toolContext: ToolContext;\n result: Record<string, unknown>;\n }): Promise<Record<string, unknown>|undefined> {\n return;\n }\n\n /**\n * Callback executed when a tool call encounters an error.\n *\n * This callback provides an opportunity to handle tool errors gracefully,\n * potentially providing alternative responses or recovery mechanisms.\n *\n * @param tool The tool instance that encountered an error.\n * @param toolArgs The arguments that were passed to the tool.\n * @param toolContext The context specific to the tool execution.\n * @param error The exception that was raised during tool execution.\n * @returns An optional dictionary. If a dictionary is returned, it will be\n * used as the tool response instead of propagating the error. Returning\n * `undefined` allows the original error to be raised.\n */\n async onToolErrorCallback({tool, toolArgs, toolContext, error}: {\n tool: BaseTool; toolArgs: Record<string, unknown>; toolContext: ToolContext;\n error: Error;\n }): Promise<Record<string, unknown>|undefined> {\n return;\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Content} from '@google/genai';\n\nimport {BaseAgent} from '../agents/base_agent.js';\nimport {CallbackContext} from '../agents/callback_context.js';\nimport {InvocationContext} from '../agents/invocation_context.js';\nimport {Event, getFunctionCalls, getFunctionResponses, isFinalResponse} from '../events/event.js';\nimport {LlmRequest} from '../models/llm_request.js';\nimport {LlmResponse} from '../models/llm_response.js';\nimport {BaseTool} from '../tools/base_tool.js';\nimport {ToolContext} from '../tools/tool_context.js';\nimport {logger} from '../utils/logger.js';\n\nimport {BasePlugin} from './base_plugin.js';\n\n/**\n * A plugin that logs important information at each callback point.\n *\n * This plugin helps printing all critical events in the console. It is not a\n * replacement of existing logging in ADK. It rather helps terminal based\n * debugging by showing all logs in the console, and serves as a simple demo for\n * everyone to leverage when developing new plugins.\n *\n * This plugin helps users track the invocation status by logging:\n * - User messages and invocation context\n * - Agent execution flow\n * - LLM requests and responses\n * - Tool calls with arguments and results\n * - Events and final responses\n * - Errors during model and tool execution\n *\n * Example:\n * ```typescript\n * const loggingPlugin = new LoggingPlugin();\n * const runner = new Runner({\n * agents: [myAgent],\n * // ...\n * plugins: [loggingPlugin],\n * });\n * ```\n */\nexport class LoggingPlugin extends BasePlugin {\n /**\n * Initialize the logging plugin.\n *\n * @param name The name of the plugin instance.\n */\n constructor(name = 'logging_plugin') {\n super(name);\n }\n\n override async onUserMessageCallback(\n {invocationContext, userMessage}:\n {invocationContext: InvocationContext; userMessage: Content;},\n ): Promise<Content|undefined> {\n this.log('\uD83D\uDE80 USER MESSAGE RECEIVED');\n this.log(` Invocation ID: ${invocationContext.invocationId}`);\n this.log(` Session ID: ${invocationContext.session.id}`);\n this.log(` User ID: ${invocationContext.userId}`);\n this.log(` App Name: ${invocationContext.appName}`);\n this.log(` Root Agent: ${invocationContext.agent.name ?? 'Unknown'}`);\n this.log(` User Content: ${this.formatContent(userMessage)}`);\n if (invocationContext.branch) {\n this.log(` Branch: ${invocationContext.branch}`);\n }\n return undefined;\n }\n\n override async beforeRunCallback({invocationContext}: {\n invocationContext: InvocationContext;\n }): Promise<Content|undefined> {\n this.log('\uD83C\uDFC3 INVOCATION STARTING');\n this.log(` Invocation ID: ${invocationContext.invocationId}`);\n this.log(` Starting Agent: ${invocationContext.agent.name ?? 'Unknown'}`);\n return undefined;\n }\n\n override async onEventCallback({invocationContext, event}: {\n invocationContext: InvocationContext; event: Event;\n }): Promise<Event|undefined> {\n this.log('\uD83D\uDCE2 EVENT YIELDED');\n this.log(` Event ID: ${event.id}`);\n this.log(` Author: ${event.author}`);\n this.log(` Content: ${this.formatContent(event.content)}`);\n this.log(` Final Response: ${isFinalResponse(event)}`);\n\n const functionCalls = getFunctionCalls(event);\n if (functionCalls.length > 0) {\n const funcCalls = functionCalls.map((fc) => fc.name);\n this.log(` Function Calls: ${funcCalls}`);\n }\n\n const functionResponses = getFunctionResponses(event);\n if (functionResponses.length > 0) {\n const funcResponses = functionResponses.map((fr) => fr.name);\n this.log(` Function Responses: ${funcResponses}`);\n }\n\n if (event.longRunningToolIds && event.longRunningToolIds.length > 0) {\n this.log(` Long Running Tools: ${[...event.longRunningToolIds]}`);\n }\n\n return undefined;\n }\n\n override async afterRunCallback({invocationContext}: {\n invocationContext: InvocationContext;\n }): Promise<void> {\n this.log('\u2705 INVOCATION COMPLETED');\n this.log(` Invocation ID: ${invocationContext.invocationId}`);\n this.log(` Final Agent: ${invocationContext.agent.name ?? 'Unknown'}`);\n return undefined;\n }\n\n override async beforeAgentCallback({agent, callbackContext}: {\n agent: BaseAgent; callbackContext: CallbackContext;\n }): Promise<Content|undefined> {\n this.log('\uD83E\uDD16 AGENT STARTING');\n this.log(` Agent Name: ${callbackContext.agentName}`);\n this.log(` Invocation ID: ${callbackContext.invocationId}`);\n if (callbackContext.invocationContext.branch) {\n this.log(` Branch: ${callbackContext.invocationContext.branch}`);\n }\n return undefined;\n }\n\n override async afterAgentCallback({agent, callbackContext}: {\n agent: BaseAgent; callbackContext: CallbackContext;\n }): Promise<Content|undefined> {\n this.log('\uD83E\uDD16 AGENT COMPLETED');\n this.log(` Agent Name: ${callbackContext.agentName}`);\n this.log(` Invocation ID: ${callbackContext.invocationId}`);\n return undefined;\n }\n\n override async beforeModelCallback({callbackContext, llmRequest}: {\n callbackContext: CallbackContext; llmRequest: LlmRequest;\n }): Promise<LlmResponse|undefined> {\n this.log('\uD83E\uDDE0 LLM REQUEST');\n this.log(` Model: ${llmRequest.model ?? 'default'}`);\n this.log(` Agent: ${callbackContext.agentName}`);\n\n if (llmRequest.config && llmRequest.config.systemInstruction) {\n let sysInstruction = llmRequest.config.systemInstruction as string;\n if (sysInstruction.length > 200) {\n sysInstruction = sysInstruction.substring(0, 200) + '...';\n }\n this.log(` System Instruction: '${sysInstruction}'`);\n }\n\n if (llmRequest.toolsDict) {\n const toolNames = Object.keys(llmRequest.toolsDict);\n this.log(` Available Tools: ${toolNames}`);\n }\n\n return undefined;\n }\n\n override async afterModelCallback({callbackContext, llmResponse}: {\n callbackContext: CallbackContext; llmResponse: LlmResponse;\n }): Promise<LlmResponse|undefined> {\n this.log('\uD83E\uDDE0 LLM RESPONSE');\n this.log(` Agent: ${callbackContext.agentName}`);\n\n if (llmResponse.errorCode) {\n this.log(` \u274C ERROR - Code: ${llmResponse.errorCode}`);\n this.log(` Error Message: ${llmResponse.errorMessage}`);\n } else {\n this.log(` Content: ${this.formatContent(llmResponse.content)}`);\n if (llmResponse.partial) {\n this.log(` Partial: ${llmResponse.partial}`);\n }\n if (llmResponse.turnComplete !== undefined) {\n this.log(` Turn Complete: ${llmResponse.turnComplete}`);\n }\n }\n\n if (llmResponse.usageMetadata) {\n this.log(` Token Usage - Input: ${\n llmResponse.usageMetadata.promptTokenCount}, Output: ${\n llmResponse.usageMetadata.candidatesTokenCount}`);\n }\n\n return undefined;\n }\n\n override async beforeToolCallback({tool, toolArgs, toolContext}: {\n tool: BaseTool; toolArgs: Record<string, unknown>; toolContext: ToolContext;\n }): Promise<Record<string, unknown>|undefined> {\n this.log('\uD83D\uDD27 TOOL STARTING');\n this.log(` Tool Name: ${tool.name}`);\n this.log(` Agent: ${toolContext.agentName}`);\n this.log(` Function Call ID: ${toolContext.functionCallId}`);\n this.log(` Arguments: ${this.formatArgs(toolArgs)}`);\n return undefined;\n }\n\n override async afterToolCallback({tool, toolArgs, toolContext, result}: {\n tool: BaseTool; toolArgs: Record<string, unknown>; toolContext: ToolContext;\n result: Record<string, unknown>;\n }): Promise<Record<string, unknown>|undefined> {\n this.log('\uD83D\uDD27 TOOL COMPLETED');\n this.log(` Tool Name: ${tool.name}`);\n this.log(` Agent: ${toolContext.agentName}`);\n this.log(` Function Call ID: ${toolContext.functionCallId}`);\n this.log(` Result: ${this.formatArgs(result)}`);\n return undefined;\n }\n\n override async onModelErrorCallback({callbackContext, llmRequest, error}: {\n callbackContext: CallbackContext; llmRequest: LlmRequest; error: Error;\n }): Promise<LlmResponse|undefined> {\n this.log('\uD83E\uDDE0 LLM ERROR');\n this.log(` Agent: ${callbackContext.agentName}`);\n this.log(` Error: ${error}`);\n\n return undefined;\n }\n\n override async onToolErrorCallback({tool, toolArgs, toolContext, error}: {\n tool: BaseTool; toolArgs: Record<string, unknown>; toolContext: ToolContext;\n error: Error;\n }): Promise<Record<string, unknown>|undefined> {\n this.log('\uD83D\uDD27 TOOL ERROR');\n this.log(` Tool Name: ${tool.name}`);\n this.log(` Agent: ${toolContext.agentName}`);\n this.log(` Function Call ID: ${toolContext.functionCallId}`);\n this.log(` Arguments: ${this.formatArgs(toolArgs)}`);\n this.log(` Error: ${error}`);\n return undefined;\n }\n\n private log(message: string): void {\n const formattedMessage = `\\u001b[90m[${this.name}] ${message}\\u001b[0m`;\n logger.info(formattedMessage);\n }\n\n private formatContent(content?: Content, maxLength = 200): string {\n if (!content || !content.parts) {\n return 'None';\n }\n\n const parts: string[] = [];\n for (const part of content.parts) {\n if (part.text) {\n let text = part.text.trim();\n if (text.length > maxLength) {\n text = text.substring(0, maxLength) + '...';\n }\n parts.push(`text: '${text}'`);\n } else if (part.functionCall) {\n parts.push(`function_call: ${part.functionCall.name}`);\n } else if (part.functionResponse) {\n parts.push(`function_response: ${part.functionResponse.name}`);\n } else if (part.codeExecutionResult) {\n parts.push('code_execution_result');\n } else {\n parts.push('other_part');\n }\n }\n\n return parts.join(' | ');\n }\n\n private formatArgs(args: Record<string, unknown>, maxLength = 300): string {\n if (!args) {\n return '{}';\n }\n\n let formatted = JSON.stringify(args);\n if (formatted.length > maxLength) {\n formatted = formatted.substring(0, maxLength) + '...}';\n }\n return formatted;\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Content} from '@google/genai';\n\nimport {BaseAgent} from '../agents/base_agent.js';\nimport {CallbackContext} from '../agents/callback_context.js';\nimport {InvocationContext} from '../agents/invocation_context.js';\nimport {Event} from '../events/event.js';\nimport {LlmRequest} from '../models/llm_request.js';\nimport {LlmResponse} from '../models/llm_response.js';\nimport {BaseTool} from '../tools/base_tool.js';\nimport {ToolContext} from '../tools/tool_context.js';\nimport {logger} from '../utils/logger.js';\n\nimport {BasePlugin} from './base_plugin.js';\n\n/**\n * Manages the registration and execution of plugins.\n *\n * The PluginManager is an internal class that orchestrates the invocation of\n * plugin callbacks at key points in the SDK's execution lifecycle. It maintains\n * a list of registered plugins and ensures they are called in the order they\n * were registered.\n *\n * The core execution logic implements an \"early exit\" strategy: if any plugin\n * callback returns a non-`undefined` value, the execution of subsequent plugins\n * for that specific event is halted, and the returned value is propagated up\n * the call stack. This allows plugins to short-circuit operations like agent\n * runs, tool calls, or model requests.\n */\nexport class PluginManager {\n private readonly plugins: Set<BasePlugin> = new Set();\n /**\n * Initializes the plugin service.\n *\n * @param plugins An optional list of plugins to register upon\n * initialization.\n */\n constructor(plugins?: BasePlugin[]) {\n if (plugins) {\n for (const plugin of plugins) {\n this.registerPlugin(plugin);\n }\n }\n }\n\n /**\n * Registers a new plugin.\n *\n * @param plugin The plugin instance to register.\n * @throws If the same exact plugin or a plugin with the same name is already\n * registered.\n */\n registerPlugin(plugin: BasePlugin): void {\n // Short circuit for duplicate objects or duplicate names\n if (this.plugins.has(plugin)) {\n throw new Error(`Plugin '${plugin.name}' already registered.`);\n }\n if (Array.from(this.plugins).some(p => p.name === plugin.name)) {\n throw new Error(`Plugin with name '${plugin.name}' already registered.`);\n }\n\n this.plugins.add(plugin);\n\n logger.info(`Plugin '${plugin.name}' registered.`);\n }\n\n /**\n * Retrieves a registered plugin by its name.\n *\n * @param pluginName The name of the plugin to retrieve.\n * @returns The plugin instance if found, otherwise `undefined`.\n */\n getPlugin(pluginName: string): BasePlugin|undefined {\n // Set operates on strict equality, we only want to match by name\n return Array.from(this.plugins).find(p => p.name === pluginName);\n }\n\n /**\n * Runs the same callback for all plugins. This is a utility method to reduce\n * duplication below.\n *\n * @param plugins The set of plugins to run\n * @param callback A closure containing the callback method to run on each\n * plugin\n * @param callbackName The name of the function being called in the closure\n * above. Used for logging purposes.\n * @returns A promise containing the plugin method result. Must be casted to\n * the proper type for the plugin method.\n */\n private async runCallbacks(\n plugins: Set<BasePlugin>,\n callback: (plugin: BasePlugin) => Promise<unknown>,\n callbackName: string,\n ): Promise<unknown> {\n for (const plugin of plugins) {\n try {\n const result = await callback(plugin);\n if (result !== undefined) {\n logger.debug(\n `Plugin '${plugin.name}' returned a value for callback '${\n callbackName}', exiting early.`);\n return result;\n }\n } catch (e) {\n const errorMessage = `Error in plugin '${\n plugin.name}' during '${callbackName}' callback: ${e}`;\n logger.error(errorMessage);\n throw new Error(errorMessage);\n }\n }\n return undefined;\n }\n\n /**\n * Runs the `onUserMessageCallback` for all plugins.\n */\n async runOnUserMessageCallback(\n {userMessage, invocationContext}:\n {userMessage: Content; invocationContext: InvocationContext;},\n ): Promise<Content|undefined> {\n return await this.runCallbacks(\n this.plugins,\n (plugin: BasePlugin) => plugin.onUserMessageCallback(\n {userMessage, invocationContext}),\n 'onUserMessageCallback',\n ) as Content |\n undefined;\n }\n\n /**\n * Runs the `beforeRunCallback` for all plugins.\n */\n async runBeforeRunCallback({invocationContext}: {\n invocationContext: InvocationContext;\n }): Promise<Content|undefined> {\n return (await this.runCallbacks(\n this.plugins,\n (plugin: BasePlugin) =>\n plugin.beforeRunCallback({invocationContext}),\n 'beforeRunCallback',\n )) as Content |\n undefined;\n }\n\n /**\n * Runs the `afterRunCallback` for all plugins.\n */\n async runAfterRunCallback({invocationContext}: {\n invocationContext: InvocationContext;\n }): Promise<void> {\n await this.runCallbacks(\n this.plugins,\n (plugin: BasePlugin) => plugin.afterRunCallback({invocationContext}),\n 'afterRunCallback',\n );\n }\n\n /**\n * Runs the `onEventCallback` for all plugins.\n */\n async runOnEventCallback({invocationContext, event}: {\n invocationContext: InvocationContext; event: Event;\n }): Promise<Event|undefined> {\n return (await this.runCallbacks(\n this.plugins,\n (plugin: BasePlugin) =>\n plugin.onEventCallback({invocationContext, event}),\n 'onEventCallback',\n )) as Event |\n undefined;\n }\n\n /**\n * Runs the `beforeAgentCallback` for all plugins.\n */\n async runBeforeAgentCallback({agent, callbackContext}: {\n agent: BaseAgent; callbackContext: CallbackContext;\n }): Promise<Content|undefined> {\n return (await this.runCallbacks(\n this.plugins,\n (plugin: BasePlugin) =>\n plugin.beforeAgentCallback({agent, callbackContext}),\n 'beforeAgentCallback',\n )) as Content |\n undefined;\n }\n\n /**\n * Runs the `afterAgentCallback` for all plugins.\n */\n async runAfterAgentCallback({agent, callbackContext}: {\n agent: BaseAgent; callbackContext: CallbackContext;\n }): Promise<Content|undefined> {\n return (await this.runCallbacks(\n this.plugins,\n (plugin: BasePlugin) =>\n plugin.afterAgentCallback({agent, callbackContext}),\n 'afterAgentCallback',\n )) as Content |\n undefined;\n }\n\n /**\n * Runs the `beforeToolCallback` for all plugins.\n */\n async runBeforeToolCallback({tool, toolArgs, toolContext}: {\n tool: BaseTool; toolArgs: Record<string, unknown>; toolContext: ToolContext;\n }): Promise<Record<string, unknown>|undefined> {\n return (await this.runCallbacks(\n this.plugins,\n (plugin: BasePlugin) =>\n plugin.beforeToolCallback({tool, toolArgs, toolContext}),\n 'beforeToolCallback',\n )) as Record<string, unknown>|\n undefined;\n }\n\n /**\n * Runs the `afterToolCallback` for all plugins.\n */\n async runAfterToolCallback({tool, toolArgs, toolContext, result}: {\n tool: BaseTool; toolArgs: Record<string, unknown>; toolContext: ToolContext;\n result: Record<string, unknown>;\n }): Promise<Record<string, unknown>|undefined> {\n return (await this.runCallbacks(\n this.plugins,\n (plugin: BasePlugin) => plugin.afterToolCallback(\n {tool, toolArgs, toolContext, result}),\n 'afterToolCallback',\n )) as Record<string, unknown>|\n undefined;\n }\n\n /**\n * Runs the `onModelErrorCallback` for all plugins.\n */\n async runOnModelErrorCallback({callbackContext, llmRequest, error}: {\n callbackContext: CallbackContext; llmRequest: LlmRequest; error: Error;\n }): Promise<LlmResponse|undefined> {\n return (await this.runCallbacks(\n this.plugins,\n (plugin: BasePlugin) => plugin.onModelErrorCallback(\n {callbackContext, llmRequest, error}),\n 'onModelErrorCallback',\n )) as LlmResponse |\n undefined;\n }\n\n /**\n * Runs the `beforeModelCallback` for all plugins.\n */\n async runBeforeModelCallback({callbackContext, llmRequest}: {\n callbackContext: CallbackContext; llmRequest: LlmRequest;\n }): Promise<LlmResponse|undefined> {\n return (await this.runCallbacks(\n this.plugins,\n (plugin: BasePlugin) =>\n plugin.beforeModelCallback({callbackContext, llmRequest}),\n 'beforeModelCallback',\n )) as LlmResponse |\n undefined;\n }\n\n /**\n * Runs the `afterModelCallback` for all plugins.\n */\n async runAfterModelCallback({callbackContext, llmResponse}: {\n callbackContext: CallbackContext; llmResponse: LlmResponse;\n }): Promise<LlmResponse|undefined> {\n return (await this.runCallbacks(\n this.plugins,\n (plugin: BasePlugin) =>\n plugin.afterModelCallback({callbackContext, llmResponse}),\n 'afterModelCallback',\n )) as LlmResponse |\n undefined;\n }\n\n /**\n * Runs the `onToolErrorCallback` for all plugins.\n */\n async runOnToolErrorCallback({tool, toolArgs, toolContext, error}: {\n tool: BaseTool; toolArgs: Record<string, unknown>; toolContext: ToolContext;\n error: Error;\n }): Promise<Record<string, unknown>|undefined> {\n return (await this.runCallbacks(\n this.plugins,\n (plugin: BasePlugin) => plugin.onToolErrorCallback(\n {tool, toolArgs, toolContext, error}),\n 'onToolErrorCallback',\n )) as Record<string, unknown>|\n undefined;\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Content, FunctionCall, FunctionResponse} from '@google/genai';\n\nimport {Event} from '../events/event.js';\nimport {BasePlugin} from '../plugins/base_plugin.js';\nimport {BaseTool} from '../tools/base_tool.js';\nimport {ToolConfirmation} from '../tools/tool_confirmation.js';\nimport {ToolContext} from '../tools/tool_context.js';\n\n// Constants\nexport const REQUEST_CONFIRMATION_FUNCTION_CALL_NAME =\n 'adk_request_confirmation';\n\nconst TOOL_CALL_SECURITY_CHECK_STATES = 'orcas_tool_call_security_check_states';\nconst INTERMEDIATE_REQUIRE_TOOL_CALL_CONFIRMATION_ERROR =\n 'This tool call needs external confirmation before completion.';\n\n// --------------------------------------------------------------------------\n// #START Policy Engine Interface\n// --------------------------------------------------------------------------\n\n/**\n * The outcome of a policy check.\n */\nexport enum PolicyOutcome {\n // The tool call is rejected by the policy engine.\n DENY = 'DENY',\n // The tool call needs external confirmation before proceeding.\n CONFIRM = 'CONFIRM',\n // The tool call is allowed by the policy engine.\n ALLOW = 'ALLOW',\n}\n\nexport interface PolicyCheckResult {\n outcome: string;\n reason?: string;\n}\n\nexport interface ToolCallPolicyContext {\n tool: BaseTool;\n toolArgs: Record<string, unknown>;\n}\n\nexport interface BasePolicyEngine {\n evaluate(context: ToolCallPolicyContext): Promise<PolicyCheckResult>;\n}\n\nexport class InMemoryPolicyEngine implements BasePolicyEngine {\n async evaluate(context: ToolCallPolicyContext): Promise<PolicyCheckResult> {\n // Default permissive implementation\n return Promise.resolve({\n outcome: PolicyOutcome.ALLOW,\n reason: 'For prototyping purpose, all tool calls are allowed.',\n });\n }\n}\n// --------------------------------------------------------------------------\n// #END Policy Engine Interface\n// --------------------------------------------------------------------------\n\n/**\n * Security Plugin for running Orcas agents.\n */\nexport class SecurityPlugin extends BasePlugin {\n private readonly policyEngine: BasePolicyEngine;\n\n constructor(params?: {policyEngine?: BasePolicyEngine;}) {\n super('security_plugin');\n this.policyEngine = params?.policyEngine ?? new InMemoryPolicyEngine();\n }\n\n override async beforeToolCallback({\n tool,\n toolArgs,\n toolContext,\n }: {\n tool: BaseTool,\n toolArgs: {[key: string]: unknown},\n toolContext: ToolContext\n }): Promise<{[key: string]: unknown}|undefined> {\n const toolCallCheckState = this.getToolCallCheckState(toolContext);\n\n // We only check the tool call policy ONCE, when the tool call is handled\n // for the first time.\n if (!toolCallCheckState) {\n return this.checkToolCallPolicy({\n tool: tool,\n toolArgs: toolArgs,\n toolContext: toolContext,\n });\n }\n\n if (toolCallCheckState !== PolicyOutcome.CONFIRM) {\n return;\n }\n\n if (!toolContext.toolConfirmation) {\n return {partial: INTERMEDIATE_REQUIRE_TOOL_CALL_CONFIRMATION_ERROR};\n }\n\n this.setToolCallCheckState(toolContext, toolContext.toolConfirmation);\n if (!toolContext.toolConfirmation.confirmed) {\n return {\n error: 'Tool call rejected from confirmation flow.',\n };\n }\n toolContext.toolConfirmation = undefined;\n return;\n }\n\n private getToolCallCheckState(toolContext: ToolContext): string\n |ToolConfirmation|undefined {\n const {functionCallId} = toolContext;\n if (!functionCallId) {\n return;\n }\n\n const toolCallStates =\n (toolContext.state.get(TOOL_CALL_SECURITY_CHECK_STATES) as\n {[key: string]: string | ToolConfirmation}) ??\n {};\n return toolCallStates[functionCallId];\n }\n\n private setToolCallCheckState(\n toolContext: ToolContext, state: string|ToolConfirmation): void {\n const {functionCallId} = toolContext;\n if (!functionCallId) {\n return;\n }\n\n const toolCallStates =\n (toolContext.state.get(TOOL_CALL_SECURITY_CHECK_STATES) as\n {[key: string]: string | ToolConfirmation}) ??\n {};\n toolCallStates[functionCallId] = state;\n toolContext.state.set(TOOL_CALL_SECURITY_CHECK_STATES, toolCallStates);\n }\n\n private async checkToolCallPolicy({\n tool,\n toolArgs,\n toolContext,\n }: {\n tool: BaseTool,\n toolArgs: {[key: string]: any},\n toolContext: ToolContext\n }): Promise<{[key: string]: unknown}|undefined> {\n const policyCheckResult =\n await this.policyEngine.evaluate({tool, toolArgs});\n\n this.setToolCallCheckState(toolContext, policyCheckResult.outcome);\n\n switch (policyCheckResult.outcome) {\n case PolicyOutcome.DENY:\n return {\n error: `This tool call is rejected by policy engine. Reason: ${\n policyCheckResult.reason}`,\n };\n case PolicyOutcome.CONFIRM:\n toolContext.requestConfirmation({\n hint: `Policy engine requires confirmation calling tool: ${\n tool.name}. Reason: ${policyCheckResult.reason}`,\n });\n return {partial: INTERMEDIATE_REQUIRE_TOOL_CALL_CONFIRMATION_ERROR};\n case PolicyOutcome.ALLOW:\n return;\n default:\n return;\n }\n }\n}\n\n\n/**\n * Gets the ask user confirmation function calls from the event.\n * @param event The event to get the function calls from.\n * @returns The ask user confirmation function calls.\n */\nexport function getAskUserConfirmationFunctionCalls(event: Event):\n FunctionCall[] {\n if (!event.content || !event.content.parts) {\n return [];\n }\n const results: FunctionCall[] = [];\n\n for (const part of event.content.parts) {\n if (part && part.functionCall &&\n part.functionCall.name === REQUEST_CONFIRMATION_FUNCTION_CALL_NAME) {\n results.push(part.functionCall);\n }\n }\n return results;\n}", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Event} from '../events/event.js';\n\nimport {Session} from './session.js';\nimport {State} from './state.js';\n\n/**\n * The configuration of getting a session.\n */\nexport interface GetSessionConfig {\n /** The number of recent events to retrieve. */\n numRecentEvents?: number;\n /** Retrieve events after this timestamp. */\n afterTimestamp?: number;\n}\n\n/**\n * The parameters for `createSession`.\n */\nexport interface CreateSessionRequest {\n /** The name of the application. */\n appName: string;\n /** The ID of the user. */\n userId: string;\n /** The initial state of the session. */\n state?: Record<string, unknown>;\n /** The ID of the session. A new ID will be generated if not provided. */\n sessionId?: string;\n}\n\n/**\n * The parameters for `getSession`.\n */\nexport interface GetSessionRequest {\n /** The name of the application. */\n appName: string;\n /** The ID of the user. */\n userId: string;\n /** The ID of the session. */\n sessionId: string;\n /** The configurations for getting the session. */\n config?: GetSessionConfig;\n}\n\n/**\n * The parameters for `listSessions`.\n */\nexport interface ListSessionsRequest {\n /** The name of the application. */\n appName: string;\n /** The ID of the user. */\n userId: string;\n}\n\n/**\n * The parameters for `deleteSession`.\n */\nexport interface DeleteSessionRequest {\n /** The name of the application. */\n appName: string;\n /** The ID of the user. */\n userId: string;\n /** The ID of the session. */\n sessionId: string;\n}\n\n/**\n * The parameters for `appendEvent`.\n */\nexport interface AppendEventRequest {\n /** The session to append the event to. */\n session: Session;\n /** The event to append. */\n event: Event;\n}\n\n/**\n * The response of listing sessions.\n *\n * The events and states are not set within each Session object.\n */\nexport interface ListSessionsResponse {\n /** A list of sessions. */\n sessions: Session[];\n}\n\n/**\n * Base class for session services.\n *\n * The service provides a set of methods for managing sessions and events.\n */\n// TODO - b/425992518: can held session internally to make the API simpler.\nexport abstract class BaseSessionService {\n /**\n * Creates a new session.\n *\n * @param request The request to create a session.\n * @return A promise that resolves to the newly created session instance.\n */\n abstract createSession(request: CreateSessionRequest): Promise<Session>;\n\n /**\n * Gets a session.\n *\n * @param request The request to get a session.\n * @return A promise that resolves to the session instance or undefined if not\n * found.\n */\n abstract getSession(request: GetSessionRequest): Promise<Session|undefined>;\n\n /**\n * Lists sessions for a user.\n *\n * @param request The request to list sessions.\n * @return A promise that resolves to a list of sessions for the user.\n */\n abstract listSessions(request: ListSessionsRequest):\n Promise<ListSessionsResponse>;\n\n /**\n * Deletes a session.\n *\n * @param request The request to delete a session.\n * @return A promise that resolves when the session is deleted.\n */\n abstract deleteSession(request: DeleteSessionRequest): Promise<void>;\n\n /**\n * Appends an event to a session.\n *\n * @param request The request to append an event.\n * @return A promise that resolves to the event that was appended.\n */\n async appendEvent({session, event}: AppendEventRequest): Promise<Event> {\n if (event.partial) {\n return event;\n }\n\n this.updateSessionState({session, event});\n session.events.push(event);\n\n return event;\n }\n\n /**\n * Updates the session state based on the event.\n *\n * @param request The request to update the session state.\n */\n private updateSessionState({session, event}: AppendEventRequest): void {\n if (!event.actions || !event.actions.stateDelta) {\n return;\n }\n for (const [key, value] of Object.entries(event.actions.stateDelta)) {\n if (key.startsWith(State.TEMP_PREFIX)) {\n continue;\n }\n session.state[key] = value;\n }\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Event} from '../events/event.js';\n\n/**\n * Represents a session in a conversation between agents and users.\n */\nexport interface Session {\n /**\n * The unique identifier of the session.\n */\n id: string;\n\n /**\n * The name of the app.\n */\n appName: string;\n\n /**\n * The id of the user.\n */\n userId: string;\n\n /**\n * The state of the session.\n */\n state: Record<string, unknown>;\n\n /**\n * The events of the session, e.g. user input, model response, function\n * call/response, etc.\n */\n events: Event[];\n\n /**\n * The last update time of the session.\n */\n lastUpdateTime: number;\n}\n\n/**\n * Creates a session from a partial session.\n *\n * @param params The partial session to create the session from.\n * @returns The session.\n */\nexport function createSession(params: Partial<Session>&{\n id: string;\n appName: string;\n}): Session {\n return {\n id: params.id,\n appName: params.appName,\n userId: params.userId || '',\n state: params.state || {},\n events: params.events || [],\n lastUpdateTime: params.lastUpdateTime || 0,\n };\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Event} from '../events/event.js';\nimport {deepClone} from '../utils/deep_clone.js';\nimport {randomUUID} from '../utils/env_aware_utils.js';\nimport {logger} from '../utils/logger.js';\n\nimport {AppendEventRequest, BaseSessionService, CreateSessionRequest, DeleteSessionRequest, GetSessionConfig, GetSessionRequest, ListSessionsRequest, ListSessionsResponse} from './base_session_service.js';\nimport {createSession, Session} from './session.js';\nimport {State} from './state.js';\n\n/**\n * An in-memory implementation of the session service.\n */\nexport class InMemorySessionService extends BaseSessionService {\n /**\n * A map from app name to a map from user ID to a map from session ID to\n * session.\n */\n private sessions:\n Record<string, Record<string, Record<string, Session>>> = {};\n\n /**\n * A map from app name to a map from user ID to a map from key to the value.\n */\n private userState:\n Record<string, Record<string, Record<string, unknown>>> = {};\n\n /**\n * A map from app name to a map from key to the value.\n */\n private appState: Record<string, Record<string, unknown>> = {};\n\n createSession({appName, userId, state, sessionId}: CreateSessionRequest):\n Promise<Session> {\n const session = createSession({\n id: sessionId || randomUUID(),\n appName,\n userId,\n state,\n events: [],\n lastUpdateTime: Date.now(),\n });\n\n if (!this.sessions[appName]) {\n this.sessions[appName] = {};\n }\n if (!this.sessions[appName][userId]) {\n this.sessions[appName][userId] = {};\n }\n\n this.sessions[appName][userId][session.id] = session;\n\n return Promise.resolve(\n this.mergeState(appName, userId, deepClone(session)));\n }\n\n getSession({appName, userId, sessionId, config}: GetSessionRequest):\n Promise<Session|undefined> {\n if (!this.sessions[appName] || !this.sessions[appName][userId] ||\n !this.sessions[appName][userId][sessionId]) {\n return Promise.resolve(undefined);\n }\n\n const session: Session = this.sessions[appName][userId][sessionId];\n const copiedSession = deepClone(session);\n\n if (config) {\n if (config.numRecentEvents) {\n copiedSession.events =\n copiedSession.events.slice(-config.numRecentEvents);\n }\n if (config.afterTimestamp) {\n let i = copiedSession.events.length - 1;\n while (i >= 0) {\n if (copiedSession.events[i].timestamp < config.afterTimestamp) {\n break;\n }\n i--;\n }\n if (i >= 0) {\n copiedSession.events = copiedSession.events.slice(i + 1);\n }\n }\n }\n\n return Promise.resolve(this.mergeState(appName, userId, copiedSession));\n }\n\n listSessions({appName, userId}: ListSessionsRequest):\n Promise<ListSessionsResponse> {\n if (!this.sessions[appName] || !this.sessions[appName][userId]) {\n return Promise.resolve({sessions: []});\n }\n\n const sessionsWithoutEvents: Session[] = [];\n for (const session of Object.values(this.sessions[appName][userId])) {\n sessionsWithoutEvents.push(createSession({\n id: session.id,\n appName: session.appName,\n userId: session.userId,\n state: {},\n events: [],\n lastUpdateTime: session.lastUpdateTime,\n }));\n }\n\n return Promise.resolve({sessions: sessionsWithoutEvents});\n }\n\n async deleteSession({appName, userId, sessionId}: DeleteSessionRequest):\n Promise<void> {\n const session = await this.getSession({appName, userId, sessionId});\n\n if (!session) {\n return;\n }\n\n delete this.sessions[appName][userId][sessionId];\n }\n\n override async appendEvent({session, event}: AppendEventRequest):\n Promise<Event> {\n await super.appendEvent({session, event});\n session.lastUpdateTime = event.timestamp;\n\n const appName = session.appName;\n const userId = session.userId;\n const sessionId = session.id;\n\n const warning = (message: string) => {\n logger.warn(`Failed to append event to session ${sessionId}: ${message}`);\n };\n\n if (!this.sessions[appName]) {\n warning(`appName ${appName} not in sessions`);\n return event;\n }\n\n if (!this.sessions[appName][userId]) {\n warning(`userId ${userId} not in sessions[appName]`);\n return event;\n }\n\n if (!this.sessions[appName][userId][sessionId]) {\n warning(`sessionId ${sessionId} not in sessions[appName][userId]`);\n return event;\n }\n\n if (event.actions && event.actions.stateDelta) {\n for (const key of Object.keys(event.actions.stateDelta)) {\n if (key.startsWith(State.APP_PREFIX)) {\n this.appState[appName] = this.appState[appName] || {};\n this.appState[appName][key.replace(State.APP_PREFIX, '')] =\n event.actions.stateDelta[key];\n }\n\n if (key.startsWith(State.USER_PREFIX)) {\n this.userState[appName] = this.userState[appName] || {};\n this.userState[appName][userId] =\n this.userState[appName][userId] || {};\n this.userState[appName][userId][key.replace(State.USER_PREFIX, '')] =\n event.actions.stateDelta[key];\n }\n }\n }\n\n const storageSession: Session = this.sessions[appName][userId][sessionId];\n await super.appendEvent({session: storageSession, event});\n\n storageSession.lastUpdateTime = event.timestamp;\n\n return event;\n }\n\n private mergeState(\n appName: string,\n userId: string,\n copiedSession: Session,\n ): Session {\n if (this.appState[appName]) {\n for (const key of Object.keys(this.appState[appName])) {\n copiedSession.state[State.APP_PREFIX + key] =\n this.appState[appName][key];\n }\n }\n\n if (!this.userState[appName] || !this.userState[appName][userId]) {\n return copiedSession;\n }\n\n for (const key of Object.keys(this.userState[appName][userId])) {\n copiedSession.state[State.USER_PREFIX + key] =\n this.userState[appName][userId][key];\n }\n return copiedSession;\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Content, createPartFromText} from '@google/genai';\nimport {trace} from '@opentelemetry/api';\n\nimport {BaseAgent} from '../agents/base_agent.js';\nimport {InvocationContext, newInvocationContextId} from '../agents/invocation_context.js';\nimport {LlmAgent} from '../agents/llm_agent.js';\nimport {createRunConfig, RunConfig} from '../agents/run_config.js';\nimport {BaseArtifactService} from '../artifacts/base_artifact_service.js';\nimport {BaseCredentialService} from '../auth/credential_service/base_credential_service.js';\nimport {createEvent, Event, getFunctionCalls} from '../events/event.js';\nimport {createEventActions} from '../events/event_actions.js';\nimport {BaseMemoryService} from '../memory/base_memory_service.js';\nimport {BasePlugin} from '../plugins/base_plugin.js';\nimport {PluginManager} from '../plugins/plugin_manager.js';\nimport {BaseSessionService} from '../sessions/base_session_service.js';\nimport {Session} from '../sessions/session.js';\nimport {logger} from '../utils/logger.js';\n\ninterface RunnerInput {\n appName: string;\n agent: BaseAgent;\n plugins?: BasePlugin[];\n artifactService?: BaseArtifactService;\n sessionService: BaseSessionService;\n memoryService?: BaseMemoryService;\n credentialService?: BaseCredentialService;\n}\n\nexport class Runner {\n readonly appName: string;\n readonly agent: BaseAgent;\n readonly pluginManager: PluginManager;\n readonly artifactService?: BaseArtifactService;\n readonly sessionService: BaseSessionService;\n readonly memoryService?: BaseMemoryService;\n readonly credentialService?: BaseCredentialService;\n\n constructor(input: RunnerInput) {\n this.appName = input.appName;\n this.agent = input.agent;\n this.pluginManager = new PluginManager(input.plugins ?? []);\n this.artifactService = input.artifactService;\n this.sessionService = input.sessionService;\n this.memoryService = input.memoryService;\n this.credentialService = input.credentialService;\n }\n\n /**\n * Runs the agent with the given message, and returns an async generator of\n * events.\n *\n * @param userId The user ID of the session.\n * @param sessionId The session ID of the session.\n * @param newMessage A new message to append to the session.\n * @param stateDelta An optional state delta to apply to the session.\n * @param runConfig The run config for the agent.\n * @yields The events generated by the agent.\n */\n // TODO - b/425992518: user, sessionId, and runConfig can be internalized.\n async * runAsync({\n userId,\n sessionId,\n newMessage,\n stateDelta,\n runConfig,\n }: {\n userId: string; sessionId: string; newMessage: Content;\n stateDelta?: Record<string, any>;\n runConfig?: RunConfig;\n }): AsyncGenerator<Event, void, undefined> {\n runConfig = createRunConfig(runConfig);\n // =========================================================================\n // Setup the session and invocation context\n // =========================================================================\n const span = trace.getTracer('gcp.vertex.agent').startSpan('invocation');\n try {\n const session =\n await this.sessionService.getSession({appName: this.appName, userId, sessionId});\n\n if (!session) {\n throw new Error(`Session not found: ${sessionId}`);\n }\n\n if (runConfig.supportCfc && this.agent instanceof LlmAgent) {\n const modelName = this.agent.canonicalModel.model;\n if (!modelName.startsWith('gemini-2')) {\n throw new Error(`CFC is not supported for model: ${\n modelName} in agent: ${this.agent.name}`);\n }\n }\n\n const invocationContext = new InvocationContext({\n artifactService: this.artifactService,\n sessionService: this.sessionService,\n memoryService: this.memoryService,\n credentialService: this.credentialService,\n invocationId: newInvocationContextId(),\n agent: this.agent,\n session,\n userContent: newMessage,\n runConfig,\n pluginManager: this.pluginManager,\n });\n\n // =========================================================================\n // Preprocess plugins on user message\n // =========================================================================\n const pluginUserMessage =\n await this.pluginManager.runOnUserMessageCallback({\n userMessage: newMessage,\n invocationContext,\n });\n if (pluginUserMessage) {\n newMessage = pluginUserMessage as Content;\n }\n\n // =========================================================================\n // Append user message to session\n // =========================================================================\n if (newMessage) {\n if (!newMessage.parts?.length) {\n throw new Error('No parts in the newMessage.');\n }\n\n // Directly saves the artifacts (if applicable) in the user message and\n // replaces the artifact data with a file name placeholder.\n // TODO - b/425992518: fix Runner<>>ArtifactService leaky abstraction.\n if (runConfig.saveInputBlobsAsArtifacts) {\n await this.saveArtifacts(\n invocationContext.invocationId, session.userId, session.id,\n newMessage);\n }\n // Append the user message to the session with optional state delta.\n await this.sessionService.appendEvent({\n session,\n event: createEvent({\n invocationId: invocationContext.invocationId,\n author: 'user',\n actions: stateDelta ? createEventActions({stateDelta}) : undefined,\n content: newMessage,\n }),\n });\n }\n\n // =========================================================================\n // Determine which agent should handle the workflow resumption.\n // =========================================================================\n invocationContext.agent =\n this.determineAgentForResumption(session, this.agent);\n\n // =========================================================================\n // Run the agent with the plugins (aka hooks to apply in the lifecycle)\n // =========================================================================\n // Step 1: Run the before_run callbacks to see if we should early exit.\n const beforeRunCallbackResponse =\n await this.pluginManager.runBeforeRunCallback({invocationContext});\n\n if (beforeRunCallbackResponse) {\n const earlyExitEvent = createEvent({\n invocationId: invocationContext.invocationId,\n author: 'model',\n content: beforeRunCallbackResponse,\n });\n // TODO: b/447446338 - In the future, do *not* save live call audio\n // content to session This is a feature in Python ADK\n await this.sessionService.appendEvent({session, event: earlyExitEvent});\n yield earlyExitEvent;\n\n } else {\n // Step 2: Otherwise continue with normal execution\n for await (const event of invocationContext.agent.runAsync(\n invocationContext)) {\n if (!event.partial) {\n await this.sessionService.appendEvent({session, event});\n }\n // Step 3: Run the on_event callbacks to optionally modify the event.\n const modifiedEvent = await this.pluginManager.runOnEventCallback(\n {invocationContext, event});\n if (modifiedEvent) {\n yield modifiedEvent;\n } else {\n yield event;\n }\n }\n }\n // Step 4: Run the after_run callbacks to optionally modify the context.\n await this.pluginManager.runAfterRunCallback({invocationContext});\n } finally {\n span.end();\n }\n }\n\n /**\n * Saves artifacts from the message parts and replaces the inline data with\n * a file name placeholder.\n *\n * @param invocationId The current invocation ID.\n * @param userId The user ID of the session.\n * @param sessionId The session ID of the session.\n * @param message The message containing parts to process.\n */\n private async saveArtifacts(\n invocationId: string, userId: string, sessionId: string,\n message: Content): Promise<void> {\n if (!this.artifactService || !message.parts?.length) {\n return;\n }\n\n for (let i = 0; i < message.parts.length; i++) {\n const part = message.parts[i];\n if (!part.inlineData) {\n continue;\n }\n const fileName = `artifact_${invocationId}_${i}`;\n // TODO - b/425992518: group appname, userId, sessionId as a key.\n await this.artifactService.saveArtifact({\n appName: this.appName,\n userId,\n sessionId,\n filename: fileName,\n artifact: part,\n });\n // TODO - b/425992518: potentially buggy if accidentally exposed to LLM.\n message.parts[i] = createPartFromText(\n `Uploaded file: ${fileName}. It is saved into artifacts`);\n }\n }\n\n /**\n * Determines the next agent to run to continue the session. This is primarily\n * used for session resumption.\n */\n // TODO - b/425992518: This is where LRO integration should happen.\n // Needs clean up before we can generalize it.\n private determineAgentForResumption(session: Session, rootAgent: BaseAgent):\n BaseAgent {\n // =========================================================================\n // Case 1: If the last event is a function response, this returns the\n // agent that made the original function call.\n // =========================================================================\n const event = findEventByLastFunctionResponseId(session.events);\n if (event && event.author) {\n return rootAgent.findAgent(event.author) || rootAgent;\n }\n\n // =========================================================================\n // Case 2: Otherwise, find the last agent that emitted a message and is\n // transferable across the agent tree.\n // =========================================================================\n // TODO - b/425992518: Optimize this, not going to work for long sessions.\n // TODO - b/425992518: The behavior is dynamic, needs better documentation.\n for (let i = session.events.length - 1; i >= 0; i--) {\n logger.info('event: ', JSON.stringify(session.events[i]));\n const event = session.events[i];\n if (event.author === 'user' || !event.author) {\n continue;\n }\n\n if (event.author === rootAgent.name) {\n return rootAgent;\n }\n\n const agent = rootAgent.findSubAgent(event.author!);\n if (!agent) {\n logger.warn(`Event from an unknown agent: ${event.author}, event id: ${\n event.id}`);\n continue;\n }\n if (this.isRoutableLlmAgent(agent)) {\n return agent;\n }\n }\n // =========================================================================\n // Case 3: default to root agent.\n // =========================================================================\n return rootAgent;\n }\n\n /**\n * Whether the agent to run can transfer to any other agent in the agent tree.\n *\n * An agent is transferable if:\n * - It is an instance of `LlmAgent`.\n * - All its ancestors are also transferable (i.e., they have\n * `disallowTransferToParent` set to false).\n *\n * @param agentToRun The agent to check for transferability.\n * @returns True if the agent can transfer, False otherwise.\n */\n private isRoutableLlmAgent(agentToRun: BaseAgent): boolean {\n let agent: BaseAgent|undefined = agentToRun;\n while (agent) {\n if (!(agent instanceof LlmAgent)) {\n return false;\n }\n if (agent.disallowTransferToParent) {\n return false;\n }\n agent = agent.parentAgent;\n }\n return true;\n }\n // TODO - b/425992518: Implement runLive and related methods.\n}\n\n/**\n * It iterates through the events in reverse order, and returns the event\n * containing a function call with a functionCall.id matching the\n * functionResponse.id from the last event in the session.\n */\n// TODO - b/425992518: a hack that used event log as transaction log. Fix.\nfunction findEventByLastFunctionResponseId(events: Event[]): Event|null {\n if (!events.length) {\n return null;\n }\n\n const lastEvent = events[events.length - 1];\n const functionCallId =\n lastEvent.content?.parts?.find((part) => part.functionResponse)\n ?.functionResponse?.id;\n if (!functionCallId) {\n return null;\n }\n\n // TODO - b/425992518: inefficient search, fix.\n for (let i = events.length - 2; i >= 0; i--) {\n const event = events[i];\n // Looking for the system long running request euc function call.\n const functionCalls = getFunctionCalls(event);\n if (!functionCalls) {\n continue;\n }\n\n for (const functionCall of functionCalls) {\n if (functionCall.id === functionCallId) {\n return event;\n }\n }\n }\n return null;\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {BaseAgent} from '../agents/base_agent.js';\nimport {InMemoryArtifactService} from '../artifacts/in_memory_artifact_service.js';\nimport {InMemoryMemoryService} from '../memory/in_memory_memory_service.js';\nimport {BasePlugin} from '../plugins/base_plugin.js';\nimport {InMemorySessionService} from '../sessions/in_memory_session_service.js';\n\nimport {Runner} from './runner.js';\n\nexport class InMemoryRunner extends Runner {\n constructor({\n agent,\n appName = 'InMemoryRunner',\n plugins = [],\n }: {agent: BaseAgent; appName?: string; plugins?: BasePlugin[];}) {\n super({\n appName,\n agent,\n plugins,\n artifactService: new InMemoryArtifactService(),\n sessionService: new InMemorySessionService(),\n memoryService: new InMemoryMemoryService(),\n });\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Content, FunctionDeclaration, Type} from '@google/genai';\n\nimport {BaseAgent} from '../agents/base_agent.js';\nimport {LlmAgent} from '../agents/llm_agent.js';\nimport {Event} from '../events/event.js';\nimport {InMemoryMemoryService} from '../memory/in_memory_memory_service.js';\nimport {Runner} from '../runner/runner.js';\nimport {InMemorySessionService} from '../sessions/in_memory_session_service.js';\nimport {GoogleLLMVariant} from '../utils/variant_utils.js';\n\nimport {BaseTool, RunAsyncToolRequest} from './base_tool.js';\nimport {ForwardingArtifactService} from './forwarding_artifact_service.js';\nimport {ToolContext} from './tool_context.js';\n\n/**\n * The configuration of the agent tool.\n */\nexport interface AgentToolConfig {\n /**\n * The reference to the agent instance.\n */\n agent: BaseAgent;\n\n /**\n * Whether to skip summarization of the agent output.\n */\n skipSummarization?: boolean;\n}\n\n/**\n * A tool that wraps an agent.\n *\n * This tool allows an agent to be called as a tool within a larger\n * application. The agent's input schema is used to define the tool's input\n * parameters, and the agent's output is returned as the tool's result.\n *\n * @param config: The configuration of the agent tool.\n */\nexport class AgentTool extends BaseTool {\n private readonly agent: BaseAgent;\n\n private readonly skipSummarization: boolean;\n\n constructor(config: AgentToolConfig) {\n super(\n {name: config.agent.name, description: config.agent.description || ''});\n this.agent = config.agent;\n this.skipSummarization = config.skipSummarization || false;\n }\n\n override _getDeclaration(): FunctionDeclaration {\n let declaration: FunctionDeclaration;\n\n if (this.agent instanceof LlmAgent && this.agent.inputSchema) {\n declaration = {\n name: this.name,\n description: this.description,\n // TODO(b/425992518): We should not use the agent's input schema as is.\n // It should be validated and possibly transformed. Consider similar\n // logic to one we have in Python ADK.\n parameters: this.agent.inputSchema,\n };\n } else {\n declaration = {\n name: this.name,\n description: this.description,\n parameters: {\n type: Type.OBJECT,\n properties: {\n 'request': {\n type: Type.STRING,\n },\n },\n required: ['request'],\n },\n };\n }\n\n if (this.apiVariant !== GoogleLLMVariant.GEMINI_API) {\n const hasOutputSchema =\n this.agent instanceof LlmAgent && this.agent.outputSchema;\n declaration.response =\n hasOutputSchema ? {type: Type.OBJECT} : {type: Type.STRING};\n }\n\n return declaration;\n }\n\n override async runAsync({args, toolContext}: RunAsyncToolRequest):\n Promise<unknown> {\n if (this.skipSummarization) {\n toolContext.actions.skipSummarization = true;\n }\n\n const hasInputSchema =\n this.agent instanceof LlmAgent && this.agent.inputSchema;\n const content: Content = {\n role: 'user',\n parts: [\n {\n // TODO(b/425992518): Should be validated. Consider similar\n // logic to one we have in Python ADK.\n text: hasInputSchema ? JSON.stringify(args) :\n args['request'] as string,\n },\n ],\n };\n\n const runner = new Runner({\n appName: this.agent.name,\n agent: this.agent,\n artifactService: new ForwardingArtifactService(toolContext),\n sessionService: new InMemorySessionService(),\n memoryService: new InMemoryMemoryService(),\n credentialService: toolContext.invocationContext.credentialService,\n });\n\n const session = await runner.sessionService.createSession({\n appName: this.agent.name,\n userId: 'tmp_user',\n state: toolContext.state.toRecord(),\n });\n\n let lastEvent: Event|undefined;\n for await (const event of runner.runAsync({\n userId: session.userId,\n sessionId: session.id,\n newMessage: content,\n })) {\n if (event.actions.stateDelta) {\n toolContext.state.update(event.actions.stateDelta);\n }\n\n lastEvent = event;\n }\n\n if (!lastEvent?.content?.parts?.length) {\n return '';\n }\n\n const hasOutputSchema =\n this.agent instanceof LlmAgent && this.agent.outputSchema;\n\n const mergetText = lastEvent.content.parts.map((part) => part.text)\n .filter((text) => text)\n .join('\\n');\n\n // TODO - b/425992518: In case of output schema, the output should be\n // validated. Consider similar logic to one we have in Python ADK.\n return hasOutputSchema ? JSON.parse(mergetText) : mergetText;\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Part} from '@google/genai';\n\nimport {InvocationContext} from '../agents/invocation_context.js';\nimport {BaseArtifactService, DeleteArtifactRequest, ListArtifactKeysRequest, ListVersionsRequest, LoadArtifactRequest, SaveArtifactRequest,} from '../artifacts/base_artifact_service.js';\n\nimport {ToolContext} from './tool_context.js';\n\n/**\n * Artifact service that forwards to the parent tool context.\n */\nexport class ForwardingArtifactService implements BaseArtifactService {\n private readonly invocationContext: InvocationContext;\n\n constructor(private readonly toolContext: ToolContext) {\n this.invocationContext = toolContext.invocationContext;\n }\n\n // TODO - b/425992518: Remove unnecessary parameters. We should rethink the\n // abstraction layer to make it more clear.\n async saveArtifact(request: SaveArtifactRequest): Promise<number> {\n return this.toolContext.saveArtifact(request.filename, request.artifact);\n }\n\n async loadArtifact(request: LoadArtifactRequest): Promise<Part|undefined> {\n return this.toolContext.loadArtifact(request.filename, request.version);\n }\n\n async listArtifactKeys(request: ListArtifactKeysRequest): Promise<string[]> {\n return this.toolContext.listArtifacts();\n }\n\n async deleteArtifact(request: DeleteArtifactRequest): Promise<void> {\n if (!this.toolContext.invocationContext.artifactService) {\n throw new Error('Artifact service is not initialized.');\n }\n\n return this.toolContext.invocationContext.artifactService.deleteArtifact(\n request);\n }\n\n async listVersions(request: ListVersionsRequest): Promise<number[]> {\n if (!this.toolContext.invocationContext.artifactService) {\n throw new Error('Artifact service is not initialized.');\n }\n\n return this.toolContext.invocationContext.artifactService.listVersions(\n request);\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {ReadonlyContext} from '../agents/readonly_context.js';\nimport {LlmRequest} from '../models/llm_request.js';\n\nimport {BaseTool} from './base_tool.js';\nimport {ToolContext} from './tool_context.js';\n\n/**\n * Function to decide whether a tool should be exposed to LLM. Toolset\n * implementer could consider whether to accept such instance in the toolset's\n * constructor and apply the predicate in getTools method.\n */\nexport type ToolPredicate =\n (tool: BaseTool, readonlyContext: ReadonlyContext) => boolean;\n\n/**\n * Base class for toolset.\n *\n * A toolset is a collection of tools that can be used by an agent.\n */\nexport abstract class BaseToolset {\n constructor(readonly toolFilter: ToolPredicate|string[]) {}\n\n /**\n * Returns the tools that should be exposed to LLM.\n *\n * @param context Context used to filter tools available to the agent. If\n * not defined, all tools in the toolset are returned.\n * @return A Promise that resolves to the list of tools.\n */\n abstract getTools(context?: ReadonlyContext): Promise<BaseTool[]>;\n\n /**\n * Closes the toolset.\n *\n * NOTE: This method is invoked, for example, at the end of an agent server's\n * lifecycle or when the toolset is no longer needed. Implementations\n * should ensure that any open connections, files, or other managed\n * resources are properly released to prevent leaks.\n *\n * @return A Promise that resolves when the toolset is closed.\n */\n abstract close(): Promise<void>;\n\n /**\n * Returns whether the tool should be exposed to LLM.\n *\n * @param tool The tool to check.\n * @param context Context used to filter tools available to the agent.\n * @return Whether the tool should be exposed to LLM.\n */\n protected isToolSelected(tool: BaseTool, context: ReadonlyContext): boolean {\n if (!this.toolFilter) {\n return true;\n }\n\n if (typeof this.toolFilter === 'function') {\n return this.toolFilter(tool, context);\n }\n\n if (Array.isArray(this.toolFilter)) {\n return (this.toolFilter as string[]).includes(tool.name);\n }\n\n return false;\n }\n\n /**\n * Processes the outgoing LLM request for this toolset. This method will be\n * called before each tool processes the llm request.\n *\n * Use cases:\n * - Instead of let each tool process the llm request, we can let the toolset\n * process the llm request. e.g. ComputerUseToolset can add computer use\n * tool to the llm request.\n *\n * @param toolContext The context of the tool.\n * @param llmRequest The outgoing LLM request, mutable this method.\n */\n async processLlmRequest(\n toolContext: ToolContext,\n llmRequest: LlmRequest,\n ): Promise<void> {}\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\nimport {GenerateContentConfig} from '@google/genai';\n\nimport {LlmRequest} from '../models/llm_request.js';\nimport {isGemini1Model, isGeminiModel} from '../utils/model_name.js';\n\nimport {BaseTool, RunAsyncToolRequest, ToolProcessLlmRequest} from './base_tool.js';\nimport {ToolContext} from './tool_context.js';\n\n/**\n * A built-in tool that is automatically invoked by Gemini 2 models to retrieve\n * search results from Google Search.\n *\n * This tool operates internally within the model and does not require or\n * perform local code execution.\n */\nclass GoogleSearchTool extends BaseTool {\n constructor() {\n super({name: 'google_search', description: 'Google Search Tool'});\n }\n\n runAsync(request: RunAsyncToolRequest): Promise<unknown> {\n // This is a built-in tool on server side, it's triggered by setting the\n // corresponding request parameters.\n return Promise.resolve();\n }\n\n override async processLlmRequest({toolContext, llmRequest}:\n ToolProcessLlmRequest):\n Promise<void> {\n if (!llmRequest.model) {\n return;\n }\n\n llmRequest.config = llmRequest.config || {} as GenerateContentConfig;\n llmRequest.config.tools = llmRequest.config.tools || [];\n\n if (isGemini1Model(llmRequest.model)) {\n if (llmRequest.config.tools.length > 0) {\n throw new Error(\n 'Google search tool can not be used with other tools in Gemini 1.x.',\n );\n }\n\n llmRequest.config.tools.push({\n googleSearchRetrieval: {},\n });\n\n return;\n }\n\n if (isGeminiModel(llmRequest.model)) {\n llmRequest.config.tools.push({\n googleSearch: {},\n });\n\n return;\n }\n\n throw new Error(\n `Google search tool is not supported for model ${llmRequest.model}`,\n );\n }\n}\n\n/**\n * A global instance of GoogleSearchTool.\n */\nexport const GOOGLE_SEARCH = new GoogleSearchTool();\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {FunctionDeclaration} from '@google/genai';\n\nimport {FunctionTool, ToolInputParameters, ToolOptions,} from './function_tool.js';\n\n/**\n * A function tool that returns the result asynchronously.\n *\n * This tool is used for long-running operations that may take a significant\n * amount of time to complete. The framework will call the function. Once the\n * function returns, the response will be returned asynchronously to the\n * framework which is identified by the function_call_id.\n */\n\nconst LONG_RUNNING_INSTRUCTION = `\n\nNOTE: This is a long-running operation. Do not call this tool again if it has already returned some intermediate or pending status.`;\n\nexport class LongRunningFunctionTool<\n TParameters extends ToolInputParameters = undefined,\n> extends FunctionTool<TParameters> {\n /**\n * The constructor acts as the user-friendly factory.\n * @param options The configuration for the tool.\n */\n constructor(options: ToolOptions<TParameters>) {\n super({...options, isLongRunning: true});\n }\n\n /**\n * Provide a schema for the function.\n */\n override _getDeclaration(): FunctionDeclaration {\n const declaration = super._getDeclaration();\n if (declaration.description) {\n declaration.description += LONG_RUNNING_INSTRUCTION;\n } else {\n declaration.description = LONG_RUNNING_INSTRUCTION.trimStart();\n }\n return declaration;\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Client} from '@modelcontextprotocol/sdk/client/index.js';\nimport {StdioClientTransport, StdioServerParameters} from '@modelcontextprotocol/sdk/client/stdio.js';\nimport {StreamableHTTPClientTransport} from '@modelcontextprotocol/sdk/client/streamableHttp.js';\n\n/**\n * Defines the parameters for establishing a connection to an MCP server using\n * standard input/output (stdio). This is typically used for running MCP servers\n * as local child processes.\n */\nexport interface StdioConnectionParams {\n type: 'StdioConnectionParams';\n serverParams: StdioServerParameters;\n timeout?: Number;\n}\n\n/**\n * Defines the parameters for establishing a connection to an MCP server over\n * HTTP using Server-Sent Events (SSE) for streaming.\n *\n * Usage:\n * const connectionParams: StreamableHTTPConnectionParams = {\n * type: 'StreamableHTTPConnectionParams',\n * url: 'http://localhost:8788/mcp'\n * };\n */\nexport interface StreamableHTTPConnectionParams {\n type: 'StreamableHTTPConnectionParams';\n url: string;\n header?: Record<string, unknown>;\n timeout?: Number;\n sseReadTimeout?: Number;\n terminateOnClose?: boolean;\n}\n\n/**\n * A union of all supported MCP connection parameter types.\n */\nexport type MCPConnectionParams =\n StdioConnectionParams|StreamableHTTPConnectionParams;\n\n/**\n * Manages Model Context Protocol (MCP) client sessions.\n *\n * This class is responsible for establishing and managing connections to MCP\n * servers. It supports different transport protocols like Standard I/O (Stdio)\n * and Server-Sent Events (SSE) over HTTP, determined by the provided\n * connection parameters.\n *\n * The primary purpose of this manager is to abstract away the details of\n * session creation and connection handling, providing a simple interface for\n * creating new MCP client instances that can be used to interact with\n * remote tools.\n */\nexport class MCPSessionManager {\n private readonly connectionParams: MCPConnectionParams;\n\n constructor(connectionParams: MCPConnectionParams) {\n this.connectionParams = connectionParams;\n }\n\n async createSession(): Promise<Client> {\n const client = new Client({name: 'MCPClient', version: '1.0.0'});\n\n switch (this.connectionParams.type) {\n case 'StdioConnectionParams':\n await client.connect(\n new StdioClientTransport(this.connectionParams.serverParams));\n break;\n case 'StreamableHTTPConnectionParams':\n await client.connect(new StreamableHTTPClientTransport(\n new URL(this.connectionParams.url)));\n break;\n default:\n // Triggers compile error if a case is missing.\n const _exhaustiveCheck: never = this.connectionParams;\n break;\n }\n\n return client;\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Schema, Type} from '@google/genai';\nimport {z} from 'zod';\n\nconst MCPToolSchema = z.object({\n type: z.literal('object'),\n properties: z.record(z.unknown()).optional(),\n required: z.string().array().optional(),\n});\ntype MCPToolSchema = z.infer<typeof MCPToolSchema>;\n\nfunction toGeminiType(mcpType: string): Type {\n switch (mcpType.toLowerCase()) {\n case 'text':\n case 'string':\n return Type.STRING;\n case 'number':\n return Type.NUMBER;\n case 'boolean':\n return Type.BOOLEAN;\n case 'integer':\n return Type.INTEGER;\n case 'array':\n return Type.ARRAY;\n case 'object':\n return Type.OBJECT;\n default:\n return Type.TYPE_UNSPECIFIED;\n }\n}\n\nexport function toGeminiSchema(mcpSchema?: MCPToolSchema): Schema|undefined {\n if (!mcpSchema) {\n return undefined;\n }\n\n function recursiveConvert(mcp: any): Schema {\n const geminiType = toGeminiType(mcp.type);\n const geminiSchema:\n Schema = {type: geminiType, description: mcp.description};\n\n if (geminiType === Type.OBJECT) {\n geminiSchema.properties = {};\n if (mcp.properties) {\n for (const name in mcp.properties) {\n geminiSchema.properties[name] =\n recursiveConvert(mcp.properties[name]);\n }\n }\n geminiSchema.required = mcp.required;\n } else if (geminiType === Type.ARRAY) {\n if (mcp.items) {\n geminiSchema.items = recursiveConvert(mcp.items);\n }\n }\n return geminiSchema;\n }\n return recursiveConvert(mcpSchema);\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {FunctionDeclaration} from '@google/genai';\nimport {CallToolRequest, CallToolResult, Tool} from '@modelcontextprotocol/sdk/types.js';\n\nimport {toGeminiSchema} from '../../utils/gemini_schema_util.js';\nimport {BaseTool, RunAsyncToolRequest} from '../base_tool.js';\n\nimport {MCPSessionManager} from './mcp_session_manager.js';\n\n/**\n * Represents a tool exposed via the Model Context Protocol (MCP).\n *\n * This class acts as a wrapper around a tool definition received from an MCP\n * server. It translates the MCP tool's schema into a format compatible with\n * the Gemini AI platform (FunctionDeclaration) and handles the remote\n * execution of the tool by communicating with the MCP server through an\n * {@link MCPSessionManager}.\n *\n * When an LLM decides to call this tool, the `runAsync` method will be\n * invoked, which in turn establishes an MCP session, sends a `callTool`\n * request with the provided arguments, and returns the result from the\n * remote tool.\n */\nexport class MCPTool extends BaseTool {\n private readonly mcpTool: Tool;\n private readonly mcpSessionManager: MCPSessionManager;\n\n constructor(mcpTool: Tool, mcpSessionManager: MCPSessionManager) {\n super({name: mcpTool.name, description: mcpTool.description || ''});\n this.mcpTool = mcpTool;\n this.mcpSessionManager = mcpSessionManager;\n }\n\n override _getDeclaration(): FunctionDeclaration {\n let declaration: FunctionDeclaration;\n declaration = {\n name: this.mcpTool.name,\n description: this.mcpTool.description,\n parameters: toGeminiSchema(this.mcpTool.inputSchema),\n // TODO: need revisit, refer to this\n // https://modelcontextprotocol.io/specification/2025-06-18/server/tools#tool-result\n response: toGeminiSchema(this.mcpTool.outputSchema),\n };\n return declaration;\n }\n\n override async runAsync(request: RunAsyncToolRequest): Promise<unknown> {\n const session = await this.mcpSessionManager.createSession();\n\n const callRequest: CallToolRequest = {} as CallToolRequest;\n callRequest.params = {name: this.mcpTool.name, arguments: request.args};\n\n return await session.callTool(callRequest.params) as CallToolResult;\n }\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {ListToolsResult} from '@modelcontextprotocol/sdk/types.js';\n\nimport {ReadonlyContext} from '../../agents/readonly_context.js';\nimport {logger} from '../../utils/logger.js';\nimport {BaseTool} from '../base_tool.js';\nimport {BaseToolset, ToolPredicate} from '../base_toolset.js';\n\nimport {MCPConnectionParams, MCPSessionManager} from './mcp_session_manager.js';\nimport {MCPTool} from './mcp_tool.js';\n\n/**\n * A toolset that dynamically discovers and provides tools from a Model Context\n * Protocol (MCP) server.\n *\n * This class connects to an MCP server, retrieves the list of available tools,\n * and wraps each of them in an {@link MCPTool} instance. This allows the agent\n * to seamlessly use tools from an external MCP-compliant service.\n *\n * The toolset can be configured with a filter to selectively expose a subset\n * of the tools provided by the MCP server.\n *\n * Usage:\n * import { MCPToolset } from '@paean-ai/adk';\n * import { StreamableHTTPConnectionParamsSchema } from '@paean-ai/adk';\n *\n * const connectionParams = StreamableHTTPConnectionParamsSchema.parse({\n * type: \"StreamableHTTPConnectionParams\",\n * url: \"http://localhost:8788/mcp\"\n * });\n *\n * const mcpToolset = new MCPToolset(connectionParams);\n * const tools = await mcpToolset.getTools();\n *\n */\nexport class MCPToolset extends BaseToolset {\n private readonly mcpSessionManager: MCPSessionManager;\n\n constructor(\n connectionParams: MCPConnectionParams,\n toolFilter: ToolPredicate|string[] = []) {\n super(toolFilter);\n this.mcpSessionManager = new MCPSessionManager(connectionParams);\n }\n\n async getTools(context?: ReadonlyContext): Promise<BaseTool[]> {\n const session = await this.mcpSessionManager.createSession();\n\n const listResult = await session.listTools() as ListToolsResult;\n logger.debug(`number of tools: ${listResult.tools.length}`)\n for (const tool of listResult.tools) {\n logger.debug(`tool: ${tool.name}`)\n }\n\n // TODO: respect context (e.g. tool filter)\n return listResult.tools.map(\n (tool) => new MCPTool(tool, this.mcpSessionManager));\n }\n\n async close(): Promise<void> {}\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Bucket, Storage} from '@google-cloud/storage';\nimport {createPartFromBase64, createPartFromText, Part} from '@google/genai';\n\nimport {BaseArtifactService, DeleteArtifactRequest, ListArtifactKeysRequest, ListVersionsRequest, LoadArtifactRequest, SaveArtifactRequest} from './base_artifact_service.js';\n\nexport class GcsArtifactService implements BaseArtifactService {\n private readonly bucket: Bucket;\n\n constructor(bucket: string) {\n this.bucket = new Storage().bucket(bucket);\n }\n\n async saveArtifact(request: SaveArtifactRequest): Promise<number> {\n const versions = await this.listVersions(request);\n const version = versions.length > 0 ? Math.max(...versions) + 1 : 0;\n const file = this.bucket.file(getFileName({\n ...request,\n version,\n }));\n\n if (request.artifact.inlineData) {\n await file.save(JSON.stringify(request.artifact.inlineData.data), {\n contentType: request.artifact.inlineData.mimeType,\n });\n\n return version;\n }\n\n if (request.artifact.text) {\n await file.save(request.artifact.text, {\n contentType: 'text/plain',\n });\n\n return version;\n }\n\n throw new Error('Artifact must have either inlineData or text.')\n }\n\n async loadArtifact(request: LoadArtifactRequest): Promise<Part|undefined> {\n let version = request.version;\n if (version === undefined) {\n const versions = await this.listVersions(request);\n\n if (versions.length === 0) {\n return undefined;\n }\n\n version = Math.max(...versions);\n }\n\n const file = this.bucket.file(getFileName({\n ...request,\n version,\n }));\n const [[metadata], [rawDataBuffer]] =\n await Promise.all([file.getMetadata(), file.download()]);\n\n if (metadata.contentType === 'text/plain') {\n return createPartFromText(rawDataBuffer.toString('utf-8'));\n }\n\n return createPartFromBase64(\n rawDataBuffer.toString('base64'), metadata.contentType!);\n }\n\n async listArtifactKeys(request: ListArtifactKeysRequest): Promise<string[]> {\n const fileNames: string[] = [];\n const sessionPrefix =\n `${request.appName}/${request.userId}/${request.sessionId}/`;\n const usernamePrefix = `${request.appName}/${request.userId}/user/`;\n const [\n [sessionFiles],\n [userSessionFiles],\n ] =\n await Promise.all([\n this.bucket.getFiles({prefix: sessionPrefix}),\n this.bucket.getFiles({prefix: usernamePrefix}),\n ]);\n\n for (const file of sessionFiles) {\n fileNames.push(file.name.split('/').pop()!);\n }\n for (const file of userSessionFiles) {\n fileNames.push(file.name.split('/').pop()!);\n }\n\n return fileNames.sort((a, b) => a.localeCompare(b));\n }\n\n async deleteArtifact(request: DeleteArtifactRequest): Promise<void> {\n const versions = await this.listVersions(request);\n\n await Promise.all(versions.map(version => {\n const file = this.bucket.file(getFileName({\n ...request,\n version,\n }));\n\n return file.delete();\n }));\n\n return\n }\n\n async listVersions(request: ListVersionsRequest): Promise<number[]> {\n const prefix = getFileName(request);\n const [files] = await this.bucket.getFiles({prefix});\n const versions = [];\n for (const file of files) {\n const version = file.name.split('/').pop()!;\n versions.push(parseInt(version, 10));\n }\n\n return versions\n }\n}\n\nfunction getFileName({\n appName,\n userId,\n sessionId,\n filename,\n version,\n}: LoadArtifactRequest): string {\n if (filename.startsWith('user:')) {\n return `${appName}/${userId}/user/${filename}/${version}`;\n }\n return `${appName}/${userId}/${sessionId}/${filename}/${version}`;\n}\n", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {trace, metrics} from '@opentelemetry/api';\nimport {logs} from '@opentelemetry/api-logs';\nimport {LoggerProvider, LogRecordProcessor, BatchLogRecordProcessor} from '@opentelemetry/sdk-logs';\nimport {MetricReader, MeterProvider, PeriodicExportingMetricReader} from '@opentelemetry/sdk-metrics';\nimport {detectResources, Resource} from '@opentelemetry/resources';\nimport {SpanProcessor, BatchSpanProcessor} from '@opentelemetry/sdk-trace-base';\nimport {NodeTracerProvider} from '@opentelemetry/sdk-trace-node';\nimport {OTLPTraceExporter} from '@opentelemetry/exporter-trace-otlp-http';\nimport {OTLPMetricExporter} from '@opentelemetry/exporter-metrics-otlp-http';\nimport {OTLPLogExporter} from '@opentelemetry/exporter-logs-otlp-http';\n\nexport interface OtelExportersConfig {\n enableTracing?: boolean;\n enableMetrics?: boolean;\n enableLogging?: boolean;\n}\n\n/**\n * Configuration hooks for OpenTelemetry setup.\n * \n * This interface defines the structure for configuring OpenTelemetry\n * components including span processors, metric readers, and log record processors.\n */\nexport interface OTelHooks {\n spanProcessors?: SpanProcessor[];\n metricReaders?: MetricReader[];\n logRecordProcessors?: LogRecordProcessor[];\n}\n\n/**\n * Sets up OTel providers if hooks for a given telemetry type were passed.\n *\n * Additionally adds generic OTLP exporters based on following env variables:\n * OTEL_EXPORTER_OTLP_ENDPOINT\n * OTEL_EXPORTER_OTLP_TRACES_ENDPOINT\n * OTEL_EXPORTER_OTLP_METRICS_ENDPOINT\n * OTEL_EXPORTER_OTLP_LOGS_ENDPOINT\n * See https://opentelemetry.io/docs/languages/sdk-configuration/otlp-exporter/\n * for how they are used.\n *\n * If a provider for a specific telemetry type was already globally set -\n * this function will not override it or register more exporters.\n *\n * @experimental (Experimental, subject to change)\n * \n * @param otelHooksToSetup per-telemetry-type processors and readers to be added\n * to OTel providers. If no hooks for a specific telemetry type are passed -\n * provider will not be set.\n * @param otelResource OTel resource to use in providers.\n * If empty - default OTel resource detection will be used.\n */\nexport function maybeSetOtelProviders(\n otelHooksToSetup: OTelHooks[] = [],\n otelResource?: Resource\n): void {\n const resource = otelResource || getOtelResource();\n const allHooks = [...otelHooksToSetup, getOtelExporters()];\n const spanProcessors = allHooks.flatMap(hooks => hooks.spanProcessors || []);\n const metricReaders = allHooks.flatMap(hooks => hooks.metricReaders || []);\n const logRecordProcessors = allHooks.flatMap(hooks => hooks.logRecordProcessors || []);\n\n if (spanProcessors.length > 0) {\n const tracerProvider = new NodeTracerProvider({\n resource,\n spanProcessors\n });\n tracerProvider.register();\n trace.setGlobalTracerProvider(tracerProvider);\n }\n\n if (metricReaders.length > 0) {\n const meterProvider = new MeterProvider({\n readers: metricReaders,\n resource,\n });\n metrics.setGlobalMeterProvider(meterProvider);\n }\n\n if (logRecordProcessors.length > 0) {\n const loggerProvider = new LoggerProvider({\n resource,\n processors: logRecordProcessors,\n });\n // logs is experimental, reference to https://open-telemetry.github.io/opentelemetry-js/modules/_opentelemetry_api-logs.html#alpha-software---use-at-your-own-risk\n logs.setGlobalLoggerProvider(loggerProvider);\n }\n}\n\n/**\n * Gets the OTel resource with environment variable detection.\n * \n * The resource detection populates resource labels from\n * environment variables like OTEL_SERVICE_NAME and OTEL_RESOURCE_ATTRIBUTES.\n * \n * @returns A Resource object with detected attributes\n */\nfunction getOtelResource(): Resource {\n return detectResources({\n detectors: [],\n });\n}\n\n/**\n * Gets OTel exporters configuration based on environment variables.\n * \n * @returns OtelExportersConfig with flags based on environment variables\n */\nfunction getOtelExportersConfig(): OtelExportersConfig {\n return {\n enableTracing: !!(process.env.OTEL_EXPORTER_OTLP_ENDPOINT || process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT),\n enableMetrics: !!(process.env.OTEL_EXPORTER_OTLP_ENDPOINT || process.env.OTEL_EXPORTER_OTLP_METRICS_ENDPOINT),\n enableLogging: !!(process.env.OTEL_EXPORTER_OTLP_ENDPOINT || process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT),\n };\n}\n\n/**\n * Gets OTel exporters based on configuration.\n * \n * @param config Configuration for which exporters to enable\n * @returns OTelHooks containing configured exporters\n */\nfunction getOtelExporters(config = getOtelExportersConfig()): OTelHooks {\n const { enableTracing, enableMetrics, enableLogging } = config;\n return {\n spanProcessors: enableTracing ? [new BatchSpanProcessor(new OTLPTraceExporter())] : [],\n metricReaders: enableMetrics ? [new PeriodicExportingMetricReader({ exporter: new OTLPMetricExporter() })] : [],\n logRecordProcessors: enableLogging ? [new BatchLogRecordProcessor(new OTLPLogExporter())] : [],\n };\n}", "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {GoogleAuth} from 'google-auth-library';\nimport {PeriodicExportingMetricReader} from '@opentelemetry/sdk-metrics';\nimport {detectResources, Resource} from '@opentelemetry/resources';\nimport {gcpDetector} from '@opentelemetry/resource-detector-gcp';\nimport {TraceExporter} from '@google-cloud/opentelemetry-cloud-trace-exporter';\nimport {BatchSpanProcessor} from '@opentelemetry/sdk-trace-base';\nimport {MetricExporter} from '@google-cloud/opentelemetry-cloud-monitoring-exporter';\n\nimport {logger} from '../utils/logger.js';\n\nimport {OtelExportersConfig, OTelHooks} from './setup.js';\n\nconst GCP_PROJECT_ERROR_MESSAGE = \n 'Cannot determine GCP Project. OTel GCP Exporters cannot be set up. ' +\n 'Please make sure to log into correct GCP Project.';\n\nasync function getGcpProjectId(): Promise<string | undefined> {\n try {\n const auth = new GoogleAuth();\n const projectId = await auth.getProjectId();\n return projectId || undefined;\n } catch (error) {\n return undefined;\n }\n}\n\nexport async function getGcpExporters(config: OtelExportersConfig = {}): Promise<OTelHooks> {\n const {\n enableTracing = false,\n enableMetrics = false,\n // enableCloudLogging = false,\n } = config;\n\n const projectId = await getGcpProjectId();\n if (!projectId) {\n logger.warn(GCP_PROJECT_ERROR_MESSAGE);\n return {};\n }\n\n return {\n spanProcessors: enableTracing ? [\n new BatchSpanProcessor(new TraceExporter({ projectId })),\n ] : [],\n metricReaders: enableMetrics ? [\n new PeriodicExportingMetricReader({\n exporter: new MetricExporter({ projectId }),\n exportIntervalMillis: 5000,\n }),\n ] : [],\n logRecordProcessors: [],\n };\n}\n\nexport function getGcpResource(): Resource {\n return detectResources({ detectors: [gcpDetector] });\n}"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["trace", "createEventActions", "state", "mergeEventActions", "sources", "target", "result", "source", "createEvent", "params", "createNewEventId", "createEventActions", "isFinalResponse", "event", "getFunctionCalls", "getFunctionResponses", "hasTrailingCodeExecutionResult", "funcCalls", "part", "funcResponses", "_a", "stringifyContent", "ASCII_LETTERS_AND_NUMBERS", "id", "i", "State", "value", "delta", "key", "defaultValue", "ReadonlyContext", "invocationContext", "State", "CallbackContext", "ReadonlyContext", "invocationContext", "eventActions", "createEventActions", "State", "filename", "version", "artifact", "isBrowser", "UUID_MASK", "randomUUID", "uuid", "i", "randomValue", "base64Decode", "data", "isBrowser", "InvocationCostManager", "runConfig", "InvocationContext", "params", "newInvocationContextId", "randomUUID", "BaseAgent", "config", "validateAgentName", "getRootAgent", "getCannonicalCallback", "parentContext", "span", "trace", "context", "beforeAgentCallbackEvent", "event", "afterAgentCallbackEvent", "name", "subAgent", "result", "InvocationContext", "invocationContext", "callbackContext", "CallbackContext", "callback", "content", "createEvent", "isIdentifier", "str", "rootAgent", "callbacks", "createUserContent", "AuthHandler", "authConfig", "state", "credentialKey", "_a", "_b", "authSchemeType", "ToolConfirmation", "hint", "confirmed", "payload", "ToolContext", "CallbackContext", "invocationContext", "eventActions", "functionCallId", "toolConfirmation", "authConfig", "authHandler", "AuthHandler", "query", "hint", "payload", "ToolConfirmation", "LogLevel", "logLevel", "setLogLevel", "level", "SimpleLogger", "args", "getColoredPrefix", "LOG_LEVEL_STR", "CONSOLE_COLOR_MAP", "RESET_COLOR", "logger", "AF_FUNCTION_CALL_ID_PREFIX", "REQUEST_EUC_FUNCTION_CALL_NAME", "REQUEST_CONFIRMATION_FUNCTION_CALL_NAME", "functionsExportedForTestingOnly", "handleFunctionCallList", "generateClientFunctionCallId", "randomUUID", "populateClientFunctionCallId", "modelResponseEvent", "functionCalls", "getFunctionCalls", "functionCall", "removeClientFunctionCallId", "content", "part", "getLongRunningFunctionCalls", "toolsDict", "longRunningToolIds", "generateAuthEvent", "invocationContext", "functionResponseEvent", "_a", "parts", "functionCallId", "authConfig", "requestEucFunctionCall", "createEvent", "generateRequestConfirmationEvent", "functionCallEvent", "_b", "toolConfirmation", "originalFunctionCall", "call", "requestConfirmationFunctionCall", "callToolAsync", "tool", "args", "toolContext", "logger", "handleFunctionCallsAsync", "beforeToolCallbacks", "afterToolCallbacks", "filters", "toolConfirmationDict", "functionResponseEvents", "filteredFunctionCalls", "getToolAndContext", "functionArgs", "functionResponse", "functionResponseError", "callback", "e", "onToolErrorResponse", "alteredFunctionResponse", "createUserContent", "mergedEvent", "mergeParallelFunctionResponseEvents", "ToolContext", "mergedParts", "event", "baseEvent", "actionsList", "mergedActions", "mergeEventActions", "LiveRequestQueue", "req", "resolve", "closeRequest", "content", "blob", "request", "z", "BaseCodeExecutor", "MODEL_NAME_PATTERN", "extractModelName", "modelString", "match", "isGeminiModel", "isGemini1Model", "isGemini2Model", "isGemini3PreviewModel", "modelString", "modelName", "extractModelName", "BuiltInCodeExecutor", "BaseCodeExecutor", "params", "llmRequest", "isGemini2Model", "Language", "Outcome", "deepClone", "obj", "extractCodeAndTruncateContent", "content", "codeBlockDelimiters", "_a", "i", "part", "textParts", "firstTextPart", "deepClone", "responseText", "leadingDelimiterPattern", "d", "trailingDelimiterPattern", "match", "prefix", "codeStr", "buildExecutableCodePart", "code", "Language", "buildCodeExecutionResultPart", "codeExecutionResult", "Outcome", "finalResult", "f", "convertCodeExecutionParts", "codeBlockDelimiter", "executionResultDelimiters", "lastPart", "CONTEXT_KEY", "SESSION_ID_KEY", "PROCESSED_FILE_NAMES_KEY", "INPUT_FILE_KEY", "ERROR_COUNT_KEY", "CODE_EXECUTION_RESULTS_KEY", "CodeExecutorContext", "sessionState", "_a", "deepClone", "executionId", "fileNames", "inputFiles", "invocationId", "errorCounts", "code", "resultStdout", "resultStderr", "codeExecutionResults", "version", "ADK_LABEL", "LANGUAGE_LABEL", "AGENT_ENGINE_TELEMETRY_TAG", "AGENT_ENGINE_TELEMETRY_ENV_VARIABLE_NAME", "_getDefaultLabels", "frameworkLabel", "version", "isBrowser", "languageLabel", "getClientLabels", "BASE_MODEL_SYMBOL", "isBaseLlm", "obj", "_a", "BaseLlm", "model", "headerValue", "getClientLabels", "llmRequest", "appendInstructions", "llmRequest", "instructions", "newInstructions", "setOutputSchema", "llmRequest", "schema", "createPartFromText", "FinishReason", "GoogleGenAI", "getGoogleLlmVariant", "getBooleanEnvVar", "envVar", "envVarValue", "GeminiLlmConnection", "geminiSession", "history", "contents", "content", "_a", "logger", "functionResponses", "part", "fr", "blob", "text", "createLlmResponse", "response", "_a", "usageMetadata", "candidate", "GEMINI3_PREVIEW_API_ENDPOINT", "Gemini", "BaseLlm", "model", "apiKey", "vertexai", "project", "location", "headers", "apiEndpoint", "isGemini3PreviewModel", "canReadEnv", "logger", "useVertexAI", "vertexAIfromEnv", "availableApiKey", "llmRequest", "stream", "_a", "_b", "_c", "_d", "_e", "_f", "_g", "_h", "_i", "_j", "_k", "streamResult", "thoughtText", "thoughtSignature", "text", "usageMetadata", "lastResponse", "response", "llmResponse", "createLlmResponse", "firstPart", "parts", "thoughtPart", "createPartFromText", "part", "FinishReason", "thoughtSig", "combinedHeaders", "GoogleGenAI", "httpOptions", "liveSession", "GeminiLlmConnection", "content", "removeDisplayNameIfPresent", "dataObj", "LRUCache", "maxSize", "key", "item", "value", "lruKey", "_LLMRegistry", "model", "modelNameRegex", "llmCls", "logger", "regex", "cachedLlm", "llmClass", "LLMRegistry", "Gemini", "BaseTool", "params", "_a", "toolContext", "llmRequest", "functionDeclaration", "tool", "findToolWithFunctionDeclarations", "getGoogleLlmVariant", "Type", "ZodObject", "Type", "z", "isZodObject", "obj", "_a", "parseZodType", "zodType", "def", "description", "result", "returnResult", "check", "zodObjectToSchema", "literalType", "nullableInner", "defaultInner", "schema", "shape", "properties", "required", "key", "fieldSchema", "parsedField", "currentSchema", "isOptional", "catchall", "additionalProperties", "toSchema", "parameters", "Type", "isZodObject", "zodObjectToSchema", "FunctionTool", "BaseTool", "options", "_a", "name", "req", "validatedArgs", "ZodObject", "error", "errorMessage", "BaseLlmRequestProcessor", "getContents", "events", "agentName", "currentBranch", "_a", "_b", "filteredEvents", "event", "isAuthEvent", "isToolConfirmationEvent", "isEventFromAnotherAgent", "convertForeignEvent", "resultEvents", "rearrangeEventsForLatestFunctionResponse", "rearrangeEventsForAsyncFunctionResponsesInHistory", "contents", "content", "deepClone", "removeClientFunctionCallId", "getCurrentTurnContents", "i", "_c", "part", "REQUEST_EUC_FUNCTION_CALL_NAME", "REQUEST_CONFIRMATION_FUNCTION_CALL_NAME", "_d", "_e", "_f", "argsText", "safeStringify", "responseText", "createEvent", "mergeFunctionResponseEvents", "mergedEvent", "partsInMergedEvent", "partIndicesInMergedEvent", "functionCallId", "latestEvent", "functionResponses", "getFunctionResponses", "functionResponsesIds", "response", "secondLatestEvent", "functionCallsFromSecondLatest", "getFunctionCalls", "functionCall", "functionCallEventIdx", "idx", "functionCalls", "functionCallIds", "fc", "id", "functionResponseEvents", "responses", "functionCallIdToResponseEventIndex", "functionResponse", "functionResponseEventsIndices", "responseIndex", "eventsToMerge", "b", "index", "obj", "injectSessionState", "template", "readonlyContext", "invocationContext", "replaceMatchedKeyWithItsValue", "match", "key", "isOptional", "fileName", "artifact", "isValidStateName", "pattern", "result", "lastEnd", "matches", "replacement", "isIdentifierPattern", "isIdentifier", "s", "VALID_PREFIXES", "State", "variableName", "parts", "StreamingMode", "createRunConfig", "params", "validateMaxLlmCalls", "value", "logger", "ADK_AGENT_NAME_LABEL_KEY", "convertToolUnionToTools", "toolUnion", "context", "BaseTool", "BasicLlmRequestProcessor", "BaseLlmRequestProcessor", "invocationContext", "llmRequest", "_a", "agent", "LlmAgent", "setOutputSchema", "BASIC_LLM_REQUEST_PROCESSOR", "IdentityLlmRequestProcessor", "si", "appendInstructions", "IDENTITY_LLM_REQUEST_PROCESSOR", "InstructionsLlmRequestProcessor", "rootAgent", "instruction", "requireStateInjection", "ReadonlyContext", "instructionWithState", "injectSessionState", "INSTRUCTIONS_LLM_REQUEST_PROCESSOR", "ContentRequestProcessor", "getContents", "getCurrentTurnContents", "CONTENT_REQUEST_PROCESSOR", "AgentTransferLlmRequestProcessor", "FunctionTool", "z", "args", "toolContext", "transferTargets", "ToolContext", "targetAgent", "targetAgents", "instructions", "targets", "peerAgent", "AGENT_TRANSFER_LLM_REQUEST_PROCESSOR", "RequestConfirmationLlmRequestProcessor", "events", "requestConfirmationFunctionResponses", "confirmationEventIndex", "i", "event", "responses", "getFunctionResponses", "foundConfirmation", "functionResponse", "REQUEST_CONFIRMATION_FUNCTION_CALL_NAME", "toolConfirmation", "ToolConfirmation", "functionCalls", "getFunctionCalls", "toolsToResumeWithConfirmation", "toolsToResumeWithArgs", "functionCall", "originalFunctionCall", "j", "eventToCheck", "functionResponses", "fr", "toolsList", "toolsDict", "tool", "functionResponseEvent", "handleFunctionCallList", "REQUEST_CONFIRMATION_LLM_REQUEST_PROCESSOR", "CodeExecutionRequestProcessor", "runPreProcessor", "BaseCodeExecutor", "content", "delimeters", "codeExecutionParts", "convertCodeExecutionParts", "DATA_FILE_UTIL_MAP", "DATA_FILE_HELPER_LIB", "CodeExecutionResponseProcessor", "llmResponse", "runPostProcessor", "responseProcessor", "codeExecutor", "BuiltInCodeExecutor", "codeExecutorContext", "CodeExecutorContext", "State", "allInputFiles", "extractAndReplaceInlineFiles", "processedFileNames", "filesToProcess", "f", "file", "codeStr", "getDataFilePreprocessingCode", "codeContent", "buildExecutableCodePart", "deepClone", "createEvent", "executionId", "getOrSetExecutionId", "codeExecutionResult", "executionResultEvent", "postProcessCodeExecutionResult", "responseContent", "extractCodeAndTruncateContent", "savedFileNames", "part", "mimeType", "fileName", "base64Decode", "resultContent", "buildCodeExecutionResultPart", "eventActions", "createEventActions", "outputFile", "version", "getNormalizedFileName", "varName", "normalizedName", "loaderCode", "CODE_EXECUTION_REQUEST_PROCESSOR", "_LlmAgent", "BaseAgent", "config", "_b", "_c", "_d", "_e", "_f", "_g", "_h", "_i", "logger", "isBaseLlm", "LLMRegistry", "ancestorAgent", "resolvedTools", "tools", "callback", "isFinalResponse", "resultStr", "result", "e", "lastEvent", "processor", "modelResponseEvent", "createNewEventId", "mergedEvent", "populateClientFunctionCallId", "getLongRunningFunctionCalls", "handleFunctionCallsAsync", "authEvent", "generateAuthEvent", "toolConfirmationEvent", "generateRequestConfirmationEvent", "nextAgentName", "nextAgent", "agentName", "agentToRun", "beforeModelResponse", "llm", "responsesGenerator", "alteredLlmResponse", "callbackContext", "CallbackContext", "beforeModelCallbackResponse", "callbackResponse", "afterModelCallbackResponse", "responseGenerator", "response", "modelError", "onModelErrorCallbackResponse", "errorResponse", "LoopAgent", "BaseAgent", "config", "_a", "context", "iteration", "subAgent", "shouldExit", "event", "ParallelAgent", "BaseAgent", "context", "agentRuns", "subAgent", "createBranchCtxForSubAgent", "event", "mergeAgentRuns", "agent", "originalContext", "invocationContext", "InvocationContext", "branchSuffix", "pendingPromises", "index", "generator", "promise", "result", "nextPromise", "TASK_COMPLETED_TOOL_NAME", "SequentialAgent", "BaseAgent", "context", "subAgent", "event", "LlmAgent", "ReadonlyContext", "tool", "FunctionTool", "InMemoryArtifactService", "appName", "userId", "sessionId", "filename", "artifact", "path", "artifactPath", "version", "versions", "sessionPrefix", "usernamespacePrefix", "filenames", "artifacts", "i", "fileHasUserNamespace", "InMemoryMemoryService", "session", "userKey", "getUserKey", "event", "_a", "_b", "_c", "req", "wordsInQuery", "response", "sessionEvents", "joinedText", "part", "text", "wordsInEvent", "extractWordsLower", "queryWord", "formatTimestamp", "appName", "userId", "match", "timestamp", "BasePlugin", "name", "invocationContext", "userMessage", "event", "agent", "callbackContext", "llmRequest", "llmResponse", "error", "tool", "toolArgs", "toolContext", "result", "LoggingPlugin", "BasePlugin", "name", "invocationContext", "userMessage", "_a", "event", "isFinalResponse", "functionCalls", "getFunctionCalls", "funcCalls", "fc", "functionResponses", "getFunctionResponses", "funcResponses", "fr", "agent", "callbackContext", "llmRequest", "sysInstruction", "toolNames", "llmResponse", "tool", "toolArgs", "toolContext", "result", "error", "message", "formattedMessage", "logger", "content", "maxLength", "parts", "part", "text", "args", "formatted", "PluginManager", "plugins", "plugin", "p", "logger", "pluginName", "callback", "callbackName", "result", "e", "errorMessage", "userMessage", "invocationContext", "event", "agent", "callbackContext", "tool", "toolArgs", "toolContext", "llmRequest", "error", "llmResponse", "REQUEST_CONFIRMATION_FUNCTION_CALL_NAME", "TOOL_CALL_SECURITY_CHECK_STATES", "INTERMEDIATE_REQUIRE_TOOL_CALL_CONFIRMATION_ERROR", "PolicyOutcome", "InMemoryPolicyEngine", "context", "SecurityPlugin", "BasePlugin", "params", "_a", "tool", "toolArgs", "toolContext", "toolCallCheckState", "functionCallId", "state", "toolCallStates", "policyCheckResult", "getAskUserConfirmationFunctionCalls", "event", "results", "part", "BaseSessionService", "session", "event", "key", "value", "State", "createSession", "params", "InMemorySessionService", "BaseSessionService", "appName", "userId", "state", "sessionId", "session", "createSession", "randomUUID", "deepClone", "config", "copiedSession", "i", "sessionsWithoutEvents", "event", "warning", "message", "logger", "key", "State", "storageSession", "createPartFromText", "trace", "Runner", "input", "_a", "PluginManager", "userId", "sessionId", "newMessage", "stateDelta", "runConfig", "createRunConfig", "span", "trace", "session", "LlmAgent", "modelName", "invocationContext", "InvocationContext", "newInvocationContextId", "pluginUserMessage", "createEvent", "createEventActions", "beforeRunCallbackResponse", "earlyExitEvent", "event", "modifiedEvent", "invocationId", "message", "i", "part", "fileName", "createPartFromText", "rootAgent", "findEventByLastFunctionResponseId", "logger", "agent", "agentToRun", "events", "_b", "_c", "_d", "functionCallId", "functionCalls", "getFunctionCalls", "functionCall", "InMemoryRunner", "Runner", "agent", "appName", "plugins", "InMemoryArtifactService", "InMemorySessionService", "InMemoryMemoryService", "Type", "ForwardingArtifactService", "toolContext", "request", "AgentTool", "BaseTool", "config", "declaration", "LlmAgent", "Type", "hasOutputSchema", "args", "toolContext", "_a", "_b", "content", "runner", "Runner", "ForwardingArtifactService", "InMemorySessionService", "InMemoryMemoryService", "session", "lastEvent", "event", "mergetText", "part", "text", "BaseToolset", "toolFilter", "tool", "context", "toolContext", "llmRequest", "GoogleSearchTool", "BaseTool", "request", "toolContext", "llmRequest", "isGemini1Model", "isGeminiModel", "GOOGLE_SEARCH", "LONG_RUNNING_INSTRUCTION", "LongRunningFunctionTool", "FunctionTool", "options", "declaration", "Client", "StdioClientTransport", "StreamableHTTPClientTransport", "MCPSessionManager", "connectionParams", "client", "_exhaustiveCheck", "Type", "z", "MCPToolSchema", "toGeminiType", "mcpType", "toGeminiSchema", "mcpSchema", "recursiveConvert", "mcp", "geminiType", "geminiSchema", "name", "MCPTool", "BaseTool", "mcpTool", "mcpSessionManager", "declaration", "toGeminiSchema", "request", "session", "callRequest", "MCPToolset", "BaseToolset", "connectionParams", "toolFilter", "MCPSessionManager", "context", "listResult", "logger", "tool", "MCPTool", "Storage", "createPartFromBase64", "createPartFromText", "GcsArtifactService", "bucket", "request", "versions", "version", "file", "getFileName", "metadata", "rawDataBuffer", "fileNames", "sessionPrefix", "usernamePrefix", "sessionFiles", "userSessionFiles", "a", "b", "prefix", "files", "appName", "userId", "sessionId", "filename", "trace", "metrics", "logs", "LoggerProvider", "BatchLogRecordProcessor", "MeterProvider", "PeriodicExportingMetricReader", "detectResources", "BatchSpanProcessor", "NodeTracerProvider", "OTLPTraceExporter", "OTLPMetricExporter", "OTLPLogExporter", "maybeSetOtelProviders", "otelHooksToSetup", "otelResource", "resource", "getOtelResource", "allHooks", "getOtelExporters", "spanProcessors", "hooks", "metricReaders", "logRecordProcessors", "tracerProvider", "meterProvider", "loggerProvider", "getOtelExportersConfig", "config", "enableTracing", "enableMetrics", "enableLogging", "GoogleAuth", "PeriodicExportingMetricReader", "detectResources", "gcpDetector", "TraceExporter", "BatchSpanProcessor", "MetricExporter", "GCP_PROJECT_ERROR_MESSAGE", "getGcpProjectId", "GoogleAuth", "getGcpExporters", "config", "enableTracing", "enableMetrics", "projectId", "BatchSpanProcessor", "TraceExporter", "PeriodicExportingMetricReader", "MetricExporter", "logger", "getGcpResource", "detectResources", "gcpDetector"]
|
|
7
7
|
}
|