kagent-adk 0.6.11__py3-none-any.whl → 0.6.12__py3-none-any.whl

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.

Potentially problematic release.


This version of kagent-adk might be problematic. Click here for more details.

@@ -9,6 +9,7 @@ from typing import TYPE_CHECKING, Any, AsyncGenerator, Iterable, Literal, Option
9
9
  from google.adk.models import BaseLlm
10
10
  from google.adk.models.llm_response import LlmResponse
11
11
  from google.genai import types
12
+ from google.genai.types import FunctionCall, FunctionResponse
12
13
  from openai import AsyncAzureOpenAI, AsyncOpenAI
13
14
  from openai.types.chat import (
14
15
  ChatCompletion,
@@ -27,7 +28,7 @@ from openai.types.chat.chat_completion_message_tool_call_param import (
27
28
  from openai.types.chat.chat_completion_message_tool_call_param import (
28
29
  Function as ToolCallFunction,
29
30
  )
30
- from openai.types.shared_params import FunctionDefinition
31
+ from openai.types.shared_params import FunctionDefinition, FunctionParameters
31
32
  from pydantic import Field
32
33
 
33
34
  if TYPE_CHECKING:
@@ -56,7 +57,7 @@ def _convert_content_to_openai_messages(
56
57
  messages.append(system_message)
57
58
 
58
59
  # First pass: collect all function responses to match with tool calls
59
- all_function_responses = {}
60
+ all_function_responses: dict[str, FunctionResponse] = {}
60
61
  for content in contents:
61
62
  for part in content.parts or []:
62
63
  if part.function_response:
@@ -67,18 +68,18 @@ def _convert_content_to_openai_messages(
67
68
  role = _convert_role_to_openai(content.role)
68
69
 
69
70
  # Separate different types of parts
70
- text_parts = []
71
- function_calls = []
72
- function_responses = []
71
+ text_parts: list[str] = []
72
+ function_calls: list[FunctionCall] = []
73
+ function_responses: list[FunctionResponse] = []
73
74
  image_parts = []
74
75
 
75
76
  for part in content.parts or []:
76
77
  if part.text:
77
78
  text_parts.append(part.text)
78
79
  elif part.function_call:
79
- function_calls.append(part)
80
+ function_calls.append(part.function_call)
80
81
  elif part.function_response:
81
- function_responses.append(part)
82
+ function_responses.append(part.function_response)
82
83
  elif part.inline_data and part.inline_data.mime_type and part.inline_data.mime_type.startswith("image"):
83
84
  if part.inline_data.data:
84
85
  image_data = base64.b64encode(part.inline_data.data).decode()
@@ -98,43 +99,43 @@ def _convert_content_to_openai_messages(
98
99
 
99
100
  for func_call in function_calls:
100
101
  tool_call_function: ToolCallFunction = {
101
- "name": func_call.function_call.name or "",
102
- "arguments": str(func_call.function_call.args) if func_call.function_call.args else "{}",
103
- }
104
- tool_call_id = func_call.function_call.id or "call_1"
105
- tool_call: ChatCompletionMessageToolCallParam = {
106
- "id": tool_call_id,
107
- "type": "function",
108
- "function": tool_call_function,
102
+ "name": func_call.name or "",
103
+ "arguments": json.dumps(func_call.args) if func_call.args else "{}",
109
104
  }
105
+ tool_call_id = func_call.id or "call_1"
106
+ tool_call = ChatCompletionMessageToolCallParam(
107
+ id=tool_call_id,
108
+ type="function",
109
+ function=tool_call_function,
110
+ )
110
111
  tool_calls.append(tool_call)
111
112
 
112
113
  # Check if we have a response for this tool call
113
114
  if tool_call_id in all_function_responses:
114
115
  func_response = all_function_responses[tool_call_id]
115
- tool_message: ChatCompletionToolMessageParam = {
116
- "role": "tool",
117
- "tool_call_id": tool_call_id,
118
- "content": str(func_response.response.get("result", "")) if func_response.response else "",
119
- }
116
+ tool_message = ChatCompletionToolMessageParam(
117
+ role="tool",
118
+ tool_call_id=tool_call_id,
119
+ content=str(func_response.response.get("result", "")) if func_response.response else "",
120
+ )
120
121
  tool_response_messages.append(tool_message)
121
122
  else:
122
123
  # If no response is available, create a placeholder response
123
124
  # This prevents the OpenAI API error
124
- tool_message: ChatCompletionToolMessageParam = {
125
- "role": "tool",
126
- "tool_call_id": tool_call_id,
127
- "content": "No response available for this function call.",
128
- }
125
+ tool_message = ChatCompletionToolMessageParam(
126
+ role="tool",
127
+ tool_call_id=tool_call_id,
128
+ content="No response available for this function call.",
129
+ )
129
130
  tool_response_messages.append(tool_message)
130
131
 
131
132
  # Create assistant message with tool calls
132
133
  text_content = "\n".join(text_parts) if text_parts else None
133
- assistant_message: ChatCompletionAssistantMessageParam = {
134
- "role": "assistant",
135
- "content": text_content,
136
- "tool_calls": tool_calls,
137
- }
134
+ assistant_message = ChatCompletionAssistantMessageParam(
135
+ role="assistant",
136
+ content=text_content,
137
+ tool_calls=tool_calls,
138
+ )
138
139
  messages.append(assistant_message)
139
140
 
140
141
  # Add all tool response messages immediately after the assistant message
@@ -145,22 +146,22 @@ def _convert_content_to_openai_messages(
145
146
  if role == "user":
146
147
  if image_parts and text_parts:
147
148
  # Multi-modal content
148
- text_part: ChatCompletionContentPartTextParam = {"type": "text", "text": "\n".join(text_parts)}
149
+ text_part = ChatCompletionContentPartTextParam(type="text", text="\n".join(text_parts))
149
150
  content_parts = [text_part] + image_parts
150
- user_message: ChatCompletionUserMessageParam = {"role": "user", "content": content_parts}
151
+ user_message = ChatCompletionUserMessageParam(role="user", content=content_parts)
151
152
  elif image_parts:
152
153
  # Image only
153
- user_message: ChatCompletionUserMessageParam = {"role": "user", "content": image_parts}
154
+ user_message = ChatCompletionUserMessageParam(role="user", content=image_parts)
154
155
  else:
155
156
  # Text only
156
- user_message: ChatCompletionUserMessageParam = {"role": "user", "content": "\n".join(text_parts)}
157
+ user_message = ChatCompletionUserMessageParam(role="user", content="\n".join(text_parts))
157
158
  messages.append(user_message)
158
159
  elif role == "assistant":
159
160
  # Assistant messages with text (no tool calls)
160
- assistant_message: ChatCompletionAssistantMessageParam = {
161
- "role": "assistant",
162
- "content": "\n".join(text_parts),
163
- }
161
+ assistant_message = ChatCompletionAssistantMessageParam(
162
+ role="assistant",
163
+ content="\n".join(text_parts),
164
+ )
164
165
  messages.append(assistant_message)
165
166
 
166
167
  return messages
@@ -197,10 +198,10 @@ def _convert_tools_to_openai(tools: list[types.Tool]) -> list[ChatCompletionTool
197
198
  if tool.function_declarations:
198
199
  for func_decl in tool.function_declarations:
199
200
  # Build function definition
200
- function_def: FunctionDefinition = {
201
- "name": func_decl.name or "",
202
- "description": func_decl.description or "",
203
- }
201
+ function_def = FunctionDefinition(
202
+ name=func_decl.name or "",
203
+ description=func_decl.description or "",
204
+ )
204
205
 
205
206
  # Always include parameters field, even if empty
206
207
  properties = {}
@@ -219,7 +220,7 @@ def _convert_tools_to_openai(tools: list[types.Tool]) -> list[ChatCompletionTool
219
220
  function_def["parameters"] = {"type": "object", "properties": properties, "required": required}
220
221
 
221
222
  # Create the tool param
222
- openai_tool: ChatCompletionToolParam = {"type": "function", "function": function_def}
223
+ openai_tool = ChatCompletionToolParam(type="function", function=function_def)
223
224
  openai_tools.append(openai_tool)
224
225
 
225
226
  return openai_tools
@@ -389,6 +390,7 @@ class AzureOpenAI(BaseOpenAI):
389
390
  api_version: Optional[str] = None
390
391
  azure_endpoint: Optional[str] = None
391
392
  azure_deployment: Optional[str] = None
393
+ headers: Optional[dict[str, str]] = None
392
394
 
393
395
  @cached_property
394
396
  def _client(self) -> AsyncAzureOpenAI:
@@ -407,4 +409,8 @@ class AzureOpenAI(BaseOpenAI):
407
409
  "API key must be provided either via api_key parameter or AZURE_OPENAI_API_KEY environment variable"
408
410
  )
409
411
 
410
- return AsyncAzureOpenAI(api_version=api_version, azure_endpoint=azure_endpoint, api_key=api_key)
412
+ default_headers = self.headers or {}
413
+
414
+ return AsyncAzureOpenAI(
415
+ api_version=api_version, azure_endpoint=azure_endpoint, api_key=api_key, default_headers=default_headers
416
+ )
kagent/adk/types.py CHANGED
@@ -36,6 +36,7 @@ class RemoteAgentConfig(BaseModel):
36
36
 
37
37
  class BaseLLM(BaseModel):
38
38
  model: str
39
+ headers: dict[str, str] | None = None
39
40
 
40
41
 
41
42
  class OpenAI(BaseLLM):
@@ -97,20 +98,26 @@ class AgentConfig(BaseModel):
97
98
  agent_card=f"{remote_agent.url}/{AGENT_CARD_WELL_KNOWN_PATH}",
98
99
  description=remote_agent.description,
99
100
  )
100
- mcp_toolsets.append(AgentTool(agent=remote_agent, skip_summarization=True))
101
+ mcp_toolsets.append(
102
+ AgentTool(agent=remote_agent, skip_summarization=True)
103
+ ) # Get headers from model config
104
+
105
+ extra_headers = self.model.headers or {}
101
106
 
102
107
  if self.model.type == "openai":
103
108
  model = OpenAINative(model=self.model.model, base_url=self.model.base_url, type="openai")
104
109
  elif self.model.type == "anthropic":
105
- model = LiteLlm(model=f"anthropic/{self.model.model}", base_url=self.model.base_url)
110
+ model = LiteLlm(
111
+ model=f"anthropic/{self.model.model}", base_url=self.model.base_url, extra_headers=extra_headers
112
+ )
106
113
  elif self.model.type == "gemini_vertex_ai":
107
114
  model = GeminiLLM(model=self.model.model)
108
115
  elif self.model.type == "gemini_anthropic":
109
116
  model = ClaudeLLM(model=self.model.model)
110
117
  elif self.model.type == "ollama":
111
- model = LiteLlm(model=f"ollama_chat/{self.model.model}")
118
+ model = LiteLlm(model=f"ollama_chat/{self.model.model}", extra_headers=extra_headers)
112
119
  elif self.model.type == "azure_openai":
113
- model = OpenAIAzure(model=self.model.model, type="azure_openai")
120
+ model = OpenAIAzure(model=self.model.model, type="azure_openai", headers=extra_headers)
114
121
  elif self.model.type == "gemini":
115
122
  model = self.model.model
116
123
  else:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kagent-adk
3
- Version: 0.6.11
3
+ Version: 0.6.12
4
4
  Summary: kagent-adk is an sdk for integrating adk agents with kagent
5
5
  Requires-Python: >=3.12.11
6
6
  Requires-Dist: a2a-sdk>=0.3.1
@@ -4,15 +4,15 @@ kagent/adk/_agent_executor.py,sha256=rxNVdrcS4L5Kwe8oF7mLUnD1KOYhe6vXK-si0O-KQ9o
4
4
  kagent/adk/_session_service.py,sha256=A47gsfDVp8jITzeW987AHTJLEhcU_mU3ik_SFptFGIc,5815
5
5
  kagent/adk/_token.py,sha256=OL46m7U5vUTby1WWjVB7Jqzig4TWddzoAmLVLlfSdAg,2515
6
6
  kagent/adk/cli.py,sha256=Sdw9FXnUmeHfgJhdRDq1zpoNMf6GM7x35ZDz_OkQgJg,2963
7
- kagent/adk/types.py,sha256=v7VbO0tAPvpjdEgWJroEq64jSCz6D3Q0yPdRM0a7MjM,4260
7
+ kagent/adk/types.py,sha256=7xW2k_16rcbLwTYchAnXZqTDbEyZIX8X3Zv3018dq7A,4534
8
8
  kagent/adk/converters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
9
  kagent/adk/converters/error_mappings.py,sha256=1KUJPS8VrcaTv6yUKb5Whg-S2XX8YGJmtTIeZqnqvuw,2769
10
10
  kagent/adk/converters/event_converter.py,sha256=WKQRqREB11TbgGp6U_--mmukvJJgew6-VEkrGBqGVA4,10519
11
11
  kagent/adk/converters/part_converter.py,sha256=Q9Kbteit8XdL_9Tb8bAtxRxOZQei8Wabszwsl4YMe2c,7507
12
12
  kagent/adk/converters/request_converter.py,sha256=iTmTmhlnyRfuYyFi4WmpTSXPz22xjjotbe750j-CvYA,1072
13
13
  kagent/adk/models/__init__.py,sha256=mqD0JhS9kT1rMpFNLq5-qnjstpp6lzT9xADaOfjrUKY,78
14
- kagent/adk/models/_openai.py,sha256=0hQklnXacTHsb5h1gkPqmuoEyJl_ibh5R-FBY-wQ7Ts,16594
15
- kagent_adk-0.6.11.dist-info/METADATA,sha256=tgksopEr1rQBB4B6nGmtBeQeNTDG7dwxLpWXEitjTs8,944
16
- kagent_adk-0.6.11.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
17
- kagent_adk-0.6.11.dist-info/entry_points.txt,sha256=a1Q2Inc9L0dvXWEkwnCdf9cfXdpX5Dl2Q6DhNWNjhxw,50
18
- kagent_adk-0.6.11.dist-info/RECORD,,
14
+ kagent/adk/models/_openai.py,sha256=ze8JgMOqZFJidf4XEtCL2o6xV6aLY1ZR1eilR7tm5KI,16789
15
+ kagent_adk-0.6.12.dist-info/METADATA,sha256=xcIldMuG_foeMSHo775znd6eRXn1bD3Uc-ynQPC3q_s,944
16
+ kagent_adk-0.6.12.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
17
+ kagent_adk-0.6.12.dist-info/entry_points.txt,sha256=a1Q2Inc9L0dvXWEkwnCdf9cfXdpX5Dl2Q6DhNWNjhxw,50
18
+ kagent_adk-0.6.12.dist-info/RECORD,,