Skip to content

Commit 4e9bb87

Browse files
committed
fix(tools): handle callable objects in model serialization to facilitate tool calling
- The span tracing uses recursive_model_demp method to seriliaze calls within its context, but the call fails when one of the parameters is a Callable type (this happens, e.g., when trying to use OpenAI agents which accept tools as an input parameter). So this commit: - Modifies recursive_model_dump to safely serialize functions and callables (even if they're part of Pydantic models) - To simplify the code, only supports Pydantic v2 models. This required dropping the pydantic v1 calls during the build process. - Fix openai_activities.py#FunctionTool type hints for callable to match openai agents lib - Adds test coverage for function serialization edge cases This fixes tool calling issues where Pydantic models containing function objects would fail during serialization, causing runtime errors in agent workflows. Tested by adding a project locally with tool calling
1 parent 343cd10 commit 4e9bb87

File tree

6 files changed

+822
-28
lines changed

6 files changed

+822
-28
lines changed

requirements-dev.lock

Lines changed: 275 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,58 +15,151 @@ aiohappyeyeballs==2.6.1
1515
aiohttp==3.12.8
1616
# via agentex-sdk
1717
# via httpx-aiohttp
18+
# via litellm
1819
aiosignal==1.3.2
1920
# via aiohttp
2021
annotated-types==0.6.0
2122
# via pydantic
22-
anyio==4.4.0
23+
anyio==4.10.0
2324
# via agentex-sdk
2425
# via httpx
26+
# via mcp
27+
# via openai
28+
# via scale-gp
29+
# via scale-gp-beta
30+
# via sse-starlette
31+
# via starlette
32+
# via watchfiles
33+
appnope==0.1.4
34+
# via ipykernel
2535
argcomplete==3.1.2
2636
# via nox
27-
async-timeout==5.0.1
28-
# via aiohttp
37+
asttokens==3.0.0
38+
# via stack-data
2939
attrs==25.3.0
3040
# via aiohttp
41+
# via jsonschema
42+
# via referencing
43+
cachetools==5.5.2
44+
# via google-auth
3145
certifi==2023.7.22
3246
# via httpcore
3347
# via httpx
48+
# via kubernetes
49+
# via requests
50+
charset-normalizer==3.4.3
51+
# via requests
52+
click==8.2.1
53+
# via litellm
54+
# via typer
55+
# via uvicorn
56+
colorama==0.4.6
57+
# via griffe
3458
colorlog==6.7.0
3559
# via nox
60+
comm==0.2.3
61+
# via ipykernel
62+
debugpy==1.8.16
63+
# via ipykernel
64+
decorator==5.2.1
65+
# via ipython
3666
dirty-equals==0.6.0
3767
distlib==0.3.7
3868
# via virtualenv
3969
distro==1.8.0
4070
# via agentex-sdk
41-
exceptiongroup==1.2.2
42-
# via anyio
43-
# via pytest
71+
# via openai
72+
# via scale-gp
73+
# via scale-gp-beta
4474
execnet==2.1.1
4575
# via pytest-xdist
76+
executing==2.2.0
77+
# via stack-data
78+
fastapi==0.115.14
79+
# via agentex-sdk
4680
filelock==3.12.4
81+
# via huggingface-hub
4782
# via virtualenv
4883
frozenlist==1.6.2
4984
# via aiohttp
5085
# via aiosignal
86+
fsspec==2025.7.0
87+
# via huggingface-hub
88+
google-auth==2.40.3
89+
# via kubernetes
90+
griffe==1.12.0
91+
# via openai-agents
5192
h11==0.16.0
5293
# via httpcore
94+
# via uvicorn
95+
hf-xet==1.1.7
96+
# via huggingface-hub
5397
httpcore==1.0.9
5498
# via httpx
55-
httpx==0.28.1
99+
httpx==0.27.2
56100
# via agentex-sdk
57101
# via httpx-aiohttp
102+
# via litellm
103+
# via mcp
104+
# via openai
58105
# via respx
106+
# via scale-gp
107+
# via scale-gp-beta
59108
httpx-aiohttp==0.1.8
60109
# via agentex-sdk
110+
httpx-sse==0.4.1
111+
# via mcp
112+
huggingface-hub==0.34.4
113+
# via tokenizers
61114
idna==3.4
62115
# via anyio
63116
# via httpx
117+
# via requests
64118
# via yarl
65119
importlib-metadata==7.0.0
120+
# via litellm
66121
iniconfig==2.0.0
67122
# via pytest
123+
ipykernel==6.30.1
124+
# via agentex-sdk
125+
ipython==9.4.0
126+
# via ipykernel
127+
ipython-pygments-lexers==1.1.1
128+
# via ipython
129+
jedi==0.19.2
130+
# via ipython
131+
jinja2==3.1.6
132+
# via agentex-sdk
133+
# via litellm
134+
jiter==0.10.0
135+
# via openai
136+
jsonref==1.1.0
137+
# via agentex-sdk
138+
jsonschema==4.25.0
139+
# via agentex-sdk
140+
# via litellm
141+
# via mcp
142+
jsonschema-specifications==2025.4.1
143+
# via jsonschema
144+
jupyter-client==8.6.3
145+
# via ipykernel
146+
jupyter-core==5.8.1
147+
# via ipykernel
148+
# via jupyter-client
149+
kubernetes==28.1.0
150+
# via agentex-sdk
151+
litellm==1.75.5.post1
152+
# via agentex-sdk
68153
markdown-it-py==3.0.0
69154
# via rich
155+
markupsafe==3.0.2
156+
# via jinja2
157+
matplotlib-inline==0.1.7
158+
# via ipykernel
159+
# via ipython
160+
mcp==1.12.4
161+
# via agentex-sdk
162+
# via openai-agents
70163
mdurl==0.1.2
71164
# via markdown-it-py
72165
multidict==6.4.4
@@ -76,59 +169,227 @@ mypy==1.14.1
76169
mypy-extensions==1.0.0
77170
# via mypy
78171
nest-asyncio==1.6.0
172+
# via ipykernel
173+
nexus-rpc==1.1.0
174+
# via temporalio
79175
nodeenv==1.8.0
80176
# via pyright
81177
nox==2023.4.22
178+
oauthlib==3.3.1
179+
# via kubernetes
180+
# via requests-oauthlib
181+
openai==1.99.9
182+
# via litellm
183+
# via openai-agents
184+
openai-agents==0.2.6
185+
# via agentex-sdk
82186
packaging==23.2
187+
# via huggingface-hub
188+
# via ipykernel
83189
# via nox
84190
# via pytest
191+
parso==0.8.4
192+
# via jedi
193+
pexpect==4.9.0
194+
# via ipython
85195
platformdirs==3.11.0
196+
# via jupyter-core
86197
# via virtualenv
87198
pluggy==1.5.0
88199
# via pytest
200+
prompt-toolkit==3.0.51
201+
# via ipython
202+
# via questionary
89203
propcache==0.3.1
90204
# via aiohttp
91205
# via yarl
206+
protobuf==5.29.5
207+
# via temporalio
208+
psutil==7.0.0
209+
# via ipykernel
210+
ptyprocess==0.7.0
211+
# via pexpect
212+
pure-eval==0.2.3
213+
# via stack-data
214+
pyasn1==0.6.1
215+
# via pyasn1-modules
216+
# via rsa
217+
pyasn1-modules==0.4.2
218+
# via google-auth
92219
pydantic==2.10.3
93220
# via agentex-sdk
221+
# via fastapi
222+
# via litellm
223+
# via mcp
224+
# via openai
225+
# via openai-agents
226+
# via pydantic-settings
227+
# via python-on-whales
228+
# via scale-gp
229+
# via scale-gp-beta
94230
pydantic-core==2.27.1
95231
# via pydantic
232+
pydantic-settings==2.10.1
233+
# via mcp
96234
pygments==2.18.0
235+
# via ipython
236+
# via ipython-pygments-lexers
237+
# via pytest
97238
# via rich
239+
pyjwt==2.10.1
240+
# via redis
98241
pyright==1.1.399
99-
pytest==8.3.3
242+
pytest==8.4.1
243+
# via agentex-sdk
100244
# via pytest-asyncio
101245
# via pytest-xdist
102-
pytest-asyncio==0.24.0
246+
pytest-asyncio==1.1.0
247+
# via agentex-sdk
103248
pytest-xdist==3.7.0
104249
python-dateutil==2.8.2
250+
# via jupyter-client
251+
# via kubernetes
105252
# via time-machine
253+
python-dotenv==1.1.1
254+
# via litellm
255+
# via mcp
256+
# via pydantic-settings
257+
python-multipart==0.0.20
258+
# via mcp
259+
python-on-whales==0.73.0
260+
# via agentex-sdk
106261
pytz==2023.3.post1
107262
# via dirty-equals
263+
pyyaml==6.0.2
264+
# via agentex-sdk
265+
# via huggingface-hub
266+
# via kubernetes
267+
pyzmq==27.0.1
268+
# via ipykernel
269+
# via jupyter-client
270+
questionary==2.1.0
271+
# via agentex-sdk
272+
redis==5.3.1
273+
# via agentex-sdk
274+
referencing==0.36.2
275+
# via jsonschema
276+
# via jsonschema-specifications
277+
regex==2025.7.34
278+
# via tiktoken
279+
requests==2.32.4
280+
# via huggingface-hub
281+
# via kubernetes
282+
# via openai-agents
283+
# via python-on-whales
284+
# via requests-oauthlib
285+
# via tiktoken
286+
requests-oauthlib==2.0.0
287+
# via kubernetes
108288
respx==0.22.0
109-
rich==13.7.1
289+
rich==13.9.4
290+
# via agentex-sdk
291+
# via typer
292+
rpds-py==0.27.0
293+
# via jsonschema
294+
# via referencing
295+
rsa==4.9.1
296+
# via google-auth
110297
ruff==0.9.4
298+
# via agentex-sdk
299+
scale-gp==0.1.0a59
300+
# via agentex-sdk
301+
scale-gp-beta==0.1.0a20
302+
# via agentex-sdk
111303
setuptools==68.2.2
112304
# via nodeenv
305+
shellingham==1.5.4
306+
# via typer
113307
six==1.16.0
308+
# via kubernetes
114309
# via python-dateutil
115310
sniffio==1.3.0
116311
# via agentex-sdk
117312
# via anyio
313+
# via httpx
314+
# via openai
315+
# via scale-gp
316+
# via scale-gp-beta
317+
sse-starlette==3.0.2
318+
# via mcp
319+
stack-data==0.6.3
320+
# via ipython
321+
starlette==0.46.2
322+
# via fastapi
323+
# via mcp
324+
temporalio==1.15.0
325+
# via agentex-sdk
326+
tiktoken==0.11.0
327+
# via litellm
118328
time-machine==2.9.0
119-
tomli==2.0.2
120-
# via mypy
121-
# via pytest
329+
tokenizers==0.21.4
330+
# via litellm
331+
tornado==6.5.2
332+
# via ipykernel
333+
# via jupyter-client
334+
tqdm==4.67.1
335+
# via huggingface-hub
336+
# via openai
337+
# via python-on-whales
338+
traitlets==5.14.3
339+
# via ipykernel
340+
# via ipython
341+
# via jupyter-client
342+
# via jupyter-core
343+
# via matplotlib-inline
344+
typer==0.16.0
345+
# via agentex-sdk
346+
# via mcp
347+
# via python-on-whales
348+
types-protobuf==6.30.2.20250809
349+
# via temporalio
350+
types-requests==2.31.0.6
351+
# via openai-agents
352+
types-urllib3==1.26.25.14
353+
# via types-requests
122354
typing-extensions==4.12.2
123355
# via agentex-sdk
124356
# via anyio
125-
# via multidict
357+
# via fastapi
358+
# via huggingface-hub
126359
# via mypy
360+
# via nexus-rpc
361+
# via openai
362+
# via openai-agents
127363
# via pydantic
128364
# via pydantic-core
129365
# via pyright
366+
# via python-on-whales
367+
# via referencing
368+
# via scale-gp
369+
# via scale-gp-beta
370+
# via temporalio
371+
# via typer
372+
# via typing-inspection
373+
typing-inspection==0.4.1
374+
# via pydantic-settings
375+
tzdata==2025.2
376+
# via agentex-sdk
377+
tzlocal==5.3.1
378+
# via agentex-sdk
379+
urllib3==1.26.20
380+
# via kubernetes
381+
# via requests
382+
uvicorn==0.35.0
383+
# via agentex-sdk
384+
# via mcp
130385
virtualenv==20.24.5
131386
# via nox
387+
watchfiles==0.24.0
388+
# via agentex-sdk
389+
wcwidth==0.2.13
390+
# via prompt-toolkit
391+
websocket-client==1.8.0
392+
# via kubernetes
132393
yarl==1.20.0
133394
# via aiohttp
134395
zipp==3.17.0

0 commit comments

Comments
 (0)