kagent-adk 0.6.20__tar.gz → 0.7.0__tar.gz
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.
- {kagent_adk-0.6.20 → kagent_adk-0.7.0}/PKG-INFO +4 -4
- {kagent_adk-0.6.20 → kagent_adk-0.7.0}/pyproject.toml +4 -4
- {kagent_adk-0.6.20 → kagent_adk-0.7.0}/src/kagent/adk/_a2a.py +39 -3
- {kagent_adk-0.6.20 → kagent_adk-0.7.0}/src/kagent/adk/_agent_executor.py +22 -18
- {kagent_adk-0.6.20 → kagent_adk-0.7.0}/src/kagent/adk/_session_service.py +9 -5
- {kagent_adk-0.6.20 → kagent_adk-0.7.0}/src/kagent/adk/cli.py +11 -1
- {kagent_adk-0.6.20 → kagent_adk-0.7.0}/.gitignore +0 -0
- {kagent_adk-0.6.20 → kagent_adk-0.7.0}/.python-version +0 -0
- {kagent_adk-0.6.20 → kagent_adk-0.7.0}/README.md +0 -0
- {kagent_adk-0.6.20 → kagent_adk-0.7.0}/src/kagent/adk/__init__.py +0 -0
- {kagent_adk-0.6.20 → kagent_adk-0.7.0}/src/kagent/adk/_token.py +0 -0
- {kagent_adk-0.6.20 → kagent_adk-0.7.0}/src/kagent/adk/converters/__init__.py +0 -0
- {kagent_adk-0.6.20 → kagent_adk-0.7.0}/src/kagent/adk/converters/error_mappings.py +0 -0
- {kagent_adk-0.6.20 → kagent_adk-0.7.0}/src/kagent/adk/converters/event_converter.py +0 -0
- {kagent_adk-0.6.20 → kagent_adk-0.7.0}/src/kagent/adk/converters/part_converter.py +0 -0
- {kagent_adk-0.6.20 → kagent_adk-0.7.0}/src/kagent/adk/converters/request_converter.py +0 -0
- {kagent_adk-0.6.20 → kagent_adk-0.7.0}/src/kagent/adk/models/__init__.py +0 -0
- {kagent_adk-0.6.20 → kagent_adk-0.7.0}/src/kagent/adk/models/_openai.py +0 -0
- {kagent_adk-0.6.20 → kagent_adk-0.7.0}/src/kagent/adk/types.py +0 -0
- {kagent_adk-0.6.20 → kagent_adk-0.7.0}/tests/__init__.py +0 -0
- {kagent_adk-0.6.20 → kagent_adk-0.7.0}/tests/unittests/__init__.py +0 -0
- {kagent_adk-0.6.20 → kagent_adk-0.7.0}/tests/unittests/converters/__init__.py +0 -0
- {kagent_adk-0.6.20 → kagent_adk-0.7.0}/tests/unittests/converters/test_event_converter.py +0 -0
- {kagent_adk-0.6.20 → kagent_adk-0.7.0}/tests/unittests/models/__init__.py +0 -0
- {kagent_adk-0.6.20 → kagent_adk-0.7.0}/tests/unittests/models/test_openai.py +0 -0
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kagent-adk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: kagent-adk is an sdk for integrating adk agents with kagent
|
|
5
5
|
Requires-Python: >=3.11.0
|
|
6
6
|
Requires-Dist: a2a-sdk>=0.3.1
|
|
7
|
-
Requires-Dist: agentsts-adk>=0.0.
|
|
8
|
-
Requires-Dist: agentsts-core>=0.0.
|
|
7
|
+
Requires-Dist: agentsts-adk>=0.0.6
|
|
8
|
+
Requires-Dist: agentsts-core>=0.0.6
|
|
9
9
|
Requires-Dist: aiofiles>=24.1.0
|
|
10
10
|
Requires-Dist: anthropic[vertex]>=0.49.0
|
|
11
11
|
Requires-Dist: anyio>=4.9.0
|
|
12
12
|
Requires-Dist: fastapi>=0.115.1
|
|
13
|
-
Requires-Dist: google-adk>=1.
|
|
13
|
+
Requires-Dist: google-adk>=1.16.0
|
|
14
14
|
Requires-Dist: google-auth>=2.40.2
|
|
15
15
|
Requires-Dist: google-genai>=1.21.1
|
|
16
16
|
Requires-Dist: httpx>=0.25.0
|
|
@@ -4,13 +4,13 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "kagent-adk"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.7.0"
|
|
8
8
|
description = "kagent-adk is an sdk for integrating adk agents with kagent"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11.0"
|
|
11
11
|
dependencies = [
|
|
12
|
-
"agentsts-adk >= 0.0.
|
|
13
|
-
"agentsts-core >= 0.0.
|
|
12
|
+
"agentsts-adk >= 0.0.6",
|
|
13
|
+
"agentsts-core >= 0.0.6",
|
|
14
14
|
"kagent-core",
|
|
15
15
|
"aiofiles>=24.1.0",
|
|
16
16
|
"anyio>=4.9.0",
|
|
@@ -22,7 +22,7 @@ dependencies = [
|
|
|
22
22
|
"anthropic[vertex]>=0.49.0",
|
|
23
23
|
"fastapi>=0.115.1",
|
|
24
24
|
"litellm>=1.74.3",
|
|
25
|
-
"google-adk>=1.
|
|
25
|
+
"google-adk>=1.16.0",
|
|
26
26
|
"google-genai>=1.21.1",
|
|
27
27
|
"google-auth>=2.40.2",
|
|
28
28
|
"httpx>=0.25.0",
|
|
@@ -7,8 +7,9 @@ from typing import Callable
|
|
|
7
7
|
import httpx
|
|
8
8
|
from a2a.server.apps import A2AFastAPIApplication
|
|
9
9
|
from a2a.server.request_handlers import DefaultRequestHandler
|
|
10
|
+
from a2a.server.tasks import InMemoryTaskStore
|
|
10
11
|
from a2a.types import AgentCard
|
|
11
|
-
from agentsts.adk import
|
|
12
|
+
from agentsts.adk import ADKSTSIntegration, ADKTokenPropagationPlugin
|
|
12
13
|
from fastapi import FastAPI, Request
|
|
13
14
|
from fastapi.responses import PlainTextResponse
|
|
14
15
|
from google.adk.agents import BaseAgent
|
|
@@ -79,13 +80,12 @@ class KAgentApp:
|
|
|
79
80
|
plugins = []
|
|
80
81
|
if sts_well_known_uri:
|
|
81
82
|
sts_integration = ADKSTSIntegration(sts_well_known_uri)
|
|
82
|
-
session_service = ADKSessionService(sts_integration, session_service)
|
|
83
83
|
plugins.append(ADKTokenPropagationPlugin(sts_integration))
|
|
84
84
|
|
|
85
85
|
adk_app = App(name=self.app_name, root_agent=self.root_agent, plugins=plugins)
|
|
86
86
|
|
|
87
87
|
def create_runner() -> Runner:
|
|
88
|
-
return
|
|
88
|
+
return Runner(
|
|
89
89
|
app=adk_app,
|
|
90
90
|
session_service=session_service,
|
|
91
91
|
)
|
|
@@ -118,6 +118,42 @@ class KAgentApp:
|
|
|
118
118
|
|
|
119
119
|
return app
|
|
120
120
|
|
|
121
|
+
def build_local(self) -> FastAPI:
|
|
122
|
+
session_service = InMemorySessionService()
|
|
123
|
+
|
|
124
|
+
def create_runner() -> Runner:
|
|
125
|
+
return Runner(
|
|
126
|
+
agent=self.root_agent,
|
|
127
|
+
app_name=self.app_name,
|
|
128
|
+
session_service=session_service,
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
agent_executor = A2aAgentExecutor(
|
|
132
|
+
runner=create_runner,
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
task_store = InMemoryTaskStore()
|
|
136
|
+
request_context_builder = KAgentRequestContextBuilder(task_store=task_store)
|
|
137
|
+
request_handler = DefaultRequestHandler(
|
|
138
|
+
agent_executor=agent_executor,
|
|
139
|
+
task_store=task_store,
|
|
140
|
+
request_context_builder=request_context_builder,
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
a2a_app = A2AFastAPIApplication(
|
|
144
|
+
agent_card=self.agent_card,
|
|
145
|
+
http_handler=request_handler,
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
faulthandler.enable()
|
|
149
|
+
app = FastAPI()
|
|
150
|
+
|
|
151
|
+
app.add_route("/health", methods=["GET"], route=health_check)
|
|
152
|
+
app.add_route("/thread_dump", methods=["GET"], route=thread_dump)
|
|
153
|
+
a2a_app.add_routes_to_app(app)
|
|
154
|
+
|
|
155
|
+
return app
|
|
156
|
+
|
|
121
157
|
async def test(self, task: str):
|
|
122
158
|
session_service = InMemorySessionService()
|
|
123
159
|
SESSION_ID = "12345"
|
|
@@ -21,6 +21,7 @@ from a2a.types import (
|
|
|
21
21
|
TaskStatusUpdateEvent,
|
|
22
22
|
TextPart,
|
|
23
23
|
)
|
|
24
|
+
from google.adk.events import Event, EventActions
|
|
24
25
|
from google.adk.runners import Runner
|
|
25
26
|
from google.adk.utils.context_utils import Aclosing
|
|
26
27
|
from opentelemetry import trace
|
|
@@ -156,12 +157,23 @@ class A2aAgentExecutor(AgentExecutor):
|
|
|
156
157
|
# Convert the a2a request to ADK run args
|
|
157
158
|
run_args = convert_a2a_request_to_adk_run_args(context)
|
|
158
159
|
|
|
160
|
+
# ensure the session exists
|
|
161
|
+
session = await self._prepare_session(context, run_args, runner)
|
|
162
|
+
|
|
159
163
|
# set request headers to session state
|
|
160
164
|
headers = context.call_context.state.get("headers", {})
|
|
161
|
-
|
|
165
|
+
state_changes = {
|
|
166
|
+
"headers": headers,
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
actions_with_update = EventActions(state_delta=state_changes)
|
|
170
|
+
system_event = Event(
|
|
171
|
+
invocation_id="header_update",
|
|
172
|
+
author="system",
|
|
173
|
+
actions=actions_with_update,
|
|
174
|
+
)
|
|
162
175
|
|
|
163
|
-
|
|
164
|
-
session = await self._prepare_session(context, run_args, runner)
|
|
176
|
+
await runner.session_service.append_event(session, system_event)
|
|
165
177
|
|
|
166
178
|
current_span = trace.get_current_span()
|
|
167
179
|
if run_args["user_id"]:
|
|
@@ -259,6 +271,7 @@ class A2aAgentExecutor(AgentExecutor):
|
|
|
259
271
|
user_id=user_id,
|
|
260
272
|
session_id=session_id,
|
|
261
273
|
)
|
|
274
|
+
|
|
262
275
|
if session is None:
|
|
263
276
|
# Extract session name from the first TextPart (like the UI does)
|
|
264
277
|
session_name = None
|
|
@@ -273,21 +286,12 @@ class A2aAgentExecutor(AgentExecutor):
|
|
|
273
286
|
session_name = text[:20] + ("..." if len(text) > 20 else "")
|
|
274
287
|
break
|
|
275
288
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
"
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
if session_name is not None:
|
|
285
|
-
create_session_kwargs["session_name"] = session_name
|
|
286
|
-
|
|
287
|
-
# We pass the kwargs using ** to avoid issues with optional
|
|
288
|
-
# parameters like `session_name` that exist within
|
|
289
|
-
# `KAgentSessionService` but not in ADK `BaseSessionService`
|
|
290
|
-
session = await runner.session_service.create_session(**create_session_kwargs)
|
|
289
|
+
session = await runner.session_service.create_session(
|
|
290
|
+
app_name=runner.app_name,
|
|
291
|
+
user_id=user_id,
|
|
292
|
+
state={"session_name": session_name},
|
|
293
|
+
session_id=session_id,
|
|
294
|
+
)
|
|
291
295
|
|
|
292
296
|
# Update run_args with the new session_id
|
|
293
297
|
run_args["session_id"] = session.id
|
|
@@ -32,7 +32,6 @@ class KAgentSessionService(BaseSessionService):
|
|
|
32
32
|
user_id: str,
|
|
33
33
|
state: Optional[dict[str, Any]] = None,
|
|
34
34
|
session_id: Optional[str] = None,
|
|
35
|
-
session_name: Optional[str] = None,
|
|
36
35
|
) -> Session:
|
|
37
36
|
# Prepare request data
|
|
38
37
|
request_data = {
|
|
@@ -41,8 +40,8 @@ class KAgentSessionService(BaseSessionService):
|
|
|
41
40
|
}
|
|
42
41
|
if session_id:
|
|
43
42
|
request_data["id"] = session_id
|
|
44
|
-
if session_name:
|
|
45
|
-
request_data["name"] = session_name
|
|
43
|
+
if state and state.get("session_name"):
|
|
44
|
+
request_data["name"] = state.get("session_name", "")
|
|
46
45
|
|
|
47
46
|
# Make API call to create session
|
|
48
47
|
response = await self.client.post(
|
|
@@ -109,13 +108,18 @@ class KAgentSessionService(BaseSessionService):
|
|
|
109
108
|
events.append(Event.model_validate_json(event_data["data"]))
|
|
110
109
|
|
|
111
110
|
# Convert to ADK Session format
|
|
112
|
-
|
|
111
|
+
session = Session(
|
|
113
112
|
id=session_data["id"],
|
|
114
113
|
user_id=session_data["user_id"],
|
|
115
114
|
events=events,
|
|
116
115
|
app_name=app_name,
|
|
117
|
-
state={},
|
|
116
|
+
state={},
|
|
118
117
|
)
|
|
118
|
+
|
|
119
|
+
for event in events:
|
|
120
|
+
await super().append_event(session, event)
|
|
121
|
+
|
|
122
|
+
return session
|
|
119
123
|
except httpx.HTTPStatusError as e:
|
|
120
124
|
if e.response.status_code == 404:
|
|
121
125
|
return None
|
|
@@ -57,6 +57,9 @@ def run(
|
|
|
57
57
|
host: str = "127.0.0.1",
|
|
58
58
|
port: int = 8080,
|
|
59
59
|
workers: int = 1,
|
|
60
|
+
local: Annotated[
|
|
61
|
+
bool, typer.Option("--local", help="Run with in-memory session service (for local development)")
|
|
62
|
+
] = False,
|
|
60
63
|
):
|
|
61
64
|
app_cfg = KAgentConfig()
|
|
62
65
|
|
|
@@ -66,8 +69,15 @@ def run(
|
|
|
66
69
|
with open(os.path.join(working_dir, name, "agent-card.json"), "r") as f:
|
|
67
70
|
agent_card = json.load(f)
|
|
68
71
|
agent_card = AgentCard.model_validate(agent_card)
|
|
72
|
+
|
|
69
73
|
kagent_app = KAgentApp(root_agent, agent_card, app_cfg.url, app_cfg.app_name)
|
|
70
|
-
|
|
74
|
+
|
|
75
|
+
if local:
|
|
76
|
+
logger.info("Running in local mode with InMemorySessionService")
|
|
77
|
+
server = kagent_app.build_local()
|
|
78
|
+
else:
|
|
79
|
+
server = kagent_app.build()
|
|
80
|
+
|
|
71
81
|
configure_tracing(server)
|
|
72
82
|
|
|
73
83
|
uvicorn.run(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|