|
2 | 2 |
|
3 | 3 | from dataclasses import dataclass, field
|
4 | 4 | from datetime import datetime
|
5 |
| -from typing import Annotated, Any, Literal, Union |
| 5 | +from typing import Annotated, Any, Literal, Union, cast |
6 | 6 |
|
7 | 7 | import pydantic
|
8 | 8 | import pydantic_core
|
9 |
| -from typing_extensions import Self |
| 9 | +from typing_extensions import Self, assert_never |
10 | 10 |
|
11 | 11 | from ._utils import now_utc as _now_utc
|
12 | 12 |
|
@@ -190,12 +190,34 @@ class ToolCallPart:
|
190 | 190 | """Part type identifier, this is available on all parts as a discriminator."""
|
191 | 191 |
|
192 | 192 | @classmethod
|
193 |
| - def from_json(cls, tool_name: str, args_json: str, tool_call_id: str | None = None) -> Self: |
194 |
| - return cls(tool_name, ArgsJson(args_json), tool_call_id) |
| 193 | + def from_raw_args(cls, tool_name: str, args: str | dict[str, Any], tool_call_id: str | None = None) -> Self: |
| 194 | + """Create a `ToolCallPart` from raw arguments.""" |
| 195 | + if isinstance(args, str): |
| 196 | + return cls(tool_name, ArgsJson(args), tool_call_id) |
| 197 | + elif isinstance(args, dict): |
| 198 | + return cls(tool_name, ArgsDict(args), tool_call_id) |
| 199 | + else: |
| 200 | + assert_never(args) |
195 | 201 |
|
196 |
| - @classmethod |
197 |
| - def from_dict(cls, tool_name: str, args_dict: dict[str, Any], tool_call_id: str | None = None) -> Self: |
198 |
| - return cls(tool_name, ArgsDict(args_dict), tool_call_id) |
| 202 | + def args_as_dict(self) -> dict[str, Any]: |
| 203 | + """Return the arguments as a Python dictionary. |
| 204 | +
|
| 205 | + This is just for convenience with models that require dicts as input. |
| 206 | + """ |
| 207 | + if isinstance(self.args, ArgsDict): |
| 208 | + return self.args.args_dict |
| 209 | + args = pydantic_core.from_json(self.args.args_json) |
| 210 | + assert isinstance(args, dict), 'args should be a dict' |
| 211 | + return cast(dict[str, Any], args) |
| 212 | + |
| 213 | + def args_as_json_str(self) -> str: |
| 214 | + """Return the arguments as a JSON string. |
| 215 | +
|
| 216 | + This is just for convenience with models that require JSON strings as input. |
| 217 | + """ |
| 218 | + if isinstance(self.args, ArgsJson): |
| 219 | + return self.args.args_json |
| 220 | + return pydantic_core.to_json(self.args.args_dict).decode() |
199 | 221 |
|
200 | 222 | def has_content(self) -> bool:
|
201 | 223 | if isinstance(self.args, ArgsDict):
|
|
0 commit comments