Skip to content

feat(openai): added support for tool results, definitions #14204

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 59 commits into from
Aug 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
a010077
adding tool changes, WIP
maxzhangdd Jul 28, 2025
df2fa61
progress on tool defs/results across openai create apis
maxzhangdd Jul 31, 2025
ac936e9
Merge branch 'main' into max.zhang/openai-tool-change
maxzhangdd Jul 31, 2025
769f495
remove tool from metadata, add tooldefs constant
maxzhangdd Aug 1, 2025
1434930
add tool results
maxzhangdd Aug 1, 2025
479084e
common method handling tool results/calls
maxzhangdd Aug 1, 2025
42129b0
improved method for chat response
maxzhangdd Aug 4, 2025
bb0e294
intial test changes
maxzhangdd Aug 4, 2025
5ddf543
linting
maxzhangdd Aug 4, 2025
51087a0
Merge branch 'main' into max.zhang/openai-tool-change
maxzhangdd Aug 6, 2025
f3ec21d
small fixes
maxzhangdd Aug 5, 2025
48de482
getting tests to work
maxzhangdd Aug 7, 2025
79e89b1
getting more tests to pass, WIP
maxzhangdd Aug 7, 2025
36ef061
llmobs tests
maxzhangdd Aug 8, 2025
cbc912f
typing fixes
maxzhangdd Aug 8, 2025
b26dba7
WIP, typing check
maxzhangdd Aug 11, 2025
6431a88
typing
maxzhangdd Aug 11, 2025
a2d88aa
typing
maxzhangdd Aug 11, 2025
7069e86
release note
maxzhangdd Aug 11, 2025
24ec9b6
fix agents failing test case
maxzhangdd Aug 14, 2025
9212ada
litellm tests pass
maxzhangdd Aug 14, 2025
2e85e31
Merge branch 'main' into max.zhang/openai-tool-change
maxzhangdd Aug 14, 2025
15e633d
working on comments
maxzhangdd Aug 18, 2025
9075e8c
typing
maxzhangdd Aug 18, 2025
9b720ed
addressing comments
maxzhangdd Aug 19, 2025
8f84edf
more safety around kwargs.get
maxzhangdd Aug 19, 2025
ced6c3e
fix typo
maxzhangdd Aug 19, 2025
efe7c2b
typing
maxzhangdd Aug 19, 2025
c6ddb6c
Merge branch 'main' into max.zhang/openai-tool-change
maxzhangdd Aug 19, 2025
cafdfed
remove unnecessary role check
maxzhangdd Aug 19, 2025
4cb6c27
Update ddtrace/llmobs/_integrations/utils.py
maxzhangdd Aug 19, 2025
0cea89d
Update ddtrace/llmobs/_integrations/utils.py
maxzhangdd Aug 19, 2025
aa6f6d9
Update ddtrace/llmobs/_integrations/utils.py
maxzhangdd Aug 19, 2025
c17d9aa
Update ddtrace/llmobs/_integrations/utils.py
maxzhangdd Aug 19, 2025
156d242
Update ddtrace/llmobs/_integrations/utils.py
maxzhangdd Aug 19, 2025
c9e374b
Update ddtrace/llmobs/_integrations/utils.py
maxzhangdd Aug 19, 2025
029e4a9
delete check that skips when name is falsy
maxzhangdd Aug 19, 2025
49cba72
fix streaming, remove extra tool id accesses for chat tool calls
maxzhangdd Aug 20, 2025
f2b22a9
remove extra tool_id and id acceses
maxzhangdd Aug 20, 2025
d7b37a1
typing changes
maxzhangdd Aug 20, 2025
c369c85
linting
maxzhangdd Aug 20, 2025
1732491
skip tooldef if all fields are emtpy
maxzhangdd Aug 20, 2025
88b576a
skip tooldef if all fields are empty but better
maxzhangdd Aug 20, 2025
4c79847
fix typo
maxzhangdd Aug 20, 2025
d1d1704
make function and custom separate vars, move function down
maxzhangdd Aug 20, 2025
84beb55
remove comment
maxzhangdd Aug 20, 2025
0140796
handle custom tools in streaming code
maxzhangdd Aug 20, 2025
6d10c70
custom tool call tests
maxzhangdd Aug 20, 2025
4e09e7d
Merge branch 'main' into max.zhang/openai-tool-change
maxzhangdd Aug 21, 2025
eadb0e1
response custom tool calls
maxzhangdd Aug 21, 2025
48325b2
small test tweak
maxzhangdd Aug 21, 2025
e07c3f6
prevent None messsage displaying
maxzhangdd Aug 21, 2025
6518b87
fix test case
maxzhangdd Aug 21, 2025
766cf55
Merge branch 'main' into max.zhang/openai-tool-change
maxzhangdd Aug 21, 2025
ba98254
Update ddtrace/llmobs/_integrations/utils.py
maxzhangdd Aug 22, 2025
a0eacf1
Update ddtrace/llmobs/_integrations/utils.py
maxzhangdd Aug 22, 2025
5d9adc8
move dispatch code above to avoid redefinition
maxzhangdd Aug 22, 2025
b843087
Merge branch 'main' into max.zhang/openai-tool-change
maxzhangdd Aug 22, 2025
85e5679
output messages can contain tool results
maxzhangdd Aug 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
278 changes: 192 additions & 86 deletions ddtrace/llmobs/_integrations/utils.py

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions releasenotes/notes/openai_tool_usage-ef5eaf531317ac3b.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
features:
- |
LLM Observability: Adds support for collecting tool definitions, tool calls and tool results in the OpenAI integration.
7 changes: 7 additions & 0 deletions tests/contrib/litellm/test_litellm_llmobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,13 @@ def test_completion_with_tools(self, litellm, request_vcr, llmobs_events, mock_t
"stream_options": {"include_usage": True},
"tool_choice": "auto",
},
tool_definitions=[
{
"name": tools[0]["function"]["name"],
"description": tools[0]["function"]["description"],
"schema": tools[0]["function"]["parameters"],
}
],
token_metrics=token_metrics,
tags={"ml_app": "<ml-app-name>", "service": "tests.contrib.litellm"},
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
interactions:
- request:
body: '{"messages":[{"role":"user","content":"Use the math_exp tool to add four
plus four."}],"model":"gpt-5","tools":[{"type":"custom","custom":{"name":"math_exp","description":"Creates
valid mathematical expressions","format":{"type":"grammar","grammar":{"syntax":"lark","definition":"\nstart:
expr\nexpr: term (SP ADD SP term)* -> add\n| term\nterm: factor (SP MUL SP factor)*
-> mul\n| factor\nfactor: INT\nSP: \" \"\nADD: \"+\"\nMUL: \"*\"\n%import common.INT\n"}}}}]}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '466'
content-type:
- application/json
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.91.0
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.91.0
x-stainless-read-timeout:
- '600'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.12.11
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: !!binary |
H4sIAAAAAAAAA3RT0W6bMBR95yssvzZMQCEpvFXtJi1Ss27SXjZVyDMXcGtszzZTuij/XtkkQNKU
B2T5+Jxzfe71LkAIswoXCNOWWNopHt4tX27N5rHJ4+u/9cO3+7z9sllG67b6teH/8cIx5J9noPbI
+kRlpzhYJsUAUw3EglONV1m2Sq7T/MYDnayAO1qjbJiFSZRkYXQTRqsDr5WMgsEF+h0ghNDO/12F
ooItLlC0OO50YAxpABfjIYSwltztYGIMM5YIixcTSKWwIFzRoud8BlgpeUkJ55Px8O1m6ykmwnn5
XTXrH1+zu/yePn/ePmx+LrleP9J+5jdIvypfEO2Nld05etgtzowQwoJ0ntcR25awVWdMn4jqfQNS
dIVSfALvg0vrp9mVNdS9Ifx9FkQIaYnrpA/j6YDsx9xrJphpSw3ESOH8Z+kFR0NvhfuTBmGlZads
aeULePEkjQdVPI3PDI3TA2qlJXwC0ixbXBAsK7CE+RaOU0MJbaGaqNP0kL5icgYEs0u+L+eS9hAA
E82kEufJhwYTQCkoC1WpNFSMnl56OqbBPbCPjo1B+5KxAf2PUSgtA+1aUkFNej4MPzavxkJX1kw0
oJVm4wsI9sEbAAAA//8DAGftrEX+AwAA
headers:
CF-RAY:
- 9724cebf8b2dd6f4-IAD
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Wed, 20 Aug 2025 20:58:22 GMT
Server:
- cloudflare
Set-Cookie:
- __cf_bm=K.tOaHC5Lf45ysCtP6USNAPbZgHy78FNC72qcH2X.Fo-1755723502-1.0.1.1-6gJa9NKR2lxcxp5WDhmS4X6xrB2zYsLnov89sMAupSGbYt8Hdbc_awPaQqbnQOdNmztzKstiMU8L_wFbmzt9f0Q7Qg_sho4.ecYi5i7_EiA;
path=/; expires=Wed, 20-Aug-25 21:28:22 GMT; domain=.api.openai.com; HttpOnly;
Secure; SameSite=None
- _cfuvid=CkJlTNRJNqcMv3f9_YvhdnJLTb4jyPNrZypv2Xi49h4-1755723502477-0.0.1.1-604800000;
path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
Strict-Transport-Security:
- max-age=31536000; includeSubDomains; preload
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
access-control-expose-headers:
- X-Request-ID
alt-svc:
- h3=":443"; ma=86400
cf-cache-status:
- DYNAMIC
openai-organization:
- datadog-staging
openai-processing-ms:
- '8067'
openai-project:
- proj_gt6TQZPRbZfoY2J9AQlEJMpd
openai-version:
- '2020-10-01'
x-envoy-upstream-service-time:
- '8091'
x-ratelimit-limit-requests:
- '15000'
x-ratelimit-limit-tokens:
- '40000000'
x-ratelimit-remaining-requests:
- '14999'
x-ratelimit-remaining-tokens:
- '39999987'
x-ratelimit-reset-requests:
- 4ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_611954e1d30494f191e4680d1c99b6e2
status:
code: 200
message: OK
version: 1
105 changes: 105 additions & 0 deletions tests/contrib/openai/cassettes/v1/response_custom_tool_call.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
interactions:
- request:
body: '{"input":"Use the math_exp tool to add four plus four.","model":"gpt-5","tools":[{"type":"custom","name":"math_exp","description":"Creates
valid mathematical expressions","format":{"type":"grammar","syntax":"lark","definition":"\n start:
expr\n expr: term (SP ADD SP term)* -> add\n | term\n term:
factor (SP MUL SP factor)* -> mul\n | factor\n factor: INT\n SP:
\" \"\n ADD: \"+\"\n MUL: \"*\"\n %import common.INT\n "}}]}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '500'
content-type:
- application/json
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.91.0
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.91.0
x-stainless-read-timeout:
- '600'
x-stainless-retry-count:
- '0'
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.12.11
method: POST
uri: https://api.openai.com/v1/responses
response:
body:
string: !!binary |
H4sIAAAAAAAAA4xUXW/bNhR9968gBAzY2riQFcmS/TCgmx86oO0CpMFQLIVwRV05bEhRI68ye1n+
e0HKMqUlw/Zi+J7D+6FzPx4XjEWijrYsMmi7cl1AnuBlUlcJL1abdQUJFOnmMisSDlWNcZ7xTcNh
vVnnwIsqunABdPUVOY1BdGtxwLlBIKxLcNwqz7K8WBdx7jlLQL11PlyrTiJhPThVwO/3Rvetq6oB
adHDaIw20Za1vZQeEO3oWNZIIKSds5ZMz0nodoYrOJS6p66nkvQ9PidJa1lykPNwStcoXbH7jpbZ
MomTbBkXyzg/CeAjRlv2+4Ixxh79b1DWjrrmdRanTtciTxOs+Aqw2iRpyl/U1YegY4eDsmB1K9p9
oGyvFJijS/vFY08XL6XnxMf8fF0khcsPvObpJl1VVbyCCrL/zs97S1oFeSZl/EsnPemelqc63N93
xWf7083u6vPXj++u/9g0v/36159IBxM8RDtIGaXsNUsD3oLyhSiguxIPXTR88oKxL74HHRiQEuW8
g2T6YX46gw9C97YcR3So6tzhzmjVUcmB32F5j8cpF7TfnsSNsGm08WUqrEWvTnVOeuK8F6eeRBYa
pGMpamxJNAJnk2zRPAiOJQ14BD3p6LQk2uBsDQhVhwao9/jqTXxCDxRqa7RREOxJE/276ahED2gq
bQUdJ59yrnpQ8k4LjvO6HGGfj/t8VkLrarTciM4to6N/9mfBsgeQomaun6iABAfJ8NAZtNZv7dn9
2fdMUu0NOMHPj322RrRiTHbbjoQlMLT1KQLorC0jNIp9f33F3u527PrK2z+8YssfGdR1ePy3J4Lt
LNccTtp49w837537gAwBVC+nAQYqIIO9Zb98/BTA66stu43Y7aT4t7udw15PsQ837x32aop9J1Sn
DTGuldLtm1nYqUj22BIcnEASzH10Ip7+97aR7kqp953RlRuE+Ax207E0fcth7EQtLFRyPPO9hT2G
mfVbH07yKttcPCcmh/4xHBh+h3XwjGfj/c9Tn+TZS8xLgc9LP/HO1rPopAlkoNPL9Lw6vZ3vuEKC
GghchqfF0zcAAAD//wMAtxAgsngHAAA=
headers:
CF-RAY:
- 972ad85b7fefc942-IAD
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Thu, 21 Aug 2025 14:33:32 GMT
Server:
- cloudflare
Set-Cookie:
- __cf_bm=G7bjch5x1Todcb0Gu9nayz0bBGGnE2IZl7nhjCTjDuE-1755786812-1.0.1.1-YO8UMu1dHwkNmJ9yA3wWlJ_.h6qvgJb.5Y.Uzz.MjHf1WEXtbg_93NuyaiEeFUje_5Z0sKYk4jvbWMJkx2nwmnKlhgY7N1v8UL4Qzr.p7TI;
path=/; expires=Thu, 21-Aug-25 15:03:32 GMT; domain=.api.openai.com; HttpOnly;
Secure; SameSite=None
- _cfuvid=xW34AolqPK2QSJ_rXrCmy7hO5U8DIRUefqk8mtN48YA-1755786812729-0.0.1.1-604800000;
path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
alt-svc:
- h3=":443"; ma=86400
cf-cache-status:
- DYNAMIC
openai-organization:
- datadog-staging
openai-processing-ms:
- '9839'
openai-project:
- proj_gt6TQZPRbZfoY2J9AQlEJMpd
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains; preload
x-envoy-upstream-service-time:
- '9853'
x-request-id:
- req_5b10ddfab4e1ea8e01f65920dc68c145
status:
code: 200
message: OK
version: 1
Loading
Loading