mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Python: Fix Python pyright package scoping and typing remediation (#4426)
* Fix Python pyright package scoping and typing remediation Implements issue #4407 by removing the root pyright include, adding package-level pyright includes, and resolving pyright/mypy typing issues across Python packages. Also cleans unnecessary casts and applies line-level, rule-specific ignores where external libraries are too dynamic. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Reduce pyright cost in handoff cloning Simplify cloned_options construction in HandoffAgentExecutor to avoid expensive TypedDict narrowing/inference in _handoff.py, which was causing pyright to spend a long time in orchestrations. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix types * Fix lint and type-check regressions Resolve current Python package check failures across lint, pyright, and mypy after recent code changes, including purview/declarative pyright issues and multiple ruff simplification findings. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fixed hooks * Stabilize package tests and test tasks Resolve cross-package non-integration test failures, simplify streaming type flow, harden locale/culture handling, and standardize package test poe tasks to exclude integration tests where applicable. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * lots of small fixes * Fix current Python test regressions Address current failing unit tests in azure-ai, bedrock, and azure-cosmos while keeping Bedrock parsing logic inline (no new static helper methods). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * small fixes * small fixes * removed pydantic from json * final updates * fix core * fix tests * fix obser --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
Unverified
parent
4a043c6c66
commit
55ddd841b7
@@ -225,11 +225,7 @@ class RawClaudeAgent(BaseAgent, Generic[OptionsT]):
|
||||
description: str | None = None,
|
||||
context_providers: Sequence[BaseContextProvider] | None = None,
|
||||
middleware: Sequence[AgentMiddlewareTypes] | None = None,
|
||||
tools: ToolTypes
|
||||
| Callable[..., Any]
|
||||
| str
|
||||
| Sequence[ToolTypes | Callable[..., Any] | str]
|
||||
| None = None,
|
||||
tools: ToolTypes | Callable[..., Any] | str | Sequence[ToolTypes | Callable[..., Any] | str] | None = None,
|
||||
default_options: OptionsT | MutableMapping[str, Any] | None = None,
|
||||
env_file_path: str | None = None,
|
||||
env_file_encoding: str | None = None,
|
||||
@@ -305,11 +301,7 @@ class RawClaudeAgent(BaseAgent, Generic[OptionsT]):
|
||||
|
||||
def _normalize_tools(
|
||||
self,
|
||||
tools: ToolTypes
|
||||
| Callable[..., Any]
|
||||
| str
|
||||
| Sequence[ToolTypes | Callable[..., Any] | str]
|
||||
| None,
|
||||
tools: ToolTypes | Callable[..., Any] | str | Sequence[ToolTypes | Callable[..., Any] | str] | None,
|
||||
) -> None:
|
||||
"""Separate built-in tools (strings) from custom tools.
|
||||
|
||||
@@ -319,21 +311,17 @@ class RawClaudeAgent(BaseAgent, Generic[OptionsT]):
|
||||
if tools is None:
|
||||
return
|
||||
|
||||
# Normalize to sequence
|
||||
if isinstance(tools, str):
|
||||
tools_list: Sequence[Any] = [tools]
|
||||
elif isinstance(tools, Sequence):
|
||||
tools_list = list(tools)
|
||||
else:
|
||||
tools_list = [tools]
|
||||
|
||||
for tool in tools_list:
|
||||
non_builtin_tools: ToolTypes | Callable[..., Any] | Sequence[ToolTypes | Callable[..., Any]] = []
|
||||
if not isinstance(tools, list):
|
||||
tools = [tools] # type: ignore[assignment, reportUnknownVariableType]
|
||||
for tool in tools: # type: ignore[reportUnknownVariableType]
|
||||
if isinstance(tool, str):
|
||||
self._builtin_tools.append(tool)
|
||||
else:
|
||||
# Use normalize_tools for custom tools
|
||||
normalized = normalize_tools(tool)
|
||||
self._custom_tools.extend(normalized)
|
||||
non_builtin_tools.append(tool) # type: ignore[union-attr, reportUnknownArgumentType]
|
||||
if not non_builtin_tools:
|
||||
return
|
||||
self._custom_tools.extend(normalize_tools(non_builtin_tools)) # type: ignore[reportUnknownVariableType]
|
||||
|
||||
async def __aenter__(self) -> RawClaudeAgent[OptionsT]:
|
||||
"""Start the agent when entering async context."""
|
||||
@@ -378,9 +366,7 @@ class RawClaudeAgent(BaseAgent, Generic[OptionsT]):
|
||||
session_id: The session ID to use, or None for a new session.
|
||||
"""
|
||||
needs_new_client = (
|
||||
not self._started
|
||||
or self._client is None
|
||||
or (session_id and session_id != self._current_session_id)
|
||||
not self._started or self._client is None or (session_id and session_id != self._current_session_id)
|
||||
)
|
||||
|
||||
if needs_new_client:
|
||||
@@ -403,9 +389,7 @@ class RawClaudeAgent(BaseAgent, Generic[OptionsT]):
|
||||
self._client = None
|
||||
raise AgentException(f"Failed to start Claude SDK client: {ex}") from ex
|
||||
|
||||
def _prepare_client_options(
|
||||
self, resume_session_id: str | None = None
|
||||
) -> SDKOptions:
|
||||
def _prepare_client_options(self, resume_session_id: str | None = None) -> SDKOptions:
|
||||
"""Prepare SDK options for client initialization.
|
||||
|
||||
Args:
|
||||
@@ -445,9 +429,7 @@ class RawClaudeAgent(BaseAgent, Generic[OptionsT]):
|
||||
|
||||
# Prepare custom tools (FunctionTool instances)
|
||||
custom_tools_server, custom_tool_names = (
|
||||
self._prepare_tools(self._custom_tools)
|
||||
if self._custom_tools
|
||||
else (None, [])
|
||||
self._prepare_tools(self._custom_tools) if self._custom_tools else (None, [])
|
||||
)
|
||||
|
||||
# MCP servers - merge user-provided servers with custom tools server
|
||||
@@ -494,13 +476,9 @@ class RawClaudeAgent(BaseAgent, Generic[OptionsT]):
|
||||
if not sdk_tools:
|
||||
return None, []
|
||||
|
||||
return create_sdk_mcp_server(
|
||||
name=TOOLS_MCP_SERVER_NAME, tools=sdk_tools
|
||||
), tool_names
|
||||
return create_sdk_mcp_server(name=TOOLS_MCP_SERVER_NAME, tools=sdk_tools), tool_names
|
||||
|
||||
def _function_tool_to_sdk_mcp_tool(
|
||||
self, func_tool: FunctionTool
|
||||
) -> SdkMcpTool[Any]:
|
||||
def _function_tool_to_sdk_mcp_tool(self, func_tool: FunctionTool) -> SdkMcpTool[Any]:
|
||||
"""Convert a FunctionTool to an SDK MCP tool.
|
||||
|
||||
Args:
|
||||
@@ -523,9 +501,7 @@ class RawClaudeAgent(BaseAgent, Generic[OptionsT]):
|
||||
return {"content": [{"type": "text", "text": f"Error: {e}"}]}
|
||||
|
||||
# Get JSON schema from pydantic model
|
||||
schema: dict[str, Any] = (
|
||||
func_tool.input_model.model_json_schema() if func_tool.input_model else {}
|
||||
)
|
||||
schema: dict[str, Any] = func_tool.input_model.model_json_schema() if func_tool.input_model else {}
|
||||
input_schema: dict[str, Any] = {
|
||||
"type": "object",
|
||||
"properties": schema.get("properties", {}),
|
||||
@@ -586,9 +562,7 @@ class RawClaudeAgent(BaseAgent, Generic[OptionsT]):
|
||||
opts["instructions"] = system_prompt
|
||||
return opts
|
||||
|
||||
def _finalize_response(
|
||||
self, updates: Sequence[AgentResponseUpdate]
|
||||
) -> AgentResponse[Any]:
|
||||
def _finalize_response(self, updates: Sequence[AgentResponseUpdate]) -> AgentResponse[Any]:
|
||||
"""Build AgentResponse and propagate structured_output as value.
|
||||
|
||||
Args:
|
||||
@@ -627,10 +601,7 @@ class RawClaudeAgent(BaseAgent, Generic[OptionsT]):
|
||||
stream: bool = False,
|
||||
session: AgentSession | None = None,
|
||||
**kwargs: Any,
|
||||
) -> (
|
||||
Awaitable[AgentResponse[Any]]
|
||||
| ResponseStream[AgentResponseUpdate, AgentResponse[Any]]
|
||||
):
|
||||
) -> Awaitable[AgentResponse[Any]] | ResponseStream[AgentResponseUpdate, AgentResponse[Any]]:
|
||||
"""Run the agent with the given messages.
|
||||
|
||||
Args:
|
||||
@@ -696,11 +667,7 @@ class RawClaudeAgent(BaseAgent, Generic[OptionsT]):
|
||||
if text:
|
||||
yield AgentResponseUpdate(
|
||||
role="assistant",
|
||||
contents=[
|
||||
Content.from_text(
|
||||
text=text, raw_representation=message
|
||||
)
|
||||
],
|
||||
contents=[Content.from_text(text=text, raw_representation=message)],
|
||||
raw_representation=message,
|
||||
)
|
||||
elif delta_type == "thinking_delta":
|
||||
@@ -708,11 +675,7 @@ class RawClaudeAgent(BaseAgent, Generic[OptionsT]):
|
||||
if thinking:
|
||||
yield AgentResponseUpdate(
|
||||
role="assistant",
|
||||
contents=[
|
||||
Content.from_text_reasoning(
|
||||
text=thinking, raw_representation=message
|
||||
)
|
||||
],
|
||||
contents=[Content.from_text_reasoning(text=thinking, raw_representation=message)],
|
||||
raw_representation=message,
|
||||
)
|
||||
elif isinstance(message, AssistantMessage):
|
||||
@@ -729,9 +692,7 @@ class RawClaudeAgent(BaseAgent, Generic[OptionsT]):
|
||||
"server_error": "Claude API server error",
|
||||
"unknown": "Unknown error from Claude API",
|
||||
}
|
||||
error_msg = error_messages.get(
|
||||
message.error, f"Claude API error: {message.error}"
|
||||
)
|
||||
error_msg = error_messages.get(message.error, f"Claude API error: {message.error}")
|
||||
# Extract any error details from content blocks
|
||||
if message.content:
|
||||
for block in message.content:
|
||||
|
||||
@@ -61,6 +61,7 @@ omit = [
|
||||
|
||||
[tool.pyright]
|
||||
extends = "../../pyproject.toml"
|
||||
include = ["agent_framework_claude"]
|
||||
exclude = ['tests']
|
||||
|
||||
[tool.mypy]
|
||||
@@ -87,7 +88,7 @@ include = "../../shared_tasks.toml"
|
||||
|
||||
[tool.poe.tasks]
|
||||
mypy = "mypy --config-file $POE_ROOT/pyproject.toml agent_framework_claude"
|
||||
test = "pytest --cov=agent_framework_claude --cov-report=term-missing:skip-covered tests"
|
||||
test = "pytest -m \"not integration\" --cov=agent_framework_claude --cov-report=term-missing:skip-covered tests"
|
||||
|
||||
[build-system]
|
||||
requires = ["flit-core >= 3.11,<4.0"]
|
||||
|
||||
Reference in New Issue
Block a user