@google/adk 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cjs/a2a/a2a_event.js +317 -0
- package/dist/cjs/a2a/a2a_remote_agent.js +174 -0
- package/dist/cjs/a2a/a2a_remote_agent_run_processor.js +198 -0
- package/dist/cjs/a2a/a2a_remote_agent_utils.js +165 -0
- package/dist/cjs/a2a/agent_card.js +380 -0
- package/dist/cjs/a2a/agent_executor.js +221 -0
- package/dist/cjs/a2a/agent_to_a2a.js +115 -0
- package/dist/cjs/a2a/event_converter_utils.js +201 -0
- package/dist/cjs/a2a/event_processor_utils.js +180 -0
- package/dist/cjs/a2a/executor_context.js +53 -0
- package/dist/cjs/a2a/metadata_converter_utils.js +126 -0
- package/dist/cjs/a2a/part_converter_utils.js +47 -34
- package/dist/cjs/agents/base_agent.js +3 -3
- package/dist/cjs/{tools/tool_context.js → agents/context.js} +70 -15
- package/dist/cjs/agents/functions.js +2 -2
- package/dist/cjs/agents/llm_agent.js +38 -674
- package/dist/cjs/agents/processors/agent_transfer_llm_request_processor.js +132 -0
- package/dist/cjs/agents/processors/basic_llm_request_processor.js +68 -0
- package/dist/cjs/agents/processors/code_execution_request_processor.js +389 -0
- package/dist/cjs/agents/{content_processor_utils.js → processors/content_processor_utils.js} +21 -2
- package/dist/cjs/agents/processors/content_request_processor.js +87 -0
- package/dist/cjs/agents/processors/context_compactor_request_processor.js +61 -0
- package/dist/cjs/agents/processors/identity_llm_request_processor.js +54 -0
- package/dist/cjs/agents/processors/instructions_llm_request_processor.js +85 -0
- package/dist/cjs/agents/processors/request_confirmation_llm_request_processor.js +165 -0
- package/dist/cjs/artifacts/file_artifact_service.js +35 -4
- package/dist/cjs/common.js +48 -7
- package/dist/cjs/context/base_context_compactor.js +27 -0
- package/dist/cjs/context/summarizers/base_summarizer.js +27 -0
- package/dist/cjs/context/summarizers/llm_summarizer.js +93 -0
- package/dist/cjs/context/token_based_context_compactor.js +135 -0
- package/dist/cjs/context/truncating_context_compactor.js +58 -0
- package/dist/cjs/events/compacted_event.js +53 -0
- package/dist/cjs/index.js +113 -53
- package/dist/cjs/index.js.map +7 -0
- package/dist/cjs/memory/in_memory_memory_service.js +1 -1
- package/dist/cjs/models/llm_response.js +2 -0
- package/dist/cjs/plugins/base_plugin.js +1 -1
- package/dist/cjs/runner/runner.js +20 -11
- package/dist/cjs/sessions/database_session_service.js +4 -1
- package/dist/cjs/sessions/db/operations.js +25 -23
- package/dist/cjs/sessions/state.js +2 -2
- package/dist/cjs/tools/agent_tool.js +6 -5
- package/dist/cjs/tools/base_tool.js +3 -0
- package/dist/cjs/tools/base_toolset.js +13 -3
- package/dist/cjs/tools/exit_loop_tool.js +63 -0
- package/dist/cjs/tools/load_artifacts_tool.js +188 -0
- package/dist/cjs/tools/load_memory_tool.js +107 -0
- package/dist/cjs/tools/mcp/mcp_toolset.js +9 -5
- package/dist/cjs/tools/preload_memory_tool.js +109 -0
- package/dist/cjs/utils/logger.js +62 -54
- package/dist/cjs/version.js +1 -1
- package/dist/esm/a2a/a2a_event.js +269 -0
- package/dist/esm/a2a/a2a_remote_agent.js +148 -0
- package/dist/esm/a2a/a2a_remote_agent_run_processor.js +175 -0
- package/dist/esm/a2a/a2a_remote_agent_utils.js +131 -0
- package/dist/esm/a2a/agent_card.js +340 -0
- package/dist/esm/a2a/agent_executor.js +202 -0
- package/dist/esm/a2a/agent_to_a2a.js +80 -0
- package/dist/esm/a2a/event_converter_utils.js +187 -0
- package/dist/esm/a2a/event_processor_utils.js +159 -0
- package/dist/esm/a2a/executor_context.js +23 -0
- package/dist/esm/a2a/metadata_converter_utils.js +91 -0
- package/dist/esm/a2a/part_converter_utils.js +49 -34
- package/dist/esm/agents/base_agent.js +3 -3
- package/dist/{web/tools/tool_context.js → esm/agents/context.js} +66 -11
- package/dist/esm/agents/functions.js +2 -2
- package/dist/esm/agents/llm_agent.js +31 -683
- package/dist/esm/agents/processors/agent_transfer_llm_request_processor.js +101 -0
- package/dist/esm/agents/processors/basic_llm_request_processor.js +37 -0
- package/dist/esm/agents/processors/code_execution_request_processor.js +363 -0
- package/dist/esm/agents/{content_processor_utils.js → processors/content_processor_utils.js} +23 -2
- package/dist/esm/agents/processors/content_request_processor.js +59 -0
- package/dist/esm/agents/processors/context_compactor_request_processor.js +31 -0
- package/dist/esm/agents/processors/identity_llm_request_processor.js +23 -0
- package/dist/esm/agents/processors/instructions_llm_request_processor.js +54 -0
- package/dist/esm/agents/processors/request_confirmation_llm_request_processor.js +140 -0
- package/dist/esm/artifacts/file_artifact_service.js +30 -3
- package/dist/esm/common.js +44 -10
- package/dist/esm/context/base_context_compactor.js +5 -0
- package/dist/esm/context/summarizers/base_summarizer.js +5 -0
- package/dist/esm/context/summarizers/llm_summarizer.js +65 -0
- package/dist/esm/context/token_based_context_compactor.js +105 -0
- package/dist/esm/context/truncating_context_compactor.js +28 -0
- package/dist/esm/events/compacted_event.js +22 -0
- package/dist/esm/index.js +119 -18
- package/dist/esm/index.js.map +7 -0
- package/dist/esm/memory/in_memory_memory_service.js +1 -1
- package/dist/esm/models/llm_response.js +2 -0
- package/dist/esm/plugins/base_plugin.js +1 -1
- package/dist/esm/runner/runner.js +18 -10
- package/dist/esm/sessions/database_session_service.js +4 -1
- package/dist/esm/sessions/db/operations.js +32 -18
- package/dist/esm/sessions/state.js +2 -2
- package/dist/esm/tools/agent_tool.js +6 -5
- package/dist/esm/tools/base_tool.js +3 -0
- package/dist/esm/tools/base_toolset.js +11 -2
- package/dist/esm/tools/exit_loop_tool.js +32 -0
- package/dist/esm/tools/load_artifacts_tool.js +159 -0
- package/dist/esm/tools/load_memory_tool.js +78 -0
- package/dist/esm/tools/mcp/mcp_toolset.js +9 -5
- package/dist/esm/tools/preload_memory_tool.js +80 -0
- package/dist/esm/utils/logger.js +52 -54
- package/dist/esm/version.js +1 -1
- package/dist/types/a2a/a2a_event.d.ts +139 -0
- package/dist/types/a2a/a2a_remote_agent.d.ts +63 -0
- package/dist/types/a2a/a2a_remote_agent_run_processor.d.ts +31 -0
- package/dist/types/a2a/a2a_remote_agent_utils.d.ts +38 -0
- package/dist/types/a2a/agent_card.d.ts +23 -0
- package/dist/types/a2a/agent_executor.d.ts +52 -0
- package/dist/types/a2a/agent_to_a2a.d.ts +45 -0
- package/dist/types/a2a/event_converter_utils.d.ts +20 -0
- package/dist/types/a2a/event_processor_utils.d.ts +24 -0
- package/dist/types/a2a/executor_context.d.ts +33 -0
- package/dist/types/a2a/metadata_converter_utils.d.ts +63 -0
- package/dist/types/a2a/part_converter_utils.d.ts +4 -3
- package/dist/types/agents/base_agent.d.ts +2 -2
- package/dist/types/{tools/tool_context.d.ts → agents/context.d.ts} +43 -8
- package/dist/types/agents/llm_agent.d.ts +14 -31
- package/dist/types/agents/loop_agent.d.ts +1 -1
- package/dist/types/agents/processors/agent_transfer_llm_request_processor.d.ts +18 -0
- package/dist/types/agents/{base_llm_processor.d.ts → processors/base_llm_processor.d.ts} +4 -4
- package/dist/types/agents/processors/basic_llm_request_processor.d.ts +13 -0
- package/dist/types/agents/processors/code_execution_request_processor.d.ts +34 -0
- package/dist/types/agents/{content_processor_utils.d.ts → processors/content_processor_utils.d.ts} +1 -1
- package/dist/types/agents/processors/content_request_processor.d.ts +13 -0
- package/dist/types/agents/processors/context_compactor_request_processor.d.ts +22 -0
- package/dist/types/agents/processors/identity_llm_request_processor.d.ts +13 -0
- package/dist/types/agents/processors/instructions_llm_request_processor.d.ts +16 -0
- package/dist/types/agents/processors/request_confirmation_llm_request_processor.d.ts +13 -0
- package/dist/types/artifacts/file_artifact_service.d.ts +4 -0
- package/dist/types/auth/credential_service/base_credential_service.d.ts +3 -3
- package/dist/types/auth/credential_service/in_memory_credential_service.d.ts +3 -3
- package/dist/types/common.d.ts +20 -5
- package/dist/types/context/base_context_compactor.d.ts +24 -0
- package/dist/types/context/summarizers/base_summarizer.d.ts +19 -0
- package/dist/types/context/summarizers/llm_summarizer.d.ts +23 -0
- package/dist/types/context/token_based_context_compactor.d.ts +33 -0
- package/dist/types/context/truncating_context_compactor.d.ts +24 -0
- package/dist/types/events/compacted_event.d.ts +33 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/models/llm_response.d.ts +5 -1
- package/dist/types/plugins/base_plugin.d.ts +12 -13
- package/dist/types/plugins/logging_plugin.d.ts +9 -10
- package/dist/types/plugins/plugin_manager.d.ts +9 -10
- package/dist/types/plugins/security_plugin.d.ts +2 -2
- package/dist/types/runner/runner.d.ts +13 -0
- package/dist/types/sessions/database_session_service.d.ts +2 -1
- package/dist/types/sessions/db/operations.d.ts +3 -4
- package/dist/types/tools/base_tool.d.ts +3 -3
- package/dist/types/tools/base_toolset.d.ts +12 -3
- package/dist/types/tools/exit_loop_tool.d.ts +24 -0
- package/dist/types/tools/forwarding_artifact_service.d.ts +2 -2
- package/dist/types/tools/function_tool.d.ts +2 -2
- package/dist/types/tools/load_artifacts_tool.d.ts +21 -0
- package/dist/types/tools/load_memory_tool.d.ts +22 -0
- package/dist/types/tools/mcp/mcp_toolset.d.ts +1 -1
- package/dist/types/tools/preload_memory_tool.d.ts +23 -0
- package/dist/types/utils/logger.d.ts +5 -9
- package/dist/types/version.d.ts +1 -1
- package/dist/web/a2a/a2a_event.js +269 -0
- package/dist/web/a2a/a2a_remote_agent.js +193 -0
- package/dist/web/a2a/a2a_remote_agent_run_processor.js +175 -0
- package/dist/web/a2a/a2a_remote_agent_utils.js +131 -0
- package/dist/web/a2a/agent_card.js +340 -0
- package/dist/web/a2a/agent_executor.js +216 -0
- package/dist/web/a2a/agent_to_a2a.js +80 -0
- package/dist/web/a2a/event_converter_utils.js +201 -0
- package/dist/web/a2a/event_processor_utils.js +168 -0
- package/dist/web/a2a/executor_context.js +23 -0
- package/dist/web/a2a/metadata_converter_utils.js +108 -0
- package/dist/web/a2a/part_converter_utils.js +49 -34
- package/dist/web/agents/base_agent.js +3 -3
- package/dist/{esm/tools/tool_context.js → web/agents/context.js} +66 -11
- package/dist/web/agents/functions.js +2 -2
- package/dist/web/agents/llm_agent.js +31 -661
- package/dist/web/agents/processors/agent_transfer_llm_request_processor.js +100 -0
- package/dist/web/agents/processors/basic_llm_request_processor.js +71 -0
- package/dist/web/agents/processors/code_execution_request_processor.js +365 -0
- package/dist/web/agents/{content_processor_utils.js → processors/content_processor_utils.js} +22 -2
- package/dist/web/agents/processors/content_request_processor.js +77 -0
- package/dist/web/agents/processors/context_compactor_request_processor.js +49 -0
- package/dist/web/agents/processors/identity_llm_request_processor.js +41 -0
- package/dist/web/agents/processors/instructions_llm_request_processor.js +72 -0
- package/dist/web/agents/processors/request_confirmation_llm_request_processor.js +158 -0
- package/dist/web/artifacts/file_artifact_service.js +30 -3
- package/dist/web/common.js +44 -10
- package/dist/web/context/base_context_compactor.js +5 -0
- package/dist/web/context/summarizers/base_summarizer.js +5 -0
- package/dist/web/context/summarizers/llm_summarizer.js +74 -0
- package/dist/web/context/token_based_context_compactor.js +105 -0
- package/dist/web/context/truncating_context_compactor.js +28 -0
- package/dist/web/events/compacted_event.js +40 -0
- package/dist/web/index.js +13 -18
- package/dist/web/index.js.map +7 -0
- package/dist/web/memory/in_memory_memory_service.js +1 -1
- package/dist/web/models/llm_response.js +2 -0
- package/dist/web/plugins/base_plugin.js +1 -1
- package/dist/web/runner/runner.js +18 -10
- package/dist/web/sessions/database_session_service.js +4 -1
- package/dist/web/sessions/db/operations.js +32 -18
- package/dist/web/sessions/state.js +2 -2
- package/dist/web/tools/agent_tool.js +6 -5
- package/dist/web/tools/base_tool.js +3 -0
- package/dist/web/tools/base_toolset.js +11 -2
- package/dist/web/tools/exit_loop_tool.js +32 -0
- package/dist/web/tools/load_artifacts_tool.js +150 -0
- package/dist/web/tools/load_memory_tool.js +77 -0
- package/dist/web/tools/mcp/mcp_toolset.js +27 -5
- package/dist/web/tools/preload_memory_tool.js +75 -0
- package/dist/web/utils/logger.js +52 -54
- package/dist/web/version.js +1 -1
- package/package.json +7 -4
- package/dist/cjs/agents/callback_context.js +0 -101
- package/dist/esm/agents/callback_context.js +0 -71
- package/dist/types/agents/callback_context.d.ts +0 -42
- package/dist/web/agents/callback_context.js +0 -71
- /package/dist/cjs/agents/{base_llm_processor.js → processors/base_llm_processor.js} +0 -0
- /package/dist/esm/agents/{base_llm_processor.js → processors/base_llm_processor.js} +0 -0
- /package/dist/web/agents/{base_llm_processor.js → processors/base_llm_processor.js} +0 -0
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { DefaultAgentCardResolver } from "@a2a-js/sdk/client";
|
|
7
|
+
import * as fs from "node:fs/promises";
|
|
8
|
+
import {
|
|
9
|
+
InvocationContext
|
|
10
|
+
} from "../agents/invocation_context.js";
|
|
11
|
+
import { isLlmAgent } from "../agents/llm_agent.js";
|
|
12
|
+
import { isLoopAgent } from "../agents/loop_agent.js";
|
|
13
|
+
import { isParallelAgent } from "../agents/parallel_agent.js";
|
|
14
|
+
import { ReadonlyContext } from "../agents/readonly_context.js";
|
|
15
|
+
import { isSequentialAgent } from "../agents/sequential_agent.js";
|
|
16
|
+
import { isBaseTool } from "../tools/base_tool.js";
|
|
17
|
+
import { isBaseToolset } from "../tools/base_toolset.js";
|
|
18
|
+
import { logger } from "../utils/logger.js";
|
|
19
|
+
async function resolveAgentCard(agentCard) {
|
|
20
|
+
if (typeof agentCard === "object") {
|
|
21
|
+
return agentCard;
|
|
22
|
+
}
|
|
23
|
+
const source = agentCard;
|
|
24
|
+
if (source.startsWith("http://") || source.startsWith("https://")) {
|
|
25
|
+
const resolver = new DefaultAgentCardResolver();
|
|
26
|
+
return await resolver.resolve(source);
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
const content = await fs.readFile(source, "utf-8");
|
|
30
|
+
return JSON.parse(content);
|
|
31
|
+
} catch (err) {
|
|
32
|
+
throw new Error(
|
|
33
|
+
`Failed to read agent card from file ${source}: ${err.message}`
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async function getA2AAgentCard(agent, transports) {
|
|
38
|
+
return {
|
|
39
|
+
name: agent.name,
|
|
40
|
+
description: agent.description || "",
|
|
41
|
+
protocolVersion: "0.3.0",
|
|
42
|
+
version: "1.0.0",
|
|
43
|
+
skills: await buildAgentSkills(agent),
|
|
44
|
+
url: transports[0].url,
|
|
45
|
+
preferredTransport: transports[0].transport,
|
|
46
|
+
capabilities: {
|
|
47
|
+
extensions: [],
|
|
48
|
+
stateTransitionHistory: false,
|
|
49
|
+
pushNotifications: false,
|
|
50
|
+
streaming: true
|
|
51
|
+
},
|
|
52
|
+
defaultInputModes: ["text"],
|
|
53
|
+
defaultOutputModes: ["text"],
|
|
54
|
+
additionalInterfaces: transports
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
async function buildAgentSkills(agent) {
|
|
58
|
+
const [primarySkills, subAgentSkills] = await Promise.all([
|
|
59
|
+
buildPrimarySkills(agent),
|
|
60
|
+
buildSubAgentSkills(agent)
|
|
61
|
+
]);
|
|
62
|
+
return [...primarySkills, ...subAgentSkills];
|
|
63
|
+
}
|
|
64
|
+
async function buildPrimarySkills(agent) {
|
|
65
|
+
if (isLlmAgent(agent)) {
|
|
66
|
+
return buildLLMAgentSkills(agent);
|
|
67
|
+
}
|
|
68
|
+
return buildNonLLMAgentSkills(agent);
|
|
69
|
+
}
|
|
70
|
+
async function buildSubAgentSkills(agent) {
|
|
71
|
+
const subAgents = agent.subAgents;
|
|
72
|
+
const result = [];
|
|
73
|
+
for (const sub of subAgents) {
|
|
74
|
+
const skills = await buildPrimarySkills(sub);
|
|
75
|
+
for (const subSkill of skills) {
|
|
76
|
+
const skill = {
|
|
77
|
+
id: `${sub.name}_${subSkill.id}`,
|
|
78
|
+
name: `${sub.name}: ${subSkill.name}`,
|
|
79
|
+
description: subSkill.description,
|
|
80
|
+
tags: [`sub_agent:${sub.name}`, ...subSkill.tags]
|
|
81
|
+
};
|
|
82
|
+
result.push(skill);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return result;
|
|
86
|
+
}
|
|
87
|
+
async function buildLLMAgentSkills(agent) {
|
|
88
|
+
const skills = [
|
|
89
|
+
{
|
|
90
|
+
id: agent.name,
|
|
91
|
+
name: "model",
|
|
92
|
+
description: await buildDescriptionFromInstructions(agent),
|
|
93
|
+
tags: ["llm"]
|
|
94
|
+
}
|
|
95
|
+
];
|
|
96
|
+
if (agent.tools && agent.tools.length > 0) {
|
|
97
|
+
for (const toolUnion of agent.tools) {
|
|
98
|
+
if (isBaseTool(toolUnion)) {
|
|
99
|
+
skills.push(toolToSkill(agent.name, toolUnion));
|
|
100
|
+
} else if (isBaseToolset(toolUnion)) {
|
|
101
|
+
const tools = await toolUnion.getTools();
|
|
102
|
+
for (const tool of tools) {
|
|
103
|
+
skills.push(toolToSkill(agent.name, tool));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return skills;
|
|
109
|
+
}
|
|
110
|
+
function toolToSkill(prefix, tool) {
|
|
111
|
+
let description = tool.description;
|
|
112
|
+
if (!description) {
|
|
113
|
+
description = `Tool: ${tool.name}`;
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
id: `${prefix}-${tool.name}`,
|
|
117
|
+
name: tool.name,
|
|
118
|
+
description,
|
|
119
|
+
tags: ["llm", "tools"]
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function buildNonLLMAgentSkills(agent) {
|
|
123
|
+
const skills = [
|
|
124
|
+
{
|
|
125
|
+
id: agent.name,
|
|
126
|
+
name: getAgentSkillName(agent),
|
|
127
|
+
description: buildAgentDescription(agent),
|
|
128
|
+
tags: [getAgentTypeTag(agent)]
|
|
129
|
+
}
|
|
130
|
+
];
|
|
131
|
+
const subAgents = agent.subAgents;
|
|
132
|
+
if (subAgents.length > 0) {
|
|
133
|
+
const descriptions = subAgents.map(
|
|
134
|
+
(sub) => sub.description || "No description"
|
|
135
|
+
);
|
|
136
|
+
skills.push({
|
|
137
|
+
id: `${agent.name}-sub-agents`,
|
|
138
|
+
name: "sub-agents",
|
|
139
|
+
description: `Orchestrates: ${descriptions.join("; ")}`,
|
|
140
|
+
tags: [getAgentTypeTag(agent), "orchestration"]
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
return skills;
|
|
144
|
+
}
|
|
145
|
+
function buildAgentDescription(agent) {
|
|
146
|
+
const descriptionParts = [];
|
|
147
|
+
if (agent.description) {
|
|
148
|
+
descriptionParts.push(agent.description);
|
|
149
|
+
}
|
|
150
|
+
if (agent.subAgents.length > 0) {
|
|
151
|
+
if (isLoopAgent(agent)) {
|
|
152
|
+
descriptionParts.push(buildLoopAgentDescription(agent));
|
|
153
|
+
} else if (isParallelAgent(agent)) {
|
|
154
|
+
descriptionParts.push(buildParallelAgentDescription(agent));
|
|
155
|
+
} else if (isSequentialAgent(agent)) {
|
|
156
|
+
descriptionParts.push(buildSequentialAgentDescription(agent));
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (descriptionParts.length > 0) {
|
|
160
|
+
return descriptionParts.join(" ");
|
|
161
|
+
} else {
|
|
162
|
+
return getDefaultAgentDescription(agent);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function buildSequentialAgentDescription(agent) {
|
|
166
|
+
const subAgents = agent.subAgents;
|
|
167
|
+
const descriptions = [];
|
|
168
|
+
subAgents.forEach((sub, i) => {
|
|
169
|
+
let subDescription = sub.description;
|
|
170
|
+
if (!subDescription) {
|
|
171
|
+
subDescription = `execute the ${sub.name} agent`;
|
|
172
|
+
}
|
|
173
|
+
if (i === 0) {
|
|
174
|
+
descriptions.push(`First, this agent will ${subDescription}.`);
|
|
175
|
+
} else if (i === subAgents.length - 1) {
|
|
176
|
+
descriptions.push(`Finally, this agent will ${subDescription}.`);
|
|
177
|
+
} else {
|
|
178
|
+
descriptions.push(`Then, this agent will ${subDescription}.`);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
return descriptions.join(" ");
|
|
182
|
+
}
|
|
183
|
+
function buildParallelAgentDescription(agent) {
|
|
184
|
+
const subAgents = agent.subAgents;
|
|
185
|
+
const descriptions = [];
|
|
186
|
+
subAgents.forEach((sub, i) => {
|
|
187
|
+
let subDescription = sub.description;
|
|
188
|
+
if (!subDescription) {
|
|
189
|
+
subDescription = `execute the ${sub.name} agent`;
|
|
190
|
+
}
|
|
191
|
+
if (i === 0) {
|
|
192
|
+
descriptions.push(`This agent will ${subDescription}`);
|
|
193
|
+
} else if (i === subAgents.length - 1) {
|
|
194
|
+
descriptions.push(`and ${subDescription}`);
|
|
195
|
+
} else {
|
|
196
|
+
descriptions.push(`, ${subDescription}`);
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
return `${descriptions.join(" ")} simultaneously.`;
|
|
200
|
+
}
|
|
201
|
+
function buildLoopAgentDescription(agent) {
|
|
202
|
+
const maxIterationsVal = agent.maxIterations;
|
|
203
|
+
let maxIterations = "unlimited";
|
|
204
|
+
if (typeof maxIterationsVal === "number" && maxIterationsVal < Number.MAX_SAFE_INTEGER) {
|
|
205
|
+
maxIterations = maxIterationsVal.toString();
|
|
206
|
+
}
|
|
207
|
+
const subAgents = agent.subAgents;
|
|
208
|
+
const descriptions = [];
|
|
209
|
+
subAgents.forEach((sub, i) => {
|
|
210
|
+
let subDescription = sub.description;
|
|
211
|
+
if (!subDescription) {
|
|
212
|
+
subDescription = `execute the ${sub.name} agent`;
|
|
213
|
+
}
|
|
214
|
+
if (i === 0) {
|
|
215
|
+
descriptions.push(`This agent will ${subDescription}`);
|
|
216
|
+
} else if (i === subAgents.length - 1) {
|
|
217
|
+
descriptions.push(`and ${subDescription}`);
|
|
218
|
+
} else {
|
|
219
|
+
descriptions.push(`, ${subDescription}`);
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
return `${descriptions.join(" ")} in a loop (max ${maxIterations} iterations).`;
|
|
223
|
+
}
|
|
224
|
+
async function buildDescriptionFromInstructions(agent) {
|
|
225
|
+
const descriptionParts = [];
|
|
226
|
+
if (agent.description) {
|
|
227
|
+
descriptionParts.push(agent.description);
|
|
228
|
+
}
|
|
229
|
+
if (agent.instruction) {
|
|
230
|
+
let instructionStr;
|
|
231
|
+
if (typeof agent.instruction === "function") {
|
|
232
|
+
const dummyContext = new ReadonlyContext(
|
|
233
|
+
new InvocationContext({
|
|
234
|
+
agent
|
|
235
|
+
})
|
|
236
|
+
);
|
|
237
|
+
try {
|
|
238
|
+
instructionStr = await agent.instruction(dummyContext);
|
|
239
|
+
} catch (e) {
|
|
240
|
+
logger.warn("Failed to resolve dynamic instruction for AgentCard", e);
|
|
241
|
+
instructionStr = "";
|
|
242
|
+
}
|
|
243
|
+
} else {
|
|
244
|
+
instructionStr = agent.instruction;
|
|
245
|
+
}
|
|
246
|
+
if (instructionStr) {
|
|
247
|
+
descriptionParts.push(replacePronouns(instructionStr));
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
const root = agent.rootAgent;
|
|
251
|
+
if (isLlmAgent(root) && root.globalInstruction) {
|
|
252
|
+
let globalInstructionStr;
|
|
253
|
+
if (typeof root.globalInstruction === "function") {
|
|
254
|
+
const dummyContext = new ReadonlyContext(
|
|
255
|
+
new InvocationContext({
|
|
256
|
+
agent
|
|
257
|
+
})
|
|
258
|
+
);
|
|
259
|
+
try {
|
|
260
|
+
globalInstructionStr = await root.globalInstruction(dummyContext);
|
|
261
|
+
} catch (e) {
|
|
262
|
+
logger.warn(
|
|
263
|
+
"Failed to resolve dynamic global instruction for AgentCard",
|
|
264
|
+
e
|
|
265
|
+
);
|
|
266
|
+
globalInstructionStr = "";
|
|
267
|
+
}
|
|
268
|
+
} else {
|
|
269
|
+
globalInstructionStr = root.globalInstruction;
|
|
270
|
+
}
|
|
271
|
+
if (globalInstructionStr) {
|
|
272
|
+
descriptionParts.push(replacePronouns(globalInstructionStr));
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
if (descriptionParts.length > 0) {
|
|
276
|
+
return descriptionParts.join(" ");
|
|
277
|
+
} else {
|
|
278
|
+
return getDefaultAgentDescription(agent);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
function replacePronouns(instruction) {
|
|
282
|
+
const substitutions = [
|
|
283
|
+
{ original: "you were", target: "I was" },
|
|
284
|
+
{ original: "you are", target: "I am" },
|
|
285
|
+
{ original: "you're", target: "I am" },
|
|
286
|
+
{ original: "you've", target: "I have" },
|
|
287
|
+
{ original: "yours", target: "mine" },
|
|
288
|
+
{ original: "your", target: "my" },
|
|
289
|
+
{ original: "you", target: "I" }
|
|
290
|
+
];
|
|
291
|
+
let result = instruction;
|
|
292
|
+
for (const sub of substitutions) {
|
|
293
|
+
const pattern = new RegExp(`\\b${sub.original}\\b`, "gi");
|
|
294
|
+
result = result.replace(pattern, sub.target);
|
|
295
|
+
}
|
|
296
|
+
return result;
|
|
297
|
+
}
|
|
298
|
+
function getDefaultAgentDescription(agent) {
|
|
299
|
+
if (isLoopAgent(agent)) {
|
|
300
|
+
return "A loop workflow agent";
|
|
301
|
+
} else if (isSequentialAgent(agent)) {
|
|
302
|
+
return "A sequential workflow agent";
|
|
303
|
+
} else if (isParallelAgent(agent)) {
|
|
304
|
+
return "A parallel workflow agent";
|
|
305
|
+
} else if (isLlmAgent(agent)) {
|
|
306
|
+
return "An LLM-based agent";
|
|
307
|
+
} else {
|
|
308
|
+
return "A custom agent";
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
function getAgentTypeTag(agent) {
|
|
312
|
+
if (isLoopAgent(agent)) {
|
|
313
|
+
return "loop_workflow";
|
|
314
|
+
} else if (isSequentialAgent(agent)) {
|
|
315
|
+
return "sequential_workflow";
|
|
316
|
+
} else if (isParallelAgent(agent)) {
|
|
317
|
+
return "parallel_workflow";
|
|
318
|
+
} else if (isLlmAgent(agent)) {
|
|
319
|
+
return "llm_agent";
|
|
320
|
+
} else {
|
|
321
|
+
return "custom_agent";
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
function getAgentSkillName(agent) {
|
|
325
|
+
if (isLlmAgent(agent)) {
|
|
326
|
+
return "model";
|
|
327
|
+
}
|
|
328
|
+
if (isWorkflowAgent(agent)) {
|
|
329
|
+
return "workflow";
|
|
330
|
+
}
|
|
331
|
+
return "custom";
|
|
332
|
+
}
|
|
333
|
+
function isWorkflowAgent(agent) {
|
|
334
|
+
return isLoopAgent(agent) || isSequentialAgent(agent) || isParallelAgent(agent);
|
|
335
|
+
}
|
|
336
|
+
export {
|
|
337
|
+
buildAgentSkills,
|
|
338
|
+
getA2AAgentCard,
|
|
339
|
+
resolveAgentCard
|
|
340
|
+
};
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { isRunner, Runner } from "../runner/runner.js";
|
|
7
|
+
import { randomUUID } from "../utils/env_aware_utils.js";
|
|
8
|
+
import { logger } from "../utils/logger.js";
|
|
9
|
+
import {
|
|
10
|
+
createTask,
|
|
11
|
+
createTaskArtifactUpdateEvent,
|
|
12
|
+
createTaskFailedEvent,
|
|
13
|
+
createTaskWorkingEvent
|
|
14
|
+
} from "./a2a_event.js";
|
|
15
|
+
import {
|
|
16
|
+
getFinalTaskStatusUpdate,
|
|
17
|
+
getTaskInputRequiredEvent
|
|
18
|
+
} from "./event_processor_utils.js";
|
|
19
|
+
import { createExecutorContext } from "./executor_context.js";
|
|
20
|
+
import {
|
|
21
|
+
getA2AEventMetadata,
|
|
22
|
+
getA2ASessionMetadata
|
|
23
|
+
} from "./metadata_converter_utils.js";
|
|
24
|
+
import { toA2AParts, toGenAIContent } from "./part_converter_utils.js";
|
|
25
|
+
class A2AAgentExecutor {
|
|
26
|
+
constructor(config) {
|
|
27
|
+
this.config = config;
|
|
28
|
+
this.agentPartialArtifactIdsMap = {};
|
|
29
|
+
}
|
|
30
|
+
async execute(ctx, eventBus) {
|
|
31
|
+
var _a, _b;
|
|
32
|
+
const a2aUserMessage = ctx.userMessage;
|
|
33
|
+
if (!a2aUserMessage) {
|
|
34
|
+
throw new Error("message not provided");
|
|
35
|
+
}
|
|
36
|
+
const userId = `A2A_USER_${ctx.contextId}`;
|
|
37
|
+
const sessionId = ctx.contextId;
|
|
38
|
+
const genAIUserMessage = toGenAIContent(a2aUserMessage);
|
|
39
|
+
const adkRunner = await getAdkRunner(this.config.runner);
|
|
40
|
+
const session = await getAdkSession(
|
|
41
|
+
userId,
|
|
42
|
+
sessionId,
|
|
43
|
+
adkRunner.sessionService,
|
|
44
|
+
adkRunner.appName
|
|
45
|
+
);
|
|
46
|
+
const executorContext = createExecutorContext({
|
|
47
|
+
session,
|
|
48
|
+
userContent: genAIUserMessage,
|
|
49
|
+
requestContext: ctx
|
|
50
|
+
});
|
|
51
|
+
try {
|
|
52
|
+
if (this.config.beforeExecuteCallback) {
|
|
53
|
+
await this.config.beforeExecuteCallback(ctx);
|
|
54
|
+
}
|
|
55
|
+
if (ctx.task) {
|
|
56
|
+
const inputRequiredEvent = getTaskInputRequiredEvent(
|
|
57
|
+
ctx.task,
|
|
58
|
+
genAIUserMessage
|
|
59
|
+
);
|
|
60
|
+
if (inputRequiredEvent) {
|
|
61
|
+
await this.publishFinalTaskStatus({
|
|
62
|
+
executorContext,
|
|
63
|
+
eventBus,
|
|
64
|
+
event: inputRequiredEvent
|
|
65
|
+
});
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (!ctx.task) {
|
|
70
|
+
eventBus.publish(
|
|
71
|
+
createTask({
|
|
72
|
+
taskId: ctx.taskId,
|
|
73
|
+
contextId: ctx.contextId,
|
|
74
|
+
message: a2aUserMessage
|
|
75
|
+
})
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
eventBus.publish(
|
|
79
|
+
createTaskWorkingEvent({
|
|
80
|
+
taskId: ctx.taskId,
|
|
81
|
+
contextId: ctx.contextId
|
|
82
|
+
})
|
|
83
|
+
);
|
|
84
|
+
const adkEvents = [];
|
|
85
|
+
for await (const adkEvent of adkRunner.runAsync({
|
|
86
|
+
userId,
|
|
87
|
+
sessionId,
|
|
88
|
+
newMessage: genAIUserMessage,
|
|
89
|
+
runConfig: this.config.runConfig
|
|
90
|
+
})) {
|
|
91
|
+
adkEvents.push(adkEvent);
|
|
92
|
+
const a2aEvent = this.convertAdkEventToA2AEvent(
|
|
93
|
+
adkEvent,
|
|
94
|
+
executorContext
|
|
95
|
+
);
|
|
96
|
+
if (!a2aEvent) {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
await ((_b = (_a = this.config).afterEventCallback) == null ? void 0 : _b.call(
|
|
100
|
+
_a,
|
|
101
|
+
executorContext,
|
|
102
|
+
adkEvent,
|
|
103
|
+
a2aEvent
|
|
104
|
+
));
|
|
105
|
+
eventBus.publish(a2aEvent);
|
|
106
|
+
}
|
|
107
|
+
await this.publishFinalTaskStatus({
|
|
108
|
+
executorContext,
|
|
109
|
+
eventBus,
|
|
110
|
+
event: getFinalTaskStatusUpdate(adkEvents, executorContext)
|
|
111
|
+
});
|
|
112
|
+
} catch (e) {
|
|
113
|
+
const error = e;
|
|
114
|
+
await this.publishFinalTaskStatus({
|
|
115
|
+
executorContext,
|
|
116
|
+
eventBus,
|
|
117
|
+
error,
|
|
118
|
+
event: createTaskFailedEvent({
|
|
119
|
+
taskId: ctx.taskId,
|
|
120
|
+
contextId: ctx.contextId,
|
|
121
|
+
error: new Error(`Agent run failed: ${error.message}`),
|
|
122
|
+
metadata: getA2ASessionMetadata(executorContext)
|
|
123
|
+
})
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// Task cancellation is not supported in this implementation yet.
|
|
128
|
+
async cancelTask(_taskId) {
|
|
129
|
+
throw new Error("Task cancellation is not supported yet.");
|
|
130
|
+
}
|
|
131
|
+
convertAdkEventToA2AEvent(adkEvent, executorContext) {
|
|
132
|
+
var _a;
|
|
133
|
+
const a2aParts = toA2AParts(
|
|
134
|
+
(_a = adkEvent.content) == null ? void 0 : _a.parts,
|
|
135
|
+
adkEvent.longRunningToolIds
|
|
136
|
+
);
|
|
137
|
+
if (a2aParts.length === 0) {
|
|
138
|
+
return void 0;
|
|
139
|
+
}
|
|
140
|
+
const artifactId = this.agentPartialArtifactIdsMap[adkEvent.author] || randomUUID();
|
|
141
|
+
const a2aEvent = createTaskArtifactUpdateEvent({
|
|
142
|
+
taskId: executorContext.requestContext.taskId,
|
|
143
|
+
contextId: executorContext.requestContext.contextId,
|
|
144
|
+
artifactId,
|
|
145
|
+
parts: a2aParts,
|
|
146
|
+
metadata: getA2AEventMetadata(adkEvent, executorContext),
|
|
147
|
+
append: adkEvent.partial,
|
|
148
|
+
lastChunk: !adkEvent.partial
|
|
149
|
+
});
|
|
150
|
+
if (adkEvent.partial) {
|
|
151
|
+
this.agentPartialArtifactIdsMap[adkEvent.author] = artifactId;
|
|
152
|
+
} else {
|
|
153
|
+
delete this.agentPartialArtifactIdsMap[adkEvent.author];
|
|
154
|
+
}
|
|
155
|
+
return a2aEvent;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Writes the final status event to the queue.
|
|
159
|
+
*/
|
|
160
|
+
async publishFinalTaskStatus({
|
|
161
|
+
executorContext,
|
|
162
|
+
eventBus,
|
|
163
|
+
event,
|
|
164
|
+
error
|
|
165
|
+
}) {
|
|
166
|
+
var _a, _b;
|
|
167
|
+
try {
|
|
168
|
+
await ((_b = (_a = this.config).afterExecuteCallback) == null ? void 0 : _b.call(_a, executorContext, event, error));
|
|
169
|
+
} catch (e) {
|
|
170
|
+
logger.error("Error in afterExecuteCallback:", e);
|
|
171
|
+
}
|
|
172
|
+
eventBus.publish(event);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
async function getAdkSession(userId, sessionId, sessionService, appName) {
|
|
176
|
+
const session = await sessionService.getSession({
|
|
177
|
+
appName,
|
|
178
|
+
userId,
|
|
179
|
+
sessionId
|
|
180
|
+
});
|
|
181
|
+
if (session) {
|
|
182
|
+
return session;
|
|
183
|
+
}
|
|
184
|
+
return sessionService.createSession({
|
|
185
|
+
appName,
|
|
186
|
+
userId,
|
|
187
|
+
sessionId
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
async function getAdkRunner(runnerOrConfig) {
|
|
191
|
+
if (typeof runnerOrConfig === "function") {
|
|
192
|
+
const result = await runnerOrConfig();
|
|
193
|
+
return getAdkRunner(result);
|
|
194
|
+
}
|
|
195
|
+
if (isRunner(runnerOrConfig)) {
|
|
196
|
+
return runnerOrConfig;
|
|
197
|
+
}
|
|
198
|
+
return new Runner(runnerOrConfig);
|
|
199
|
+
}
|
|
200
|
+
export {
|
|
201
|
+
A2AAgentExecutor
|
|
202
|
+
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { AGENT_CARD_PATH } from "@a2a-js/sdk";
|
|
7
|
+
import { DefaultRequestHandler, InMemoryTaskStore } from "@a2a-js/sdk/server";
|
|
8
|
+
import {
|
|
9
|
+
agentCardHandler,
|
|
10
|
+
jsonRpcHandler,
|
|
11
|
+
restHandler,
|
|
12
|
+
UserBuilder
|
|
13
|
+
} from "@a2a-js/sdk/server/express";
|
|
14
|
+
import express from "express";
|
|
15
|
+
import { StreamingMode } from "../agents/run_config.js";
|
|
16
|
+
import { InMemorySessionService } from "../sessions/in_memory_session_service.js";
|
|
17
|
+
import { getA2AAgentCard, resolveAgentCard } from "./agent_card.js";
|
|
18
|
+
import { A2AAgentExecutor } from "./agent_executor.js";
|
|
19
|
+
async function toA2a(agent, options = {}) {
|
|
20
|
+
var _a, _b, _c, _d;
|
|
21
|
+
const host = (_a = options.host) != null ? _a : "localhost";
|
|
22
|
+
const port = (_b = options.port) != null ? _b : 8e3;
|
|
23
|
+
const protocol = (_c = options.protocol) != null ? _c : "http";
|
|
24
|
+
const basePath = options.basePath || "";
|
|
25
|
+
const rpcUrl = `${protocol}://${host}:${port}${basePath}`;
|
|
26
|
+
const agentCard = options.agentCard ? await resolveAgentCard(options.agentCard) : await getA2AAgentCard(agent, [
|
|
27
|
+
{
|
|
28
|
+
url: `${rpcUrl}/jsonrpc`,
|
|
29
|
+
transport: "JSONRPC"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
url: `${rpcUrl}/rest`,
|
|
33
|
+
transport: "HTTP+JSON"
|
|
34
|
+
}
|
|
35
|
+
]);
|
|
36
|
+
const agentExecutor = new A2AAgentExecutor({
|
|
37
|
+
runner: options.runner || {
|
|
38
|
+
agent,
|
|
39
|
+
appName: agent.name,
|
|
40
|
+
sessionService: options.sessionService || new InMemorySessionService(),
|
|
41
|
+
memoryService: options.memoryService,
|
|
42
|
+
artifactService: options.artifactService
|
|
43
|
+
},
|
|
44
|
+
runConfig: {
|
|
45
|
+
streamingMode: StreamingMode.SSE
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
const requestHandler = new DefaultRequestHandler(
|
|
49
|
+
agentCard,
|
|
50
|
+
new InMemoryTaskStore(),
|
|
51
|
+
agentExecutor
|
|
52
|
+
);
|
|
53
|
+
const app = (_d = options.app) != null ? _d : express();
|
|
54
|
+
if (!options.app) {
|
|
55
|
+
app.use(express.urlencoded({ limit: "50mb", extended: true }));
|
|
56
|
+
app.use(express.json({ limit: "50mb" }));
|
|
57
|
+
}
|
|
58
|
+
app.use(
|
|
59
|
+
`${basePath}/${AGENT_CARD_PATH}`,
|
|
60
|
+
agentCardHandler({ agentCardProvider: requestHandler })
|
|
61
|
+
);
|
|
62
|
+
app.use(
|
|
63
|
+
`${basePath}/rest`,
|
|
64
|
+
restHandler({
|
|
65
|
+
requestHandler,
|
|
66
|
+
userBuilder: UserBuilder.noAuthentication
|
|
67
|
+
})
|
|
68
|
+
);
|
|
69
|
+
app.use(
|
|
70
|
+
`${basePath}/jsonrpc`,
|
|
71
|
+
jsonRpcHandler({
|
|
72
|
+
requestHandler,
|
|
73
|
+
userBuilder: UserBuilder.noAuthentication
|
|
74
|
+
})
|
|
75
|
+
);
|
|
76
|
+
return app;
|
|
77
|
+
}
|
|
78
|
+
export {
|
|
79
|
+
toA2a
|
|
80
|
+
};
|