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.
Files changed (25) hide show
  1. {kagent_adk-0.6.20 → kagent_adk-0.7.0}/PKG-INFO +4 -4
  2. {kagent_adk-0.6.20 → kagent_adk-0.7.0}/pyproject.toml +4 -4
  3. {kagent_adk-0.6.20 → kagent_adk-0.7.0}/src/kagent/adk/_a2a.py +39 -3
  4. {kagent_adk-0.6.20 → kagent_adk-0.7.0}/src/kagent/adk/_agent_executor.py +22 -18
  5. {kagent_adk-0.6.20 → kagent_adk-0.7.0}/src/kagent/adk/_session_service.py +9 -5
  6. {kagent_adk-0.6.20 → kagent_adk-0.7.0}/src/kagent/adk/cli.py +11 -1
  7. {kagent_adk-0.6.20 → kagent_adk-0.7.0}/.gitignore +0 -0
  8. {kagent_adk-0.6.20 → kagent_adk-0.7.0}/.python-version +0 -0
  9. {kagent_adk-0.6.20 → kagent_adk-0.7.0}/README.md +0 -0
  10. {kagent_adk-0.6.20 → kagent_adk-0.7.0}/src/kagent/adk/__init__.py +0 -0
  11. {kagent_adk-0.6.20 → kagent_adk-0.7.0}/src/kagent/adk/_token.py +0 -0
  12. {kagent_adk-0.6.20 → kagent_adk-0.7.0}/src/kagent/adk/converters/__init__.py +0 -0
  13. {kagent_adk-0.6.20 → kagent_adk-0.7.0}/src/kagent/adk/converters/error_mappings.py +0 -0
  14. {kagent_adk-0.6.20 → kagent_adk-0.7.0}/src/kagent/adk/converters/event_converter.py +0 -0
  15. {kagent_adk-0.6.20 → kagent_adk-0.7.0}/src/kagent/adk/converters/part_converter.py +0 -0
  16. {kagent_adk-0.6.20 → kagent_adk-0.7.0}/src/kagent/adk/converters/request_converter.py +0 -0
  17. {kagent_adk-0.6.20 → kagent_adk-0.7.0}/src/kagent/adk/models/__init__.py +0 -0
  18. {kagent_adk-0.6.20 → kagent_adk-0.7.0}/src/kagent/adk/models/_openai.py +0 -0
  19. {kagent_adk-0.6.20 → kagent_adk-0.7.0}/src/kagent/adk/types.py +0 -0
  20. {kagent_adk-0.6.20 → kagent_adk-0.7.0}/tests/__init__.py +0 -0
  21. {kagent_adk-0.6.20 → kagent_adk-0.7.0}/tests/unittests/__init__.py +0 -0
  22. {kagent_adk-0.6.20 → kagent_adk-0.7.0}/tests/unittests/converters/__init__.py +0 -0
  23. {kagent_adk-0.6.20 → kagent_adk-0.7.0}/tests/unittests/converters/test_event_converter.py +0 -0
  24. {kagent_adk-0.6.20 → kagent_adk-0.7.0}/tests/unittests/models/__init__.py +0 -0
  25. {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.6.20
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.5
8
- Requires-Dist: agentsts-core>=0.0.5
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.11.0
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.6.20"
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.5",
13
- "agentsts-core >= 0.0.5",
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.11.0",
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 ADKRunner, ADKSessionService, ADKSTSIntegration, ADKTokenPropagationPlugin
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 ADKRunner(
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
- run_args["headers"] = headers
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
- # ensure the session exists
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
- # Prepare kwargs for create_session
277
- create_session_kwargs = {
278
- "app_name": runner.app_name,
279
- "user_id": user_id,
280
- "state": {},
281
- "session_id": session_id,
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
- return Session(
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={}, # TODO: restore 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
- server = kagent_app.build()
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